Signed-off-by: Ziqing Hui zhui@codeweavers.com --- include/Makefile.in | 1 + include/d2d1_1.idl | 1 + include/d2d1effects.idl | 46 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100755 include/d2d1effects.idl
diff --git a/include/Makefile.in b/include/Makefile.in index 61a74a210c9..46cb0f53a5e 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -99,6 +99,7 @@ SOURCES = \ d2d1.idl \ d2d1_1.idl \ d2d1_2.idl \ + d2d1effects.idl \ d2dbasetypes.h \ d2derr.h \ d3d.h \ diff --git a/include/d2d1_1.idl b/include/d2d1_1.idl index 257a970968f..fdec8ae5f9c 100644 --- a/include/d2d1_1.idl +++ b/include/d2d1_1.idl @@ -17,6 +17,7 @@ */
import "d2d1.idl"; +import "d2d1effects.idl";
interface ID2D1DeviceContext; interface ID2D1PathGeometry1; diff --git a/include/d2d1effects.idl b/include/d2d1effects.idl new file mode 100755 index 00000000000..ee1dbe94728 --- /dev/null +++ b/include/d2d1effects.idl @@ -0,0 +1,46 @@ +/* + * Copyright 2021 Ziqing Hui for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +cpp_quote("DEFINE_GUID(CLSID_D2D12DAffineTransform, 0x6aa97485,0x6354,0x4cfc,0x90,0x8c,0xe4,0xa7,0x4f,0x62,0xc9,0x6c);") + +typedef enum D2D1_BORDER_MODE +{ + D2D1_BORDER_MODE_SOFT = 0x0, + D2D1_BORDER_MODE_HARD = 0x1, + D2D1_BORDER_MODE_FORCE_DWORD = 0xffffffff +} D2D1_BORDER_MODE; + +typedef enum D2D1_2DAFFINETRANSFORM_PROP +{ + D2D1_2DAFFINETRANSFORM_PROP_INTERPOLATION_MODE = 0x0, + D2D1_2DAFFINETRANSFORM_PROP_BORDER_MODE = 0x1, + D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX = 0x2, + D2D1_2DAFFINETRANSFORM_PROP_SHARPNESS = 0x3, + D2D1_2DAFFINETRANSFORM_PROP_FORCE_DWORD = 0xffffffff +} D2D1_2DAFFINETRANSFORM_PROP; + +typedef enum D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE +{ + D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_NEAREST_NEIGHBOR = 0x0, + D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_LINEAR = 0x1, + D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_CUBIC = 0x2, + D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_MULTI_SAMPLE_LINEAR = 0x3, + D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_ANISOTROPIC = 0x4, + D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC = 0x5, + D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_FORCE_DWORD = 0xffffffff +} D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE;
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index e60128b38f2..f0f6e054047 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -9678,6 +9678,54 @@ static void test_mt_factory(BOOL d3d11) ID2D1Factory_Release(factory); }
+static void test_effect(BOOL d3d11) +{ + ID2D1Image *image_a = NULL, *image_b = NULL; + ID2D1DeviceContext *context = NULL; + ID2D1Factory1 *factory = NULL; + struct d2d1_test_context ctx; + ID2D1Effect *effect = NULL; + HRESULT hr; + + if (!init_test_context(&ctx, d3d11)) + return; + + if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory))) + { + win_skip("ID2D1Factory1 is not supported.\n"); + goto end; + } + + hr = ID2D1RenderTarget_QueryInterface(ctx.rt, &IID_ID2D1DeviceContext, (void **)&context); + ok(hr == S_OK, "Failed to get device context interface, hr %#x.\n", hr); + + hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D12DAffineTransform, &effect); + ok(hr == S_OK, "Failed to create effect, hr %#x.\n", hr); + + hr = ID2D1Effect_QueryInterface(effect, &IID_ID2D1Image, (void **)&image_a); + todo_wine + ok(hr == S_OK, "Failed to get image interface, hr %#x.\n", hr); + if (hr != S_OK) + goto end; + + ID2D1Effect_GetOutput(effect, &image_b); + todo_wine + ok(image_a == image_b, "Image interface mismatch.\n"); + +end: + if (image_b) + ID2D1Image_Release(image_b); + if (image_a) + ID2D1Image_Release(image_a); + if (effect) + ID2D1Effect_Release(effect); + if (context) + ID2D1DeviceContext_Release(context); + if (factory) + ID2D1Factory1_Release(factory); + release_test_context(&ctx); +} + START_TEST(d2d1) { HMODULE d2d1_dll = GetModuleHandleA("d2d1.dll"); @@ -9739,6 +9787,7 @@ START_TEST(d2d1) queue_d3d10_test(test_colour_space); queue_test(test_geometry_group); queue_test(test_mt_factory); + queue_test(test_effect);
run_queued_tests(); }
Signed-off-by: Ziqing Hui zhui@codeweavers.com ---
v4: Remove a HRESULT check in test.
dlls/d2d1/d2d1_private.h | 5 +++- dlls/d2d1/device.c | 3 ++- dlls/d2d1/effect.c | 54 +++++++++++++++++++++++++++++++++++++++- dlls/d2d1/tests/d2d1.c | 3 --- 4 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index f25a7809b17..ce99e7c3432 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -568,10 +568,13 @@ void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *factory, IDXGIDev struct d2d_effect { ID2D1Effect ID2D1Effect_iface; + ID2D1Image ID2D1Image_iface; LONG refcount; + + ID2D1Factory *factory; };
-void d2d_effect_init(struct d2d_effect *effect) DECLSPEC_HIDDEN; +void d2d_effect_init(struct d2d_effect *effect, ID2D1Factory *factory) DECLSPEC_HIDDEN;
static inline BOOL d2d_array_reserve(void **elements, size_t *capacity, size_t count, size_t size) { diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 3b444321c87..75b351e571e 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -1886,6 +1886,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromDxgiSurface( static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateEffect(ID2D1DeviceContext *iface, REFCLSID effect_id, ID2D1Effect **effect) { + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); struct d2d_effect *object;
FIXME("iface %p, effect_id %s, effect %p stub!\n", iface, debugstr_guid(effect_id), effect); @@ -1893,7 +1894,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateEffect(ID2D1DeviceCont if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY;
- d2d_effect_init(object); + d2d_effect_init(object, context->factory);
TRACE("Created effect %p.\n", object); *effect = &object->ID2D1Effect_iface; diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index fb1e66a3d9b..50cd8864921 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -25,8 +25,14 @@ static inline struct d2d_effect *impl_from_ID2D1Effect(ID2D1Effect *iface) return CONTAINING_RECORD(iface, struct d2d_effect, ID2D1Effect_iface); }
+static inline struct d2d_effect *impl_from_ID2D1Image(ID2D1Image *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_effect, ID2D1Image_iface); +} + static HRESULT STDMETHODCALLTYPE d2d_effect_QueryInterface(ID2D1Effect *iface, REFIID iid, void **out) { + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
if (IsEqualGUID(iid, &IID_ID2D1Effect) @@ -37,6 +43,12 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_QueryInterface(ID2D1Effect *iface, R *out = iface; return S_OK; } + if (IsEqualGUID(iid, &IID_ID2D1Image) + || IsEqualGUID(iid, &IID_ID2D1Resource)) + { + ID2D1Image_AddRef(*out = &effect->ID2D1Image_iface); + return S_OK; + }
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
@@ -62,7 +74,10 @@ static ULONG STDMETHODCALLTYPE d2d_effect_Release(ID2D1Effect *iface) TRACE("%p decreasing refcount to %u.\n", iface, refcount);
if (!refcount) + { + ID2D1Factory_Release(effect->factory); heap_free(effect); + }
return refcount; } @@ -181,6 +196,33 @@ static void STDMETHODCALLTYPE d2d_effect_GetOutput(ID2D1Effect *iface, ID2D1Imag FIXME("iface %p, output %p stub!\n", iface, output); }
+static HRESULT STDMETHODCALLTYPE d2d_effect_image_QueryInterface(ID2D1Image *iface, REFIID iid, void **out) +{ + struct d2d_effect *effect = impl_from_ID2D1Image(iface); + return d2d_effect_QueryInterface(&effect->ID2D1Effect_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE d2d_effect_image_AddRef(ID2D1Image *iface) +{ + struct d2d_effect *effect = impl_from_ID2D1Image(iface); + return d2d_effect_AddRef(&effect->ID2D1Effect_iface); +} + +static ULONG STDMETHODCALLTYPE d2d_effect_image_Release(ID2D1Image *iface) +{ + struct d2d_effect *effect = impl_from_ID2D1Image(iface); + return d2d_effect_Release(&effect->ID2D1Effect_iface); +} + +static void STDMETHODCALLTYPE d2d_effect_image_GetFactory(ID2D1Image *iface, ID2D1Factory **factory) +{ + struct d2d_effect *effect = impl_from_ID2D1Image(iface); + + TRACE("iface %p, factory %p.\n", iface, factory); + + ID2D1Factory_AddRef(*factory = effect->factory); +} + static const ID2D1EffectVtbl d2d_effect_vtbl = { d2d_effect_QueryInterface, @@ -204,8 +246,18 @@ static const ID2D1EffectVtbl d2d_effect_vtbl = d2d_effect_GetOutput, };
-void d2d_effect_init(struct d2d_effect *effect) +static const ID2D1ImageVtbl d2d_effect_image_vtbl = +{ + d2d_effect_image_QueryInterface, + d2d_effect_image_AddRef, + d2d_effect_image_Release, + d2d_effect_image_GetFactory +}; + +void d2d_effect_init(struct d2d_effect *effect, ID2D1Factory *factory) { effect->ID2D1Effect_iface.lpVtbl = &d2d_effect_vtbl; + effect->ID2D1Image_iface.lpVtbl = &d2d_effect_image_vtbl; effect->refcount = 1; + ID2D1Factory_AddRef(effect->factory = factory); } diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index f0f6e054047..48fc064f91e 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -9703,10 +9703,7 @@ static void test_effect(BOOL d3d11) ok(hr == S_OK, "Failed to create effect, hr %#x.\n", hr);
hr = ID2D1Effect_QueryInterface(effect, &IID_ID2D1Image, (void **)&image_a); - todo_wine ok(hr == S_OK, "Failed to get image interface, hr %#x.\n", hr); - if (hr != S_OK) - goto end;
ID2D1Effect_GetOutput(effect, &image_b); todo_wine
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/effect.c | 6 +++++- dlls/d2d1/tests/d2d1.c | 1 - 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 50cd8864921..09ff140884b 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -193,7 +193,11 @@ static UINT32 STDMETHODCALLTYPE d2d_effect_GetInputCount(ID2D1Effect *iface)
static void STDMETHODCALLTYPE d2d_effect_GetOutput(ID2D1Effect *iface, ID2D1Image **output) { - FIXME("iface %p, output %p stub!\n", iface, output); + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + + TRACE("iface %p, output %p.\n", iface, output); + + ID2D1Image_AddRef(*output = &effect->ID2D1Image_iface); }
static HRESULT STDMETHODCALLTYPE d2d_effect_image_QueryInterface(ID2D1Image *iface, REFIID iid, void **out) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 48fc064f91e..76ca9500cfb 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -9706,7 +9706,6 @@ static void test_effect(BOOL d3d11) ok(hr == S_OK, "Failed to get image interface, hr %#x.\n", hr);
ID2D1Effect_GetOutput(effect, &image_b); - todo_wine ok(image_a == image_b, "Image interface mismatch.\n");
end:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=94065
Your paranoid android.
=== debiant2 (32 bit Chinese:China report) ===
Report validation errors: d2d1:d2d1 is missing some skip messages