Signed-off-by: Ziqing Hui zhui@codeweavers.com
-- v2: d2d1: Implement ID2D1BlendTransform. d2d1/tests: Test ID2D1BorderTransform. d2d1/tests: Test ID2D1BlendTransform. d2d1: Implement ID2D1OffsetTransform. d2d1/tests: Add tests for ID2D1OffsetTransform. d2d1/tests: Add tests for ID2D1TransformGraph.
From: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 143 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 1 deletion(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 3a38d593625..5be8cdb707d 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -132,6 +132,9 @@ L"<?xml version='1.0'?> \ <Property name='Integer' type='uint32'> \ <Property name='DisplayName' type='string' value='Integer'/> \ </Property> \ + <Property name='Graph' type='iunknown'> \ + <Property name='DisplayName' type='string' value='Graph'/> \ + </Property> \ </Effect> \ ";
@@ -350,6 +353,7 @@ struct effect_impl LONG refcount; UINT integer; ID2D1EffectContext *effect_context; + ID2D1TransformGraph *transform_graph; };
static void queue_d3d1x_test(void (*test)(BOOL d3d11), BOOL d3d11) @@ -10690,6 +10694,7 @@ static HRESULT STDMETHODCALLTYPE effect_impl_Initialize(ID2D1EffectImpl *iface, { struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl(iface); ID2D1EffectContext_AddRef(effect_impl->effect_context = context); + ID2D1TransformGraph_AddRef(effect_impl->transform_graph = graph); return S_OK; }
@@ -10724,6 +10729,7 @@ static HRESULT STDMETHODCALLTYPE effect_impl_create(IUnknown **effect_impl) object->refcount = 1; object->integer = 10; object->effect_context = NULL; + object->transform_graph = NULL;
*effect_impl = (IUnknown *)&object->ID2D1EffectImpl_iface; return S_OK; @@ -10771,6 +10777,21 @@ static HRESULT STDMETHODCALLTYPE effect_impl_get_context(const IUnknown *iface, return S_OK; }
+static HRESULT STDMETHODCALLTYPE effect_impl_get_graph(const IUnknown *iface, + BYTE *data, UINT32 data_size, UINT32 *actual_size) +{ + struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl((ID2D1EffectImpl *)iface); + + if (!data) + return E_INVALIDARG; + + *((ID2D1TransformGraph **)data) = effect_impl->transform_graph; + if (actual_size) + *actual_size = sizeof(effect_impl->transform_graph); + + return S_OK; +} + static void test_effect_register(BOOL d3d11) { ID2D1DeviceContext *device_context; @@ -11400,7 +11421,7 @@ static void test_effect_properties(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
count = ID2D1Effect_GetPropertyCount(effect); - ok(count == 2, "Got unexpected property count %u.\n", count); + ok(count == 3, "Got unexpected property count %u.\n", count);
index = ID2D1Effect_GetPropertyIndex(effect, L"Context"); ok(index == 0, "Got unexpected index %u.\n", index); @@ -11997,6 +12018,125 @@ static void test_registered_effects(BOOL d3d11) release_test_context(&ctx); }
+static void test_transform_graph(BOOL d3d11) +{ + ID2D1OffsetTransform *offset_transform = NULL; + ID2D1BlendTransform *blend_transform = NULL; + D2D1_BLEND_DESCRIPTION blend_desc = {0}; + ID2D1EffectContext *effect_context; + struct d2d1_test_context ctx; + ID2D1TransformGraph *graph; + ID2D1Factory1 *factory; + POINT point = {0 ,0}; + ID2D1Effect *effect; + UINT i, count; + HRESULT hr; + + const D2D1_PROPERTY_BINDING binding[] = + { + {L"Context", NULL, effect_impl_get_context}, + {L"Graph", NULL, effect_impl_get_graph}, + }; + + if (!init_test_context(&ctx, d3d11)) + return; + + factory = ctx.factory1; + if (!factory) + { + win_skip("ID2D1Factory1 is not supported.\n"); + release_test_context(&ctx); + return; + } + + hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, + effect_xml_c, binding, ARRAY_SIZE(binding), effect_impl_create); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1DeviceContext_CreateEffect(ctx.context, &CLSID_TestEffect, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1Effect_GetValueByName(effect, L"Graph", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&graph, sizeof(graph)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_GetValueByName(effect, L"Context", + D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Create transforms */ + hr = ID2D1EffectContext_CreateOffsetTransform(effect_context, point, &offset_transform); + todo_wine 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; + + /* Add nodes */ + hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)blend_transform); + 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); + hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)blend_transform); + 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); + 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); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_ConnectNode(graph, + (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, 0); + 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); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_ConnectNode(graph, + (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, 0); + 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); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)blend_transform); + 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); + 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); + 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); + ID2D1Effect_Release(effect); + hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + release_test_context(&ctx); +} + static void test_stroke_contains_point(BOOL d3d11) { ID2D1TransformedGeometry *transformed_geometry; @@ -12812,6 +12952,7 @@ START_TEST(d2d1) queue_test(test_effect_crop); queue_test(test_effect_grayscale); queue_test(test_registered_effects); + queue_test(test_transform_graph); queue_d3d10_test(test_stroke_contains_point); queue_test(test_image_bounds); queue_test(test_bitmap_map);
From: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 68 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 5be8cdb707d..ea056ac017b 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12137,6 +12137,73 @@ done: release_test_context(&ctx); }
+static void test_offset_transform(BOOL d3d11) +{ + ID2D1OffsetTransform *transform = NULL; + ID2D1EffectContext *effect_context; + D2D1_PROPERTY_BINDING binding; + struct d2d1_test_context ctx; + ID2D1Factory1 *factory; + D2D1_POINT_2L offset; + ID2D1Effect *effect; + UINT input_count; + HRESULT hr; + + if (!init_test_context(&ctx, d3d11)) + return; + + factory = ctx.factory1; + if (!factory) + { + win_skip("ID2D1Factory1 is not supported.\n"); + release_test_context(&ctx); + return; + } + + binding.propertyName = L"Context"; + binding.setFunction = NULL; + binding.getFunction = effect_impl_get_context; + hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, + effect_xml_b, &binding, 1, effect_impl_create); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1DeviceContext_CreateEffect(ctx.context, &CLSID_TestEffect, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1Effect_GetValueByName(effect, L"Context", + D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Create transform */ + 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; + offset = ID2D1OffsetTransform_GetOffset(transform); + ok(offset.x == 1 && offset.y == 2, "Got unexpected offset {%ld, %ld}.\n", offset.x, offset.y); + + /* Input count */ + input_count = ID2D1OffsetTransform_GetInputCount(transform); + ok(input_count == 1, "Got unexpected input count %u.\n", input_count); + + /* Set offset */ + offset.x = -10; + offset.y = 20; + ID2D1OffsetTransform_SetOffset(transform, offset); + 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); + ID2D1Effect_Release(effect); + hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + release_test_context(&ctx); +} + static void test_stroke_contains_point(BOOL d3d11) { ID2D1TransformedGeometry *transformed_geometry; @@ -12953,6 +13020,7 @@ START_TEST(d2d1) queue_test(test_effect_grayscale); queue_test(test_registered_effects); queue_test(test_transform_graph); + queue_test(test_offset_transform); queue_d3d10_test(test_stroke_contains_point); queue_test(test_image_bounds); queue_test(test_bitmap_map);
From: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/d2d1_private.h | 7 +++ dlls/d2d1/effect.c | 95 +++++++++++++++++++++++++++++++++++++++- dlls/d2d1/tests/d2d1.c | 14 +++--- 3 files changed, 105 insertions(+), 11 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 98f99744746..e554a906855 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -658,6 +658,13 @@ struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory void d2d_factory_register_effect(struct d2d_factory *factory, struct d2d_effect_registration *effect) DECLSPEC_HIDDEN;
+struct d2d_transform +{ + ID2D1OffsetTransform ID2D1OffsetTransform_iface; + LONG refcount; + D2D1_POINT_2L offset; +}; + struct d2d_transform_graph { ID2D1TransformGraph ID2D1TransformGraph_iface; diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 7b086e20b9b..821c537b313 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -20,6 +20,87 @@
WINE_DEFAULT_DEBUG_CHANNEL(d2d);
+static inline struct d2d_transform *impl_from_ID2D1OffsetTransform(ID2D1OffsetTransform *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_transform, ID2D1OffsetTransform_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)) + { + ID2D1OffsetTransform_AddRef(iface); + *out = iface; + return S_OK; + } + + *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 *ret) +{ + struct d2d_transform *transform = impl_from_ID2D1OffsetTransform(iface); + + TRACE("iface %p, ret %p.\n", iface, ret); + + *ret = transform->offset; + return ret; +} + +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 inline struct d2d_transform_graph *impl_from_ID2D1TransformGraph(ID2D1TransformGraph *iface) { return CONTAINING_RECORD(iface, struct d2d_transform_graph, ID2D1TransformGraph_iface); @@ -754,9 +835,19 @@ 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); + struct d2d_transform *object;
- return E_NOTIMPL; + TRACE("iface %p, offset %s, transform %p.\n", iface, debug_d2d_point_2l(&offset), transform); + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1OffsetTransform_iface.lpVtbl = &d2d_offset_transform_vtbl; + object->refcount = 1; + object->offset = offset; + *transform = &object->ID2D1OffsetTransform_iface; + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateBoundsAdjustmentTransform(ID2D1EffectContext *iface, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index ea056ac017b..06b5ef94546 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12064,10 +12064,10 @@ 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) + if (!blend_transform) goto done;
/* Add nodes */ @@ -12139,8 +12139,8 @@ done:
static void test_offset_transform(BOOL d3d11) { - ID2D1OffsetTransform *transform = NULL; ID2D1EffectContext *effect_context; + ID2D1OffsetTransform *transform; D2D1_PROPERTY_BINDING binding; struct d2d1_test_context ctx; ID2D1Factory1 *factory; @@ -12178,9 +12178,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);
@@ -12195,9 +12193,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: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 125 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 06b5ef94546..9d9224ca473 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12200,6 +12200,130 @@ static void test_offset_transform(BOOL d3d11) release_test_context(&ctx); }
+#define check_blend_desc(blend_desc, expected) check_blend_desc_(__LINE__, blend_desc, expected) +static void check_blend_desc_(unsigned int line, + const D2D1_BLEND_DESCRIPTION *blend_desc, const D2D1_BLEND_DESCRIPTION *expected) +{ + ok_(__FILE__, line)(blend_desc->sourceBlend == expected->sourceBlend, + "Got unexpected source blend %u, expected %u.\n", + blend_desc->sourceBlend, expected->sourceBlend); + ok_(__FILE__, line)(blend_desc->destinationBlend == expected->destinationBlend, + "Got unexpected destination blend %u, expected %u.\n", + blend_desc->destinationBlend, expected->destinationBlend); + ok_(__FILE__, line)(blend_desc->blendOperation == expected->blendOperation, + "Got unexpected blend operation %u, expected %u.\n", + blend_desc->blendOperation, expected->blendOperation); + ok_(__FILE__, line)(blend_desc->sourceBlendAlpha == expected->sourceBlendAlpha, + "Got unexpected source blend alpha %u, expected %u.\n", + blend_desc->sourceBlendAlpha, expected->sourceBlendAlpha); + ok_(__FILE__, line)(blend_desc->destinationBlendAlpha == expected->destinationBlendAlpha, + "Got unexpected destination blend alpha %u, expected %u.\n", + blend_desc->destinationBlendAlpha, expected->destinationBlendAlpha); + ok_(__FILE__, line)(blend_desc->blendOperationAlpha == expected->blendOperationAlpha, + "Got unexpected blend operation alpha %u, expected %u.\n", + blend_desc->blendOperationAlpha, expected->blendOperationAlpha); + ok_(__FILE__, line)(blend_desc->blendFactor[0] == expected->blendFactor[0], + "Got unexpected blendFactor[0] %.8e, expected %.8e.\n", + blend_desc->blendFactor[0], expected->blendFactor[0]); + ok_(__FILE__, line)(blend_desc->blendFactor[1] == expected->blendFactor[1], + "Got unexpected blendFactor[1] %.8e, expected %.8e.\n", + blend_desc->blendFactor[1], expected->blendFactor[1]); + ok_(__FILE__, line)(blend_desc->blendFactor[2] == expected->blendFactor[2], + "Got unexpected blendFactor[2] %.8e, expected %.8e.\n", + blend_desc->blendFactor[2], expected->blendFactor[2]); + ok_(__FILE__, line)(blend_desc->blendFactor[3] == expected->blendFactor[3], + "Got unexpected blendFactor[3] %.8e, expected %.8e.\n", + blend_desc->blendFactor[3], expected->blendFactor[3]); +} + +static void test_blend_transform(BOOL d3d11) +{ + D2D1_BLEND_DESCRIPTION blend_desc, expected= {0}; + ID2D1BlendTransform *transform = NULL; + ID2D1EffectContext *effect_context; + D2D1_PROPERTY_BINDING binding; + struct d2d1_test_context ctx; + ID2D1Factory1 *factory; + ID2D1Effect *effect; + UINT input_count; + HRESULT hr; + + if (!init_test_context(&ctx, d3d11)) + return; + + factory = ctx.factory1; + if (!factory) + { + win_skip("ID2D1Factory1 is not supported.\n"); + release_test_context(&ctx); + return; + } + + binding.propertyName = L"Context"; + binding.setFunction = NULL; + binding.getFunction = effect_impl_get_context; + hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, + effect_xml_b, &binding, 1, effect_impl_create); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1DeviceContext_CreateEffect(ctx.context, &CLSID_TestEffect, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1Effect_GetValueByName(effect, L"Context", + D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Create transform */ + hr = ID2D1EffectContext_CreateBlendTransform(effect_context, 0, &expected, &transform); + todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + 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; + ID2D1BlendTransform_Release(transform); + hr = ID2D1EffectContext_CreateBlendTransform(effect_context, 4, &expected, &transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Get description */ + ID2D1BlendTransform_GetDescription(transform, &blend_desc); + check_blend_desc(&blend_desc, &expected); + + /* Input count */ + input_count = ID2D1BlendTransform_GetInputCount(transform); + ok(input_count == 4, "Got unexpected input count %u.\n", input_count); + + /* Set output buffer */ + hr = ID2D1BlendTransform_SetOutputBuffer(transform, 0xdeadbeef, D2D1_CHANNEL_DEPTH_DEFAULT); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1BlendTransform_SetOutputBuffer(transform, D2D1_BUFFER_PRECISION_UNKNOWN, 0xdeadbeef); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1BlendTransform_SetOutputBuffer(transform, D2D1_BUFFER_PRECISION_UNKNOWN, D2D1_CHANNEL_DEPTH_DEFAULT); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Set description */ + expected.sourceBlend = D2D1_BLEND_ZERO; + expected.destinationBlend = D2D1_BLEND_ZERO; + expected.blendOperation = D2D1_BLEND_OPERATION_ADD; + expected.sourceBlendAlpha = 0xdeadbeef; + expected.destinationBlendAlpha = 0; + expected.blendOperationAlpha = 12345678; + expected.blendFactor[0] = 0.0f; + expected.blendFactor[1] = 0.0f; + expected.blendFactor[2] = 0.0f; + expected.blendFactor[3] = 0.0f; + ID2D1BlendTransform_SetDescription(transform, &expected); + ID2D1BlendTransform_GetDescription(transform, &blend_desc); + check_blend_desc(&blend_desc, &expected); + +done: + if (transform) + ID2D1BlendTransform_Release(transform); + ID2D1Effect_Release(effect); + hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + release_test_context(&ctx); +} + static void test_stroke_contains_point(BOOL d3d11) { ID2D1TransformedGeometry *transformed_geometry; @@ -13017,6 +13141,7 @@ START_TEST(d2d1) queue_test(test_registered_effects); queue_test(test_transform_graph); queue_test(test_offset_transform); + queue_test(test_blend_transform); queue_d3d10_test(test_stroke_contains_point); queue_test(test_image_bounds); queue_test(test_bitmap_map);
From: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 96 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 9d9224ca473..9fa222e207a 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12324,6 +12324,101 @@ done: release_test_context(&ctx); }
+static void test_border_transform(BOOL d3d11) +{ + ID2D1BorderTransform *transform = NULL; + ID2D1EffectContext *effect_context; + D2D1_PROPERTY_BINDING binding; + struct d2d1_test_context ctx; + ID2D1Factory1 *factory; + D2D1_EXTEND_MODE mode; + ID2D1Effect *effect; + UINT input_count; + HRESULT hr; + + if (!init_test_context(&ctx, d3d11)) + return; + + factory = ctx.factory1; + if (!factory) + { + win_skip("ID2D1Factory1 is not supported.\n"); + release_test_context(&ctx); + return; + } + + binding.propertyName = L"Context"; + binding.setFunction = NULL; + binding.getFunction = effect_impl_get_context; + hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, + effect_xml_b, &binding, 1, effect_impl_create); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1DeviceContext_CreateEffect(ctx.context, &CLSID_TestEffect, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1Effect_GetValueByName(effect, L"Context", + D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Create transform with invalid extend mode */ + hr = ID2D1EffectContext_CreateBorderTransform(effect_context, 0xdeadbeef, 0xdeadbeef, &transform); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (hr != S_OK) + goto done; + mode = ID2D1BorderTransform_GetExtendModeX(transform); + ok(mode == 0xdeadbeef, "Got unexpected extend mode %u.\n", mode); + mode = ID2D1BorderTransform_GetExtendModeY(transform); + ok(mode == 0xdeadbeef, "Got unexpected extend mode %u.\n", mode); + ID2D1BorderTransform_Release(transform); + + /* Create transform */ + hr = ID2D1EffectContext_CreateBorderTransform(effect_context, D2D1_EXTEND_MODE_CLAMP, D2D1_EXTEND_MODE_WRAP, &transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Get extend mode */ + mode = ID2D1BorderTransform_GetExtendModeX(transform); + ok(mode == D2D1_EXTEND_MODE_CLAMP, "Got unexpected extend mode %u.\n", mode); + mode = ID2D1BorderTransform_GetExtendModeY(transform); + ok(mode == D2D1_EXTEND_MODE_WRAP, "Got unexpected extend mode %u.\n", mode); + + /* Input count */ + input_count = ID2D1BorderTransform_GetInputCount(transform); + ok(input_count == 1, "Got unexpected input count %u.\n", input_count); + + /* Set output buffer */ + hr = ID2D1BorderTransform_SetOutputBuffer(transform, 0xdeadbeef, D2D1_CHANNEL_DEPTH_DEFAULT); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1BorderTransform_SetOutputBuffer(transform, D2D1_BUFFER_PRECISION_UNKNOWN, 0xdeadbeef); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1BorderTransform_SetOutputBuffer(transform, D2D1_BUFFER_PRECISION_UNKNOWN, D2D1_CHANNEL_DEPTH_DEFAULT); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Set extend mode */ + ID2D1BorderTransform_SetExtendModeX(transform, D2D1_EXTEND_MODE_MIRROR); + mode = ID2D1BorderTransform_GetExtendModeX(transform); + ok(mode == D2D1_EXTEND_MODE_MIRROR, "Got unexpected extend mode %u.\n", mode); + ID2D1BorderTransform_SetExtendModeY(transform, D2D1_EXTEND_MODE_CLAMP); + mode = ID2D1BorderTransform_GetExtendModeY(transform); + ok(mode == D2D1_EXTEND_MODE_CLAMP, "Got unexpected extend mode %u.\n", mode); + + /* Set extend mode with invalid value */ + ID2D1BorderTransform_SetExtendModeX(transform, 0xdeadbeef); + mode = ID2D1BorderTransform_GetExtendModeX(transform); + ok(mode == D2D1_EXTEND_MODE_MIRROR, "Got unexpected extend mode %u.\n", mode); + ID2D1BorderTransform_SetExtendModeY(transform, 0xdeadbeef); + mode = ID2D1BorderTransform_GetExtendModeY(transform); + ok(mode == D2D1_EXTEND_MODE_CLAMP, "Got unexpected extend mode %u.\n", mode); + +done: + if (transform) + ID2D1BorderTransform_Release(transform); + ID2D1Effect_Release(effect); + hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + release_test_context(&ctx); +} + static void test_stroke_contains_point(BOOL d3d11) { ID2D1TransformedGeometry *transformed_geometry; @@ -13142,6 +13237,7 @@ START_TEST(d2d1) queue_test(test_transform_graph); queue_test(test_offset_transform); queue_test(test_blend_transform); + queue_test(test_border_transform); queue_d3d10_test(test_stroke_contains_point); queue_test(test_image_bounds); queue_test(test_bitmap_map);
From: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/d2d1_private.h | 11 ++- dlls/d2d1/effect.c | 142 +++++++++++++++++++++++++++++++++++++-- dlls/d2d1/tests/d2d1.c | 57 +++++++--------- 3 files changed, 171 insertions(+), 39 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index e554a906855..8e193924cb3 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -661,8 +661,17 @@ void d2d_factory_register_effect(struct d2d_factory *factory, struct d2d_transform { ID2D1OffsetTransform ID2D1OffsetTransform_iface; + ID2D1BlendTransform ID2D1BlendTransform_iface; LONG refcount; - D2D1_POINT_2L offset; + UINT32 input_count; + BOOL is_cached; + D2D1_BUFFER_PRECISION precision; + D2D1_CHANNEL_DEPTH depth; + union + { + D2D1_POINT_2L offset; + D2D1_BLEND_DESCRIPTION blend_desc; + } u; };
struct d2d_transform_graph diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 821c537b313..c25aea7f42d 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -78,7 +78,7 @@ static void STDMETHODCALLTYPE d2d_offset_transform_SetOffset(ID2D1OffsetTransfor
TRACE("iface %p, offset %s.\n", iface, debug_d2d_point_2l(&offset));
- transform->offset = offset; + transform->u.offset = offset; }
static D2D1_POINT_2L *STDMETHODCALLTYPE d2d_offset_transform_GetOffset(ID2D1OffsetTransform *iface, D2D1_POINT_2L *ret) @@ -87,7 +87,7 @@ static D2D1_POINT_2L *STDMETHODCALLTYPE d2d_offset_transform_GetOffset(ID2D1Offs
TRACE("iface %p, ret %p.\n", iface, ret);
- *ret = transform->offset; + *ret = transform->u.offset; return ret; }
@@ -101,6 +101,124 @@ static const ID2D1OffsetTransformVtbl d2d_offset_transform_vtbl = d2d_offset_transform_GetOffset, };
+static inline struct d2d_transform *impl_from_ID2D1BlendTransform(ID2D1BlendTransform *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_transform, ID2D1BlendTransform_iface); +} + +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)) + { + ID2D1BlendTransform_AddRef(iface); + *out = iface; + return S_OK; + } + + *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) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + + TRACE("iface %p, precision %#x, depth %#x.\n", iface, precision, depth); + + if ((precision != D2D1_BUFFER_PRECISION_UNKNOWN + && precision != D2D1_BUFFER_PRECISION_8BPC_UNORM + && precision != D2D1_BUFFER_PRECISION_8BPC_UNORM_SRGB + && precision != D2D1_BUFFER_PRECISION_16BPC_UNORM + && precision != D2D1_BUFFER_PRECISION_16BPC_FLOAT + && precision != D2D1_BUFFER_PRECISION_32BPC_FLOAT) + || (depth != D2D1_CHANNEL_DEPTH_DEFAULT && depth != D2D1_CHANNEL_DEPTH_1 && depth != D2D1_CHANNEL_DEPTH_4)) + return E_INVALIDARG; + + transform->precision = precision; + transform->depth = depth; + + return S_OK; +} + +static void STDMETHODCALLTYPE d2d_blend_transform_SetCached(ID2D1BlendTransform *iface, BOOL is_cached) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + + TRACE("iface %p, is_cached %d.\n", iface, is_cached); + + transform->is_cached = is_cached; +} + +static void STDMETHODCALLTYPE d2d_blend_transform_SetDescription(ID2D1BlendTransform *iface, + const D2D1_BLEND_DESCRIPTION *desc) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + transform->u.blend_desc = *desc; +} + +static void STDMETHODCALLTYPE d2d_blend_transform_GetDescription(ID2D1BlendTransform *iface, + D2D1_BLEND_DESCRIPTION *desc) +{ + struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = transform->u.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 inline struct d2d_transform_graph *impl_from_ID2D1TransformGraph(ID2D1TransformGraph *iface) { return CONTAINING_RECORD(iface, struct d2d_transform_graph, ID2D1TransformGraph_iface); @@ -819,9 +937,23 @@ 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); + struct d2d_transform *object;
- return E_NOTIMPL; + TRACE("iface %p, num_inputs %u, description %p, transform %p.\n", iface, num_inputs, description, transform); + + if (!num_inputs) + return E_INVALIDARG; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1BlendTransform_iface.lpVtbl = &d2d_blend_transform_vtbl; + object->refcount = 1; + object->input_count = num_inputs; + object->u.blend_desc = *description; + *transform = &object->ID2D1BlendTransform_iface; + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateBorderTransform(ID2D1EffectContext *iface, @@ -844,7 +976,7 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateOffsetTransform(ID2D1E
object->ID2D1OffsetTransform_iface.lpVtbl = &d2d_offset_transform_vtbl; object->refcount = 1; - object->offset = offset; + object->u.offset = offset; *transform = &object->ID2D1OffsetTransform_iface;
return S_OK; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 9fa222e207a..5b7148a47bb 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12020,9 +12020,9 @@ static void test_registered_effects(BOOL d3d11)
static void test_transform_graph(BOOL d3d11) { - ID2D1OffsetTransform *offset_transform = NULL; - ID2D1BlendTransform *blend_transform = NULL; D2D1_BLEND_DESCRIPTION blend_desc = {0}; + ID2D1OffsetTransform *offset_transform; + ID2D1BlendTransform *blend_transform; ID2D1EffectContext *effect_context; struct d2d1_test_context ctx; ID2D1TransformGraph *graph; @@ -12066,71 +12066,66 @@ 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 (!blend_transform) - goto done; + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* Add nodes */ hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); - ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)blend_transform); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + todo_wine 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); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)offset_transform); - ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)blend_transform); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + 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); - ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); + 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); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_ConnectNode(graph, (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, 0); - ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); + 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); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_ConnectNode(graph, (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, 0); - ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); + 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); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)blend_transform); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + 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); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + 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); - ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + 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); @@ -12239,8 +12234,8 @@ static void check_blend_desc_(unsigned int line, static void test_blend_transform(BOOL d3d11) { D2D1_BLEND_DESCRIPTION blend_desc, expected= {0}; - ID2D1BlendTransform *transform = NULL; ID2D1EffectContext *effect_context; + ID2D1BlendTransform *transform; D2D1_PROPERTY_BINDING binding; struct d2d1_test_context ctx; ID2D1Factory1 *factory; @@ -12275,11 +12270,9 @@ static void test_blend_transform(BOOL d3d11)
/* Create transform */ 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); 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); @@ -12315,9 +12308,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);
v2��� * Remove D2D_ERR_NOT_FOUND. * Use one struct for all transforms: d2d_transform. * Add more tests. * Implement ID2D1BlendTransform.
Nikolay Sivov (@nsivov) commented about dlls/d2d1/d2d1_private.h:
void d2d_factory_register_effect(struct d2d_factory *factory, struct d2d_effect_registration *effect) DECLSPEC_HIDDEN;
+struct d2d_transform +{
- ID2D1OffsetTransform ID2D1OffsetTransform_iface;
- ID2D1BlendTransform ID2D1BlendTransform_iface;
I was thinking doing it similar to "struct d2d_brush", but down to transform node. But then again, before the graph is implemented, it's not clear what is the best way. I think we should start small with e.g. offset transform, and make it work to see which direction to take.
Nikolay Sivov (@nsivov) commented about dlls/d2d1/effect.c:
- return transform->input_count;
+}
+static HRESULT STDMETHODCALLTYPE d2d_blend_transform_SetOutputBuffer(ID2D1BlendTransform *iface,
D2D1_BUFFER_PRECISION precision, D2D1_CHANNEL_DEPTH depth)
+{
- struct d2d_transform *transform = impl_from_ID2D1BlendTransform(iface);
- TRACE("iface %p, precision %#x, depth %#x.\n", iface, precision, depth);
- if ((precision != D2D1_BUFFER_PRECISION_UNKNOWN
&& precision != D2D1_BUFFER_PRECISION_8BPC_UNORM
&& precision != D2D1_BUFFER_PRECISION_8BPC_UNORM_SRGB
&& precision != D2D1_BUFFER_PRECISION_16BPC_UNORM
&& precision != D2D1_BUFFER_PRECISION_16BPC_FLOAT
&& precision != D2D1_BUFFER_PRECISION_32BPC_FLOAT)
These values are sequential, you could just check if it's within valid range.
On Tue Jul 12 10:10:21 2022 +0000, Nikolay Sivov wrote:
I was thinking doing it similar to "struct d2d_brush", but down to transform node. But then again, before the graph is implemented, it's not clear what is the best way. I think we should start small with e.g. offset transform, and make it work to see which direction to take.
If I want the current patches get upstreamed, should I remove the last blend transform patch for now, and reserve the offset transform?