From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/d2d1_private.h | 3 + dlls/d2d1/effect.c | 130 ++++++++++++++++++++++++++++++++++++++- dlls/d2d1/tests/d2d1.c | 41 +++++++----- 3 files changed, 157 insertions(+), 17 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 1ea0e1fdbd3..177b4149cbf 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -716,7 +716,10 @@ struct d2d_transform union { D2D1_POINT_2L offset; + D2D1_BLEND_DESCRIPTION blend_desc; }; + + UINT32 input_count; };
struct d2d_transform_graph diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 0c9c027aed0..3fb48db8bb0 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -25,6 +25,11 @@ static inline struct d2d_transform *impl_from_ID2D1OffsetTransform(ID2D1OffsetTr return CONTAINING_RECORD(iface, struct d2d_transform, ID2D1TransformNode_iface); }
+static inline struct d2d_transform *impl_from_ID2D1BlendTransform(ID2D1BlendTransform *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_transform, ID2D1TransformNode_iface); +} + static HRESULT STDMETHODCALLTYPE d2d_offset_transform_QueryInterface(ID2D1OffsetTransform *iface, REFIID iid, void **out) { @@ -121,6 +126,127 @@ static HRESULT d2d_offset_transform_create(D2D1_POINT_2L offset, ID2D1OffsetTran return S_OK; }
+static HRESULT STDMETHODCALLTYPE d2d_blend_transform_QueryInterface(ID2D1BlendTransform *iface, + REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1BlendTransform) + || IsEqualGUID(iid, &IID_ID2D1ConcreteTransform) + || IsEqualGUID(iid, &IID_ID2D1TransformNode) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *out = iface; + ID2D1BlendTransform_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_blend_transform_AddRef(ID2D1BlendTransform *iface) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + ULONG refcount = InterlockedIncrement(&transform->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_blend_transform_Release(ID2D1BlendTransform *iface) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + ULONG refcount = InterlockedDecrement(&transform->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + free(transform); + + return refcount; +} + +static UINT32 STDMETHODCALLTYPE d2d_blend_transform_GetInputCount(ID2D1BlendTransform *iface) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + + TRACE("iface %p.\n", iface); + + return transform->input_count; +} + +static HRESULT STDMETHODCALLTYPE d2d_blend_transform_SetOutputBuffer(ID2D1BlendTransform *iface, + D2D1_BUFFER_PRECISION precision, D2D1_CHANNEL_DEPTH depth) +{ + FIXME("iface %p, precision %u, depth %u stub.\n", iface, precision, depth); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d2d_blend_transform_SetCached(ID2D1BlendTransform *iface, + BOOL is_cached) +{ + FIXME("iface %p, is_cached %d stub.\n", iface, is_cached); +} + +static void STDMETHODCALLTYPE d2d_blend_transform_SetDescription(ID2D1BlendTransform *iface, + const D2D1_BLEND_DESCRIPTION *description) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + + TRACE("iface %p, description %p.\n", iface, description); + + transform->blend_desc = *description; +} + +static void STDMETHODCALLTYPE d2d_blend_transform_GetDescription(ID2D1BlendTransform *iface, + D2D1_BLEND_DESCRIPTION *description) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + + TRACE("iface %p, description %p.\n", iface, description); + + *description = transform->blend_desc; +} + +static const ID2D1BlendTransformVtbl d2d_blend_transform_vtbl = +{ + d2d_blend_transform_QueryInterface, + d2d_blend_transform_AddRef, + d2d_blend_transform_Release, + d2d_blend_transform_GetInputCount, + d2d_blend_transform_SetOutputBuffer, + d2d_blend_transform_SetCached, + d2d_blend_transform_SetDescription, + d2d_blend_transform_GetDescription, +}; + +static HRESULT d2d_blend_transform_create(UINT32 input_count, const D2D1_BLEND_DESCRIPTION *blend_desc, + ID2D1BlendTransform **transform) +{ + struct d2d_transform *object; + + *transform = NULL; + + if (!input_count) + return E_INVALIDARG; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1TransformNode_iface.lpVtbl = (ID2D1TransformNodeVtbl *)&d2d_blend_transform_vtbl; + object->refcount = 1; + object->input_count = input_count; + object->blend_desc = *blend_desc; + + *transform = (ID2D1BlendTransform *)&object->ID2D1TransformNode_iface; + + return S_OK; +} + static inline struct d2d_transform_graph *impl_from_ID2D1TransformGraph(ID2D1TransformGraph *iface) { return CONTAINING_RECORD(iface, struct d2d_transform_graph, ID2D1TransformGraph_iface); @@ -887,9 +1013,9 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateTransformNodeFromEffec static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateBlendTransform(ID2D1EffectContext *iface, UINT32 num_inputs, const D2D1_BLEND_DESCRIPTION *description, ID2D1BlendTransform **transform) { - FIXME("iface %p, num_inputs %u, description %p, transform %p stub!\n", iface, num_inputs, description, transform); + TRACE("iface %p, num_inputs %u, description %p, transform %p,\n", iface, num_inputs, description, transform);
- return E_NOTIMPL; + return d2d_blend_transform_create(num_inputs, description, transform); }
static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateBorderTransform(ID2D1EffectContext *iface, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 4fb9893fd14..b26e5d6fe3c 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12724,71 +12724,81 @@ static void test_transform_graph(BOOL d3d11) hr = ID2D1EffectContext_CreateOffsetTransform(effect_context, point, &offset_transform); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1EffectContext_CreateBlendTransform(effect_context, 2, &blend_desc, &blend_transform); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (!offset_transform || !blend_transform) - goto done; + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* Add nodes */ hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); + todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)blend_transform); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* Remove nodes */ hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)offset_transform); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)offset_transform); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)blend_transform); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* Connect nodes which are both un-added */ ID2D1TransformGraph_Clear(graph); hr = ID2D1TransformGraph_ConnectNode(graph, (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, 0); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr);
/* Connect added node to un-added node */ hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_ConnectNode(graph, (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, 0); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr);
/* Connect un-added node to added node */ ID2D1TransformGraph_Clear(graph); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)blend_transform); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_ConnectNode(graph, (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, 0); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr);
/* Connect nodes */ ID2D1TransformGraph_Clear(graph); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)blend_transform); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); count = ID2D1BlendTransform_GetInputCount(blend_transform); for (i = 0; i < count; ++i) { hr = ID2D1TransformGraph_ConnectNode(graph, (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, i); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); }
/* Connect node to out-of-bounds index */ hr = ID2D1TransformGraph_ConnectNode(graph, (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, count); + todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
-done: - if (blend_transform) - ID2D1BlendTransform_Release(blend_transform); - if (offset_transform) - ID2D1OffsetTransform_Release(offset_transform); + ID2D1BlendTransform_Release(blend_transform); + ID2D1OffsetTransform_Release(offset_transform); ID2D1Effect_Release(effect); hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); @@ -12932,12 +12942,12 @@ static void test_blend_transform(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* Create transform */ + transform = (void *)0xdeadbeef; hr = ID2D1EffectContext_CreateBlendTransform(effect_context, 0, &expected, &transform); - todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ok(!transform, "Unexpected pointer %p.\n", transform); hr = ID2D1EffectContext_CreateBlendTransform(effect_context, 1, &expected, &transform); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (hr != S_OK) - goto done; + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ID2D1BlendTransform_Release(transform); hr = ID2D1EffectContext_CreateBlendTransform(effect_context, 4, &expected, &transform); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); @@ -12952,10 +12962,13 @@ static void test_blend_transform(BOOL d3d11)
/* Set output buffer */ hr = ID2D1BlendTransform_SetOutputBuffer(transform, 0xdeadbeef, D2D1_CHANNEL_DEPTH_DEFAULT); + todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1BlendTransform_SetOutputBuffer(transform, D2D1_BUFFER_PRECISION_UNKNOWN, 0xdeadbeef); + todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1BlendTransform_SetOutputBuffer(transform, D2D1_BUFFER_PRECISION_UNKNOWN, D2D1_CHANNEL_DEPTH_DEFAULT); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* Set description */ @@ -12973,9 +12986,7 @@ static void test_blend_transform(BOOL d3d11) ID2D1BlendTransform_GetDescription(transform, &blend_desc); check_blend_desc(&blend_desc, &expected);
-done: - if (transform) - ID2D1BlendTransform_Release(transform); + ID2D1BlendTransform_Release(transform); ID2D1Effect_Release(effect); hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);