[PATCH v3 resend] d2d1/tests: Add tests for effect register.
Ziqing Hui
zhui at codeweavers.com
Sun May 22 22:44:21 CDT 2022
Signed-off-by: Ziqing Hui <zhui at codeweavers.com>
---
This patch is resend to see the its result on test bot.
dlls/d2d1/tests/d2d1.c | 301 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 301 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 663fc150df8..0a8245d6805 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -21,6 +21,7 @@
#include <math.h>
#include <float.h>
#include "d2d1_3.h"
+#include "d2d1effectauthor.h"
#include "d3d11.h"
#include "wincrypt.h"
#include "wine/test.h"
@@ -29,6 +30,62 @@
#include "wincodec.h"
#include "wine/heap.h"
+DEFINE_GUID(CLSID_TestEffect, 0xb9ee12e9,0x32d9,0xe659,0xac,0x61,0x2d,0x7c,0xea,0x69,0x28,0x78);
+
+static const WCHAR *effect_xml_a =
+L"<?xml version='1.0'?> \
+ <Effect> \
+ <Property name='DisplayName' type='string' value='TestEffect'/> \
+ <Property name='Author' type='string' value='The Wine Project'/> \
+ <Property name='Category' type='string' value='Test'/> \
+ <Property name='Description' type='string' value='Test effect.'/> \
+ <Inputs> \
+ <Input name='Source'/> \
+ </Inputs> \
+ <Property name='Integer' type='uint32'> \
+ <Property name='DisplayName' type='string' value='Integer'/> \
+ <Property name='Min' type='uint32' value='0'/> \
+ <Property name='Max' type='uint32' value='100'/> \
+ <Property name='Default' type='uint32' value='10'/> \
+ </Property> \
+ </Effect> \
+";
+
+static const WCHAR *effect_xml_b =
+L"<?xml version='1.0'?> \
+ <Effect> \
+ <Property name='DisplayName' type='string' value='TestEffect'/> \
+ <Property name='Author' type='string' value='The Wine Project'/> \
+ <Property name='Category' type='string' value='Test'/> \
+ <Property name='Description' type='string' value='Test effect.'/> \
+ <Inputs> \
+ <Input name='Source'/> \
+ </Inputs> \
+ <Property name='Context' type='iunknown'> \
+ <Property name='DisplayName' type='string' value='Context'/> \
+ </Property> \
+ </Effect> \
+";
+
+static const WCHAR *effect_xml_c =
+L"<?xml version='1.0'?> \
+ <Effect> \
+ <Property name='DisplayName' type='string' value='TestEffect'/> \
+ <Property name='Author' type='string' value='The Wine Project'/> \
+ <Property name='Category' type='string' value='Test'/> \
+ <Property name='Description' type='string' value='Test effect.'/> \
+ <Inputs> \
+ <Input name='Source'/> \
+ </Inputs> \
+ <Property name='Context' type='iunknown'> \
+ <Property name='DisplayName' type='string' value='Context'/> \
+ </Property> \
+ <Property name='Integer' type='uint32'> \
+ <Property name='DisplayName' type='string' value='Integer'/> \
+ </Property> \
+ </Effect> \
+";
+
static HRESULT (WINAPI *pD2D1CreateDevice)(IDXGIDevice *dxgi_device,
const D2D1_CREATION_PROPERTIES *properties, ID2D1Device **device);
static void (WINAPI *pD2D1SinCos)(float angle, float *s, float *c);
@@ -118,6 +175,14 @@ struct expected_geometry_figure
const struct geometry_segment *segments;
};
+struct effect_impl
+{
+ ID2D1EffectImpl ID2D1EffectImpl_iface;
+ LONG refcount;
+ UINT integer;
+ ID2D1EffectContext *effect_context;
+};
+
static void queue_d3d1x_test(void (*test)(BOOL d3d11), BOOL d3d11)
{
if (mt_test_count >= mt_tests_size)
@@ -10296,6 +10361,241 @@ static void test_effect(BOOL d3d11)
release_test_context(&ctx);
}
+static inline struct effect_impl *impl_from_ID2D1EffectImpl(ID2D1EffectImpl *iface)
+{
+ return CONTAINING_RECORD(iface, struct effect_impl, ID2D1EffectImpl_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE effect_impl_QueryInterface(ID2D1EffectImpl *iface, REFIID iid, void **out)
+{
+ if (IsEqualGUID(iid, &IID_ID2D1EffectImpl)
+ || IsEqualGUID(iid, &IID_IUnknown))
+ {
+ ID2D1EffectImpl_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE effect_impl_AddRef(ID2D1EffectImpl *iface)
+{
+ struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl(iface);
+ ULONG refcount = InterlockedIncrement(&effect_impl->refcount);
+ return refcount;
+}
+
+static ULONG STDMETHODCALLTYPE effect_impl_Release(ID2D1EffectImpl *iface)
+{
+ struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl(iface);
+ ULONG refcount = InterlockedDecrement(&effect_impl->refcount);
+
+ if (!refcount)
+ {
+ if (effect_impl->effect_context)
+ ID2D1EffectContext_Release(effect_impl->effect_context);
+ heap_free(effect_impl);
+ }
+
+ return refcount;
+}
+
+static HRESULT STDMETHODCALLTYPE effect_impl_Initialize(ID2D1EffectImpl *iface,
+ ID2D1EffectContext *context,ID2D1TransformGraph *graph)
+{
+ struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl(iface);
+ ID2D1EffectContext_AddRef(effect_impl->effect_context = context);
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE effect_impl_PrepareForRender(ID2D1EffectImpl *iface, D2D1_CHANGE_TYPE type)
+{
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE effect_impl_SetGraph(ID2D1EffectImpl *iface, ID2D1TransformGraph *graph)
+{
+ return E_NOTIMPL;
+}
+
+static const ID2D1EffectImplVtbl effect_impl_vtbl =
+{
+ effect_impl_QueryInterface,
+ effect_impl_AddRef,
+ effect_impl_Release,
+ effect_impl_Initialize,
+ effect_impl_PrepareForRender,
+ effect_impl_SetGraph,
+};
+
+static HRESULT STDMETHODCALLTYPE effect_impl_create(IUnknown **effect_impl)
+{
+ struct effect_impl *object;
+
+ if (!(object = heap_alloc(sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ object->ID2D1EffectImpl_iface.lpVtbl = &effect_impl_vtbl;
+ object->refcount = 1;
+ object->integer = 0;
+ object->effect_context = NULL;
+
+ *effect_impl = (IUnknown *)&object->ID2D1EffectImpl_iface;
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE effect_impl_set_integer(IUnknown *iface, const BYTE *data, UINT32 data_size)
+{
+ struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl((ID2D1EffectImpl *)iface);
+
+ if (!data || data_size != sizeof(effect_impl->integer))
+ return E_INVALIDARG;
+
+ effect_impl->integer = *((UINT *)data);
+
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE effect_impl_get_integer(const IUnknown *iface,
+ BYTE *data, UINT32 data_size, UINT32 *actual_size)
+{
+ struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl((ID2D1EffectImpl *)iface);
+
+ if (!data || data_size != sizeof(effect_impl->integer))
+ return E_INVALIDARG;
+
+ *((UINT *)data) = effect_impl->integer;
+ if (actual_size)
+ *actual_size = sizeof(effect_impl->integer);
+
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE effect_impl_get_context(const IUnknown *iface,
+ BYTE *data, UINT32 data_size, UINT32 *actual_size)
+{
+ struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl((ID2D1EffectImpl *)iface);
+
+ if (!data || data_size != sizeof(effect_impl->effect_context))
+ return E_INVALIDARG;
+
+ *((ID2D1EffectContext **)data) = effect_impl->effect_context;
+ if (actual_size)
+ *actual_size = sizeof(effect_impl->effect_context);
+
+ return S_OK;
+}
+
+static void test_effect_register(BOOL d3d11)
+{
+ struct d2d1_test_context ctx;
+ ID2D1Factory1 *factory;
+ unsigned int i;
+ HRESULT hr;
+
+ const D2D1_PROPERTY_BINDING binding[] =
+ {
+ {L"Integer", effect_impl_set_integer, effect_impl_get_integer},
+ {L"Context", NULL, effect_impl_get_context},
+ {L"Integer", NULL, effect_impl_get_integer},
+ {L"Integer", effect_impl_set_integer, NULL},
+ {L"Integer", NULL, NULL},
+ {L"DeadBeef", effect_impl_set_integer, effect_impl_get_integer},
+ };
+
+ const struct binding_test
+ {
+ const D2D1_PROPERTY_BINDING *binding;
+ UINT32 binding_count;
+ const WCHAR *effect_xml;
+ HRESULT hr;
+ }
+ binding_tests[] =
+ {
+ {NULL, 0, effect_xml_a, S_OK},
+ {NULL, 0, effect_xml_b, S_OK},
+ {binding, 1, effect_xml_a, S_OK},
+ {binding, 1, effect_xml_b, D2DERR_INVALID_PROPERTY},
+ {binding + 1, 1, effect_xml_b, S_OK},
+ {binding + 2, 1, effect_xml_a, S_OK},
+ {binding + 3, 1, effect_xml_a, S_OK},
+ {binding + 4, 1, effect_xml_a, S_OK},
+ {binding + 5, 1, effect_xml_a, D2DERR_INVALID_PROPERTY},
+ {binding, 2, effect_xml_a, D2DERR_INVALID_PROPERTY},
+ {binding, 2, effect_xml_b, D2DERR_INVALID_PROPERTY},
+ {binding, 2, effect_xml_c, S_OK},
+ };
+
+ if (!init_test_context(&ctx, d3d11))
+ return;
+
+ if (!(factory = create_factory(&IID_ID2D1Factory1, NULL)))
+ {
+ win_skip("ID2D1Factory1 is not supported.\n");
+ release_test_context(&ctx);
+ return;
+ }
+
+ /* Register effect once */
+ hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect,
+ effect_xml_a, NULL, 0, effect_impl_create);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
+ todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
+ todo_wine ok(hr == D2DERR_EFFECT_IS_NOT_REGISTERED, "Got unexpected hr %#lx.\n", hr);
+
+ /* Register effect multiple times */
+ hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect,
+ effect_xml_a, NULL, 0, effect_impl_create);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect,
+ effect_xml_a, NULL, 0, effect_impl_create);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
+ todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
+ todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
+ todo_wine ok(hr == D2DERR_EFFECT_IS_NOT_REGISTERED, "Got unexpected hr %#lx.\n", hr);
+
+ /* Register effect multiple times with different xml */
+ hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect,
+ effect_xml_a, NULL, 0, effect_impl_create);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect,
+ effect_xml_b, NULL, 0, effect_impl_create);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
+ todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
+ todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ /* Register effect with property binding */
+ for (i = 0; i < ARRAY_SIZE(binding_tests); ++i)
+ {
+ const struct binding_test *test = &binding_tests[i];
+ winetest_push_context("Test %u", i);
+
+ hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect,
+ test->effect_xml, test->binding, test->binding_count, effect_impl_create);
+ todo_wine_if(test->hr != S_OK)
+ ok(hr == test->hr, "Got unexpected hr %#lx, expected %#lx.\n", hr, test->hr);
+ ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
+
+ winetest_pop_context();
+ }
+
+ /* Unregister builtin effect */
+ hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_D2D1Composite);
+ todo_wine ok(hr == D2DERR_EFFECT_IS_NOT_REGISTERED, "Got unexpected hr %#lx.\n", hr);
+
+ ID2D1Factory1_Release(factory);
+ release_test_context(&ctx);
+}
+
static void test_effect_2d_affine(BOOL d3d11)
{
D2D1_MATRIX_3X2_F rotate, scale, skew;
@@ -11088,6 +11388,7 @@ START_TEST(d2d1)
queue_d3d10_test(test_colour_space);
queue_test(test_geometry_group);
queue_test(test_mt_factory);
+ queue_test(test_effect_register);
queue_test(test_effect);
queue_test(test_effect_2d_affine);
queue_test(test_effect_crop);
--
2.25.1
More information about the wine-devel
mailing list