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