From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 301cbdca51f..862a08ae467 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -34,6 +34,28 @@ DEFINE_GUID(CLSID_TestEffect, 0xb9ee12e9,0x32d9,0xe659,0xac,0x61,0x2d,0x7c,0xea, DEFINE_GUID(GUID_TestVertexShader, 0x5bcdcfae,0x1e92,0x4dc1,0x94,0xfa,0x3b,0x01,0xca,0x54,0x59,0x20); DEFINE_GUID(GUID_TestPixelShader, 0x53015748,0xfc13,0x4168,0xbd,0x13,0x0f,0xcf,0x15,0x29,0x7f,0x01);
+static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + +#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) +static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported) +{ + IUnknown *iface = iface_ptr; + HRESULT hr, expected_hr; + IUnknown *unk; + + expected_hr = supported ? S_OK : E_NOINTERFACE; + + hr = IUnknown_QueryInterface(iface, iid, (void **)&unk); + ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr); + if (SUCCEEDED(hr)) + IUnknown_Release(unk); +} + static const WCHAR *effect_xml_a = L"<?xml version='1.0'?> \ <Effect> \ @@ -14365,6 +14387,15 @@ static HRESULT STDMETHODCALLTYPE effect_impl_draw_transform_MapInvalidRect( static HRESULT STDMETHODCALLTYPE effect_impl_draw_transform_SetDrawInfo(ID2D1DrawTransform *iface, ID2D1DrawInfo *info) { + ULONG refcount; + + check_interface(info, &IID_IUnknown, TRUE); + check_interface(info, &IID_ID2D1RenderInfo, TRUE); + check_interface(info, &IID_ID2D1EffectContext, FALSE); + + refcount = get_refcount(info); + ok(refcount == 1, "Unexpected refcount %lu.\n", refcount); + return ID2D1DrawInfo_SetPixelShader(info, &GUID_TestPixelShader, 0); }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 862a08ae467..b6db1e81178 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -267,6 +267,9 @@ L"<?xml version='1.0'?> \ <Input name='Source2'/> \ <Input name='Source3'/> \ </Inputs> \ + <Property name='Graph' type='iunknown'> \ + <Property name='DisplayName' type='string' value='Graph'/> \ + </Property> \ </Effect> \ ";
@@ -11284,10 +11287,12 @@ static void test_effect_register(BOOL d3d11) ID2D1DeviceContext *device_context; ID2D1EffectContext *effect_context; struct d2d1_test_context ctx; + ID2D1TransformGraph *graph; unsigned int i, integer; ID2D1Factory1 *factory; WCHAR display_name[64]; ID2D1Effect *effect; + UINT32 count; HRESULT hr;
const struct xml_test @@ -11320,6 +11325,11 @@ static void test_effect_register(BOOL d3d11) {L"DeadBeef", effect_impl_set_integer, effect_impl_get_integer}, };
+ static const D2D1_PROPERTY_BINDING bindings2[] = + { + {L"Graph", NULL, effect_impl_get_graph}, + }; + const struct binding_test { const D2D1_PROPERTY_BINDING *binding; @@ -11502,13 +11512,20 @@ static void test_effect_register(BOOL d3d11)
/* Variable input count. */ hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, - effect_variable_input_count, NULL, 0, effect_impl_create); + effect_variable_input_count, bindings2, ARRAY_SIZE(bindings2), effect_impl_create); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1DeviceContext_CreateEffect(device_context, &CLSID_TestEffect, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); integer = ID2D1Effect_GetInputCount(effect); ok(integer == 3, "Unexpected input count %u.\n", integer);
+ hr = ID2D1Effect_GetValueByName(effect, L"Graph", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&graph, sizeof(graph)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + count = ID2D1TransformGraph_GetInputCount(graph); + todo_wine + ok(count == 3, "Unexpected input count %u.\n", count); + integer = 0; hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); @@ -11529,6 +11546,12 @@ static void test_effect_register(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(integer == 3, "Unexpected data %u.\n", integer);
+ hr = ID2D1Effect_GetValueByName(effect, L"Graph", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&graph, sizeof(graph)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + count = ID2D1TransformGraph_GetInputCount(graph); + todo_wine + ok(count == 4, "Unexpected input count %u.\n", count); + ID2D1Effect_Release(effect);
hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); @@ -12696,6 +12719,10 @@ static void test_transform_graph(BOOL d3d11) D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ count = ID2D1TransformGraph_GetInputCount(graph); + todo_wine + ok(count == 1, "Unexpected input count %u.\n", count); + /* Create transforms */ hr = ID2D1EffectContext_CreateOffsetTransform(effect_context, point, &offset_transform); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/d2d1_private.h | 2 ++ dlls/d2d1/effect.c | 51 +++++++++++++++++++++++----------------- dlls/d2d1/tests/d2d1.c | 3 --- 3 files changed, 31 insertions(+), 25 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index dced9847390..9c314e08694 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -712,6 +712,8 @@ struct d2d_transform_graph { ID2D1TransformGraph ID2D1TransformGraph_iface; LONG refcount; + + UINT32 input_count; };
struct d2d_effect diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 50c4b01de12..3a3bc896fe9 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -66,9 +66,11 @@ static ULONG STDMETHODCALLTYPE d2d_transform_graph_Release(ID2D1TransformGraph *
static UINT32 STDMETHODCALLTYPE d2d_transform_graph_GetInputCount(ID2D1TransformGraph *iface) { - FIXME("iface %p stub!\n", iface); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + + TRACE("iface %p.\n", iface);
- return 0; + return graph->input_count; }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetSingleTransformNode(ID2D1TransformGraph *iface, @@ -144,10 +146,20 @@ static const ID2D1TransformGraphVtbl d2d_transform_graph_vtbl = d2d_transform_graph_SetPassthroughGraph, };
-static void d2d_transform_graph_init(struct d2d_transform_graph *graph) +static HRESULT d2d_transform_graph_create(UINT32 input_count, struct d2d_transform_graph **graph) { - graph->ID2D1TransformGraph_iface.lpVtbl = &d2d_transform_graph_vtbl; - graph->refcount = 1; + struct d2d_transform_graph *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1TransformGraph_iface.lpVtbl = &d2d_transform_graph_vtbl; + object->refcount = 1; + object->input_count = input_count; + + *graph = object; + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_effect_impl_QueryInterface(ID2D1EffectImpl *iface, REFIID iid, void **out) @@ -1273,12 +1285,11 @@ static HRESULT d2d_effect_set_input_count(struct d2d_effect *effect, UINT32 coun ID2D1TransformGraph_Release(&effect->graph->ID2D1TransformGraph_iface); effect->graph = NULL;
- if (!(effect->graph = calloc(1, sizeof(*effect->graph)))) - return E_OUTOFMEMORY; - d2d_transform_graph_init(effect->graph); - - if (FAILED(hr = ID2D1EffectImpl_SetGraph(effect->impl, &effect->graph->ID2D1TransformGraph_iface))) - WARN("Failed to set a new transform graph, hr %#lx.\n", hr); + if (SUCCEEDED(hr = d2d_transform_graph_create(count, &effect->graph))) + { + if (FAILED(hr = ID2D1EffectImpl_SetGraph(effect->impl, &effect->graph->ID2D1TransformGraph_iface))) + WARN("Failed to set a new transform graph, hr %#lx.\n", hr); + } }
return hr; @@ -1626,7 +1637,6 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec { struct d2d_effect_context *effect_context; const struct d2d_effect_registration *reg; - struct d2d_transform_graph *graph; struct d2d_effect *object; UINT32 input_count; WCHAR clsidW[39]; @@ -1642,16 +1652,8 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec return E_OUTOFMEMORY; d2d_effect_context_init(effect_context, context);
- if (!(graph = calloc(1, sizeof(*graph)))) - { - ID2D1EffectContext_Release(&effect_context->ID2D1EffectContext_iface); - return E_OUTOFMEMORY; - } - d2d_transform_graph_init(graph); - if (!(object = calloc(1, sizeof(*object)))) { - ID2D1TransformGraph_Release(&graph->ID2D1TransformGraph_iface); ID2D1EffectContext_Release(&effect_context->ID2D1EffectContext_iface); return E_OUTOFMEMORY; } @@ -1660,7 +1662,6 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec object->ID2D1Image_iface.lpVtbl = &d2d_effect_image_vtbl; object->refcount = 1; object->effect_context = effect_context; - object->graph = graph;
/* Create properties */ d2d_effect_duplicate_properties(&object->properties, ®->properties); @@ -1675,6 +1676,12 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec d2d_effect_get_value(object, D2D1_PROPERTY_INPUTS, D2D1_PROPERTY_TYPE_ARRAY, (BYTE *)&input_count, sizeof(input_count)); d2d_effect_set_input_count(object, input_count);
+ if (FAILED(hr = d2d_transform_graph_create(input_count, &object->graph))) + { + ID2D1EffectContext_Release(&effect_context->ID2D1EffectContext_iface); + return hr; + } + if (FAILED(hr = reg->factory((IUnknown **)&object->impl))) { WARN("Failed to create implementation object, hr %#lx.\n", hr); @@ -1683,7 +1690,7 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec }
if (FAILED(hr = ID2D1EffectImpl_Initialize(object->impl, &effect_context->ID2D1EffectContext_iface, - &graph->ID2D1TransformGraph_iface))) + &object->graph->ID2D1TransformGraph_iface))) { WARN("Failed to initialize effect, hr %#lx.\n", hr); ID2D1Effect_Release(&object->ID2D1Effect_iface); diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index b6db1e81178..05ed2d985e5 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -11523,7 +11523,6 @@ static void test_effect_register(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
count = ID2D1TransformGraph_GetInputCount(graph); - todo_wine ok(count == 3, "Unexpected input count %u.\n", count);
integer = 0; @@ -11549,7 +11548,6 @@ static void test_effect_register(BOOL d3d11) hr = ID2D1Effect_GetValueByName(effect, L"Graph", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&graph, sizeof(graph)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); count = ID2D1TransformGraph_GetInputCount(graph); - todo_wine ok(count == 4, "Unexpected input count %u.\n", count);
ID2D1Effect_Release(effect); @@ -12720,7 +12718,6 @@ static void test_transform_graph(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
count = ID2D1TransformGraph_GetInputCount(graph); - todo_wine ok(count == 1, "Unexpected input count %u.\n", count);
/* Create transforms */
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/d2d1_private.h | 11 ++++ dlls/d2d1/effect.c | 105 ++++++++++++++++++++++++++++++++++++++- dlls/d2d1/tests/d2d1.c | 10 ++-- 3 files changed, 117 insertions(+), 9 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 9c314e08694..1ea0e1fdbd3 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -708,6 +708,17 @@ void d2d_factory_register_effect(struct d2d_factory *factory, HRESULT d2d_effect_property_get_uint32_value(const struct d2d_effect_properties *properties, const struct d2d_effect_property *prop, UINT32 *value);
+struct d2d_transform +{ + ID2D1TransformNode ID2D1TransformNode_iface; + LONG refcount; + + union + { + D2D1_POINT_2L offset; + }; +}; + struct d2d_transform_graph { ID2D1TransformGraph ID2D1TransformGraph_iface; diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 3a3bc896fe9..0c9c027aed0 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -20,6 +20,107 @@
WINE_DEFAULT_DEBUG_CHANNEL(d2d);
+static inline struct d2d_transform *impl_from_ID2D1OffsetTransform(ID2D1OffsetTransform *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_transform, ID2D1TransformNode_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_offset_transform_QueryInterface(ID2D1OffsetTransform *iface, + REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID2D1OffsetTransform) + || IsEqualGUID(iid, &IID_ID2D1TransformNode) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *out = iface; + ID2D1OffsetTransform_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_offset_transform_AddRef(ID2D1OffsetTransform *iface) +{ + struct d2d_transform *transform = impl_from_ID2D1OffsetTransform(iface); + ULONG refcount = InterlockedIncrement(&transform->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_offset_transform_Release(ID2D1OffsetTransform *iface) +{ + struct d2d_transform *transform = impl_from_ID2D1OffsetTransform(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_offset_transform_GetInputCount(ID2D1OffsetTransform *iface) +{ + TRACE("iface %p.\n", iface); + + return 1; +} + +static void STDMETHODCALLTYPE d2d_offset_transform_SetOffset(ID2D1OffsetTransform *iface, + D2D1_POINT_2L offset) +{ + struct d2d_transform *transform = impl_from_ID2D1OffsetTransform(iface); + + TRACE("iface %p, offset %s.\n", iface, debug_d2d_point_2l(&offset)); + + transform->offset = offset; +} + +static D2D1_POINT_2L * STDMETHODCALLTYPE d2d_offset_transform_GetOffset(ID2D1OffsetTransform *iface, + D2D1_POINT_2L *offset) +{ + struct d2d_transform *transform = impl_from_ID2D1OffsetTransform(iface); + + TRACE("iface %p.\n", iface); + + *offset = transform->offset; + return offset; +} + +static const ID2D1OffsetTransformVtbl d2d_offset_transform_vtbl = +{ + d2d_offset_transform_QueryInterface, + d2d_offset_transform_AddRef, + d2d_offset_transform_Release, + d2d_offset_transform_GetInputCount, + d2d_offset_transform_SetOffset, + d2d_offset_transform_GetOffset, +}; + +static HRESULT d2d_offset_transform_create(D2D1_POINT_2L offset, ID2D1OffsetTransform **transform) +{ + struct d2d_transform *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1TransformNode_iface.lpVtbl = (ID2D1TransformNodeVtbl *)&d2d_offset_transform_vtbl; + object->refcount = 1; + object->offset = offset; + + *transform = (ID2D1OffsetTransform *)&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); @@ -802,9 +903,9 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateBorderTransform(ID2D1E static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateOffsetTransform(ID2D1EffectContext *iface, D2D1_POINT_2L offset, ID2D1OffsetTransform **transform) { - FIXME("iface %p, offset %s, transform %p stub!\n", iface, debug_d2d_point_2l(&offset), transform); + TRACE("iface %p, offset %s, transform %p.\n", iface, debug_d2d_point_2l(&offset), transform);
- return E_NOTIMPL; + return d2d_offset_transform_create(offset, transform); }
static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateBoundsAdjustmentTransform(ID2D1EffectContext *iface, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 05ed2d985e5..4fb9893fd14 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12722,7 +12722,7 @@ static void test_transform_graph(BOOL d3d11)
/* Create transforms */ hr = ID2D1EffectContext_CreateOffsetTransform(effect_context, point, &offset_transform); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + 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) @@ -12836,9 +12836,7 @@ static void test_offset_transform(BOOL d3d11) offset.x = 1; offset.y = 2; hr = ID2D1EffectContext_CreateOffsetTransform(effect_context, offset, &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); offset = ID2D1OffsetTransform_GetOffset(transform); ok(offset.x == 1 && offset.y == 2, "Got unexpected offset {%ld, %ld}.\n", offset.x, offset.y);
@@ -12853,9 +12851,7 @@ static void test_offset_transform(BOOL d3d11) offset = ID2D1OffsetTransform_GetOffset(transform); ok(offset.x == -10 && offset.y == 20, "Got unexpected offset {%ld, %ld}.\n", offset.x, offset.y);
-done: - if (transform) - ID2D1OffsetTransform_Release(transform); + ID2D1OffsetTransform_Release(transform); ID2D1Effect_Release(effect); hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
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);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/d2d1_private.h | 8 ++++ dlls/d2d1/effect.c | 84 ++++++++++++++++++++++++++++++++++++---- dlls/d2d1/tests/d2d1.c | 10 ----- 3 files changed, 85 insertions(+), 17 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 177b4149cbf..1f5093e29a4 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -722,12 +722,20 @@ struct d2d_transform UINT32 input_count; };
+struct d2d_transform_node +{ + struct list entry; + ID2D1TransformNode *object; +}; + struct d2d_transform_graph { ID2D1TransformGraph ID2D1TransformGraph_iface; LONG refcount;
UINT32 input_count; + + struct list nodes; };
struct d2d_effect diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 3fb48db8bb0..f441abde2b9 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -247,6 +247,54 @@ static HRESULT d2d_blend_transform_create(UINT32 input_count, const D2D1_BLEND_D return S_OK; }
+static struct d2d_transform_node * d2d_transform_graph_get_node(const struct d2d_transform_graph *graph, + ID2D1TransformNode *object) +{ + struct d2d_transform_node *node; + + LIST_FOR_EACH_ENTRY(node, &graph->nodes, struct d2d_transform_node, entry) + { + if (node->object == object) + return node; + } + + return NULL; +} + +static HRESULT d2d_transform_graph_add_node(struct d2d_transform_graph *graph, + ID2D1TransformNode *object) +{ + struct d2d_transform_node *node; + + if (!(node = calloc(1, sizeof(*node)))) + return E_OUTOFMEMORY; + + node->object = object; + ID2D1TransformNode_AddRef(node->object); + list_add_tail(&graph->nodes, &node->entry); + + return S_OK; +} + +static void d2d_transform_graph_delete_node(struct d2d_transform_graph *graph, + struct d2d_transform_node *node) +{ + list_remove(&node->entry); + ID2D1TransformNode_Release(node->object); + + free(node); +} + +static void d2d_transform_graph_clear(struct d2d_transform_graph *graph) +{ + struct d2d_transform_node *node, *node_next; + + LIST_FOR_EACH_ENTRY_SAFE(node, node_next, &graph->nodes, struct d2d_transform_node, entry) + { + d2d_transform_graph_delete_node(graph, node); + } +} + static inline struct d2d_transform_graph *impl_from_ID2D1TransformGraph(ID2D1TransformGraph *iface) { return CONTAINING_RECORD(iface, struct d2d_transform_graph, ID2D1TransformGraph_iface); @@ -286,7 +334,10 @@ static ULONG STDMETHODCALLTYPE d2d_transform_graph_Release(ID2D1TransformGraph * TRACE("%p decreasing refcount to %lu.\n", iface, refcount);
if (!refcount) + { + d2d_transform_graph_clear(graph); free(graph); + }
return refcount; } @@ -308,18 +359,32 @@ static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetSingleTransformNode(ID2D return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE d2d_transform_graph_AddNode(ID2D1TransformGraph *iface, ID2D1TransformNode *node) +static HRESULT STDMETHODCALLTYPE d2d_transform_graph_AddNode(ID2D1TransformGraph *iface, + ID2D1TransformNode *object) { - FIXME("iface %p, node %p stub!\n", iface, node); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface);
- return E_NOTIMPL; + TRACE("iface %p, object %p.\n", iface, object); + + if (d2d_transform_graph_get_node(graph, object)) + return E_INVALIDARG; + + return d2d_transform_graph_add_node(graph, object); }
-static HRESULT STDMETHODCALLTYPE d2d_transform_graph_RemoveNode(ID2D1TransformGraph *iface, ID2D1TransformNode *node) +static HRESULT STDMETHODCALLTYPE d2d_transform_graph_RemoveNode(ID2D1TransformGraph *iface, + ID2D1TransformNode *object) { - FIXME("iface %p, node %p stub!\n", iface, node); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *node;
- return E_NOTIMPL; + TRACE("iface %p, object %p.\n", iface, object); + + if (!(node = d2d_transform_graph_get_node(graph, object))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + d2d_transform_graph_delete_node(graph, node); + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetOutputNode(ID2D1TransformGraph *iface, ID2D1TransformNode *node) @@ -347,7 +412,11 @@ static HRESULT STDMETHODCALLTYPE d2d_transform_graph_ConnectToEffectInput(ID2D1T
static void STDMETHODCALLTYPE d2d_transform_graph_Clear(ID2D1TransformGraph *iface) { - FIXME("iface %p stub!\n", iface); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + + TRACE("iface %p.\n", iface); + + d2d_transform_graph_clear(graph); }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetPassthroughGraph(ID2D1TransformGraph *iface, UINT32 index) @@ -383,6 +452,7 @@ static HRESULT d2d_transform_graph_create(UINT32 input_count, struct d2d_transfo object->ID2D1TransformGraph_iface.lpVtbl = &d2d_transform_graph_vtbl; object->refcount = 1; object->input_count = input_count; + list_init(&object->nodes);
*graph = object;
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index b26e5d6fe3c..15d3b8b82ee 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12728,24 +12728,18 @@ static void test_transform_graph(BOOL d3d11)
/* 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 */ @@ -12757,7 +12751,6 @@ static void test_transform_graph(BOOL d3d11)
/* 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); @@ -12767,7 +12760,6 @@ static void test_transform_graph(BOOL d3d11) /* 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); @@ -12777,10 +12769,8 @@ static void test_transform_graph(BOOL d3d11) /* 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)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/d2d1_private.h | 9 ++++++++- dlls/d2d1/effect.c | 40 ++++++++++++++++++++++++++++++++++++---- dlls/d2d1/tests/d2d1.c | 11 +++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 1f5093e29a4..d59fbf10013 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -728,12 +728,19 @@ struct d2d_transform_node ID2D1TransformNode *object; };
+struct d2d_transform_node_connection +{ + struct d2d_transform_node *node; + unsigned int index; +}; + struct d2d_transform_graph { ID2D1TransformGraph ID2D1TransformGraph_iface; LONG refcount;
- UINT32 input_count; + struct d2d_transform_node_connection *inputs; + unsigned int input_count;
struct list nodes; }; diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index f441abde2b9..a6a0d33a5a8 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -279,9 +279,17 @@ static HRESULT d2d_transform_graph_add_node(struct d2d_transform_graph *graph, static void d2d_transform_graph_delete_node(struct d2d_transform_graph *graph, struct d2d_transform_node *node) { + unsigned int i; + list_remove(&node->entry); ID2D1TransformNode_Release(node->object);
+ for (i = 0; i < graph->input_count; ++i) + { + if (graph->inputs[i].node == node) + memset(&graph->inputs[i].node, 0, sizeof(graph->inputs[i].node)); + } + free(node); }
@@ -336,6 +344,7 @@ static ULONG STDMETHODCALLTYPE d2d_transform_graph_Release(ID2D1TransformGraph * if (!refcount) { d2d_transform_graph_clear(graph); + free(graph->inputs); free(graph); }
@@ -403,11 +412,28 @@ static HRESULT STDMETHODCALLTYPE d2d_transform_graph_ConnectNode(ID2D1TransformG }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_ConnectToEffectInput(ID2D1TransformGraph *iface, - UINT32 input_index, ID2D1TransformNode *node, UINT32 node_index) + UINT32 input_index, ID2D1TransformNode *object, UINT32 node_index) { - FIXME("iface %p, input_index %u, node %p, node_index %u stub!\n", iface, input_index, node, node_index); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *node; + unsigned int count;
- return E_NOTIMPL; + TRACE("iface %p, input_index %u, object %p, node_index %u.\n", iface, input_index, object, node_index); + + if (!(node = d2d_transform_graph_get_node(graph, object))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + if (input_index >= graph->input_count) + return E_INVALIDARG; + + count = ID2D1TransformNode_GetInputCount(object); + if (node_index >= count) + return E_INVALIDARG; + + graph->inputs[input_index].node = node; + graph->inputs[input_index].index = node_index; + + return S_OK; }
static void STDMETHODCALLTYPE d2d_transform_graph_Clear(ID2D1TransformGraph *iface) @@ -451,9 +477,15 @@ static HRESULT d2d_transform_graph_create(UINT32 input_count, struct d2d_transfo
object->ID2D1TransformGraph_iface.lpVtbl = &d2d_transform_graph_vtbl; object->refcount = 1; - object->input_count = input_count; list_init(&object->nodes);
+ if (!(object->inputs = calloc(input_count, sizeof(*object->inputs)))) + { + free(object); + return E_OUTOFMEMORY; + } + object->input_count = input_count; + *graph = object;
return S_OK; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 15d3b8b82ee..b2d1296bdde 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12727,6 +12727,8 @@ static void test_transform_graph(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* Add nodes */ + hr = ID2D1TransformGraph_ConnectToEffectInput(graph, 1, (ID2D1TransformNode *)offset_transform, 0); + ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); @@ -12734,6 +12736,15 @@ static void test_transform_graph(BOOL d3d11) hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)blend_transform); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ /* Invalid effect input index. */ + hr = ID2D1TransformGraph_ConnectToEffectInput(graph, 1, (ID2D1TransformNode *)offset_transform, 0); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + /* Invalid object input index. */ + hr = ID2D1TransformGraph_ConnectToEffectInput(graph, 0, (ID2D1TransformNode *)offset_transform, 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_ConnectToEffectInput(graph, 0, (ID2D1TransformNode *)offset_transform, 0); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + /* Remove nodes */ hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)offset_transform); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/d2d1_private.h | 2 ++ dlls/d2d1/effect.c | 18 +++++++++++++++--- dlls/d2d1/tests/d2d1.c | 4 ++++ 3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index d59fbf10013..3589b508704 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -742,6 +742,8 @@ struct d2d_transform_graph struct d2d_transform_node_connection *inputs; unsigned int input_count;
+ struct d2d_transform_node *output; + struct list nodes; };
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index a6a0d33a5a8..3eb1dba7ea1 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -290,6 +290,9 @@ static void d2d_transform_graph_delete_node(struct d2d_transform_graph *graph, memset(&graph->inputs[i].node, 0, sizeof(graph->inputs[i].node)); }
+ if (graph->output == node) + graph->output = NULL; + free(node); }
@@ -396,11 +399,20 @@ static HRESULT STDMETHODCALLTYPE d2d_transform_graph_RemoveNode(ID2D1TransformGr return S_OK; }
-static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetOutputNode(ID2D1TransformGraph *iface, ID2D1TransformNode *node) +static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetOutputNode(ID2D1TransformGraph *iface, + ID2D1TransformNode *object) { - FIXME("iface %p, node %p stub!\n", iface, node); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *node;
- return E_NOTIMPL; + TRACE("iface %p, object %p.\n", iface, object); + + if (!(node = d2d_transform_graph_get_node(graph, object))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + graph->output = node; + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_ConnectNode(ID2D1TransformGraph *iface, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index b2d1296bdde..cb779104552 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12729,6 +12729,8 @@ static void test_transform_graph(BOOL d3d11) /* Add nodes */ hr = ID2D1TransformGraph_ConnectToEffectInput(graph, 1, (ID2D1TransformNode *)offset_transform, 0); ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_SetOutputNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); @@ -12744,6 +12746,8 @@ static void test_transform_graph(BOOL d3d11) ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_ConnectToEffectInput(graph, 0, (ID2D1TransformNode *)offset_transform, 0); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_SetOutputNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* Remove nodes */ hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)offset_transform);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/effect.c | 28 +++++++++++++++++++++++++--- dlls/d2d1/tests/d2d1.c | 18 ++++++++++++------ 2 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 3eb1dba7ea1..cf715332fde 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -364,11 +364,33 @@ static UINT32 STDMETHODCALLTYPE d2d_transform_graph_GetInputCount(ID2D1Transform }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetSingleTransformNode(ID2D1TransformGraph *iface, - ID2D1TransformNode *node) + ID2D1TransformNode *object) { - FIXME("iface %p, node %p stub!\n", iface, node); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *node; + unsigned int i, input_count; + HRESULT hr;
- return E_NOTIMPL; + TRACE("iface %p, object %p.\n", iface, object); + + d2d_transform_graph_clear(graph); + if (FAILED(hr = d2d_transform_graph_add_node(graph, object))) + return hr; + + node = d2d_transform_graph_get_node(graph, object); + graph->output = node; + + input_count = ID2D1TransformNode_GetInputCount(object); + if (graph->input_count != input_count) + return E_INVALIDARG; + + for (i = 0; i < graph->input_count; ++i) + { + graph->inputs[i].node = node; + graph->inputs[i].index = i; + } + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_AddNode(ID2D1TransformGraph *iface, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index cb779104552..723cc1f8384 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12731,6 +12731,18 @@ static void test_transform_graph(BOOL d3d11) ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_SetOutputNode(graph, (ID2D1TransformNode *)offset_transform); ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); + + /* Single input effect, single input node. */ + hr = ID2D1TransformGraph_SetSingleTransformNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Single input effect, two-input node. */ + hr = ID2D1TransformGraph_SetSingleTransformNode(graph, (ID2D1TransformNode *)blend_transform); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)blend_transform); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ID2D1TransformGraph_Clear(graph); + hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); @@ -14507,13 +14519,7 @@ static void test_effect_custom_pixel_shader(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_TestEffect, &effect); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (FAILED(hr)) - { - release_test_context(&ctx); - return; - }
set_size_u(&input_size, 1, 1); pixel = 0xabcd00ff;