Commit 1707550d authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

d2d1/effect: Implement blend transform object.

parent 5908d7fa
......@@ -716,7 +716,10 @@ struct d2d_transform
union
{
D2D1_POINT_2L offset;
D2D1_BLEND_DESCRIPTION blend_desc;
};
UINT32 input_count;
};
struct d2d_transform_graph
......
......@@ -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,
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment