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);