From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 334e9f1adea..fed0e9bdf96 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10934,7 +10934,11 @@ static void test_effect_register(BOOL d3d11) hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, test->effect_xml, test->binding, test->binding_count, effect_impl_create); ok(hr == test->hr, "Got unexpected hr %#lx, expected %#lx.\n", hr, test->hr); - ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); + if (SUCCEEDED(hr)) + { + hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + }
winetest_pop_context(); }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/factory.c | 3 ++- dlls/d2d1/tests/d2d1.c | 1 - 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 699b8c05669..0a8a3bbd5b1 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -921,7 +921,8 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Facto if (!parse_effect_get_property(effect, L"DisplayName") || !parse_effect_get_property(effect, L"Author") || !parse_effect_get_property(effect, L"Category") - || !parse_effect_get_property(effect, L"Description")) + || !parse_effect_get_property(effect, L"Description") + || !parse_effect_get_property(effect, L"Inputs")) { WARN("Missing required properties.\n"); d2d_effect_registration_cleanup(effect); diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index fed0e9bdf96..05ebf10e666 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10855,7 +10855,6 @@ static void test_effect_register(BOOL d3d11) winetest_push_context("Test %u", i);
hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, test->xml, NULL, 0, effect_impl_create); - todo_wine_if(i == 5) ok(hr == test->hr, "Got unexpected hr %#lx, expected %#lx.\n", hr, test->hr); if (hr == S_OK) {
From: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/d2d1_private.h | 6 ++++ dlls/d2d1/effect.c | 76 ++++++++++++++++------------------------ dlls/d2d1/factory.c | 40 ++++++++++++++++++--- dlls/d2d1/tests/d2d1.c | 5 +++ 4 files changed, 78 insertions(+), 49 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index db6787c2f86..98f99744746 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -643,14 +643,20 @@ struct d2d_effect_registration struct list entry; PD2D1_EFFECT_FACTORY factory; UINT32 registration_count; + BOOL builtin; CLSID id;
UINT32 input_count; + UINT32 default_input_count; struct d2d_effect_properties properties; };
+struct d2d_factory; +void d2d_effects_init_builtins(struct d2d_factory *factory) DECLSPEC_HIDDEN; struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory *factory, const GUID *effect_id) DECLSPEC_HIDDEN; +void d2d_factory_register_effect(struct d2d_factory *factory, + struct d2d_effect_registration *effect) DECLSPEC_HIDDEN;
struct d2d_transform_graph { diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 640aab15817..7b086e20b9b 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -229,6 +229,33 @@ static const struct d2d_effect_info builtin_effects[] = {&CLSID_D2D1Grayscale, 1, 1, 1}, };
+void d2d_effects_init_builtins(struct d2d_factory *factory) +{ + struct d2d_effect_registration *effect; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(builtin_effects); ++i) + { + const struct d2d_effect_info *info = &builtin_effects[i]; + WCHAR max_inputs[32]; + + if (!(effect = calloc(1, sizeof(*effect)))) + return; + + swprintf(max_inputs, ARRAY_SIZE(max_inputs), L"%lu", info->max_inputs); + d2d_effect_properties_add(&effect->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS, + D2D1_PROPERTY_TYPE_UINT32, L"1"); + d2d_effect_properties_add(&effect->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, + D2D1_PROPERTY_TYPE_UINT32, max_inputs); + + memcpy(&effect->id, info->clsid, sizeof(*info->clsid)); + effect->default_input_count = info->default_input_count; + effect->factory = builtin_factory_stub; + effect->builtin = TRUE; + d2d_factory_register_effect(factory, effect); + } +} + /* Same syntax is used for value and default values. */ static HRESULT d2d_effect_parse_float_array(D2D1_PROPERTY_TYPE type, const WCHAR *value, float *vec) @@ -1539,31 +1566,14 @@ static void d2d_effect_init_properties_vtbls(struct d2d_effect *effect) HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effect_id, ID2D1Effect **effect) { - const struct d2d_effect_info *builtin = NULL; struct d2d_effect_context *effect_context; const struct d2d_effect_registration *reg; - unsigned int i, default_input_count; struct d2d_transform_graph *graph; - PD2D1_EFFECT_FACTORY factory; struct d2d_effect *object; WCHAR clsidW[39]; HRESULT hr;
if (!(reg = d2d_factory_get_registered_effect(context->factory, effect_id))) - { - for (i = 0; i < ARRAY_SIZE(builtin_effects); ++i) - { - const struct d2d_effect_info *info = &builtin_effects[i]; - - if (IsEqualGUID(effect_id, info->clsid)) - { - builtin = info; - break; - } - } - } - - if (!reg && !builtin) { WARN("Effect id %s not found.\n", wine_dbgstr_guid(effect_id)); return D2DERR_EFFECT_IS_NOT_REGISTERED; @@ -1594,41 +1604,17 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec object->graph = graph;
/* Create properties */ - StringFromGUID2(effect_id, clsidW, ARRAY_SIZE(clsidW)); - if (builtin) - { - WCHAR max_inputs[32]; - swprintf(max_inputs, ARRAY_SIZE(max_inputs), L"%lu", builtin->max_inputs); - d2d_effect_properties_add(&object->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS, - D2D1_PROPERTY_TYPE_UINT32, L"1"); - d2d_effect_properties_add(&object->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, - D2D1_PROPERTY_TYPE_UINT32, max_inputs); - - default_input_count = builtin->default_input_count; - - factory = builtin_factory_stub; - } - else - { - d2d_effect_duplicate_properties(&object->properties, ®->properties); - d2d_effect_properties_add(&object->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS, - D2D1_PROPERTY_TYPE_UINT32, L"1"); - d2d_effect_properties_add(&object->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, - D2D1_PROPERTY_TYPE_UINT32, L"1" /* FIXME */); - - default_input_count = 1; - - factory = reg->factory; - } + d2d_effect_duplicate_properties(&object->properties, ®->properties);
+ StringFromGUID2(effect_id, clsidW, ARRAY_SIZE(clsidW)); d2d_effect_properties_add(&object->properties, L"CLSID", D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_CLSID, clsidW); d2d_effect_properties_add(&object->properties, L"Cached", D2D1_PROPERTY_CACHED, D2D1_PROPERTY_TYPE_BOOL, L"false"); d2d_effect_properties_add(&object->properties, L"Precision", D2D1_PROPERTY_PRECISION, D2D1_PROPERTY_TYPE_ENUM, L"0"); d2d_effect_init_properties_vtbls(object);
- d2d_effect_SetInputCount(&object->ID2D1Effect_iface, default_input_count); + d2d_effect_SetInputCount(&object->ID2D1Effect_iface, reg->default_input_count);
- if (FAILED(hr = factory((IUnknown **)&object->impl))) + if (FAILED(hr = reg->factory((IUnknown **)&object->impl))) { WARN("Failed to create implementation object, hr %#lx.\n", hr); ID2D1Effect_Release(&object->ID2D1Effect_iface); diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 0a8a3bbd5b1..856af97cd43 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -48,6 +48,7 @@ struct d2d_factory float dpi_y;
struct list effects; + INIT_ONCE init_builtins;
CRITICAL_SECTION cs; }; @@ -67,12 +68,31 @@ static inline struct d2d_factory *impl_from_ID2D1Multithread(ID2D1Multithread *i return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Multithread_iface); }
+static BOOL WINAPI d2d_factory_builtins_initonce(INIT_ONCE *once, void *param, void **context) +{ + d2d_effects_init_builtins(param); + + return TRUE; +} + +static void d2d_factory_init_builtin_effects(struct d2d_factory *factory) +{ + InitOnceExecuteOnce(&factory->init_builtins, d2d_factory_builtins_initonce, factory, NULL); +} + +void d2d_factory_register_effect(struct d2d_factory *factory, struct d2d_effect_registration *effect) +{ + list_add_tail(&factory->effects, &effect->entry); +} + struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory *iface, const GUID *id) { - const struct d2d_factory *factory = unsafe_impl_from_ID2D1Factory(iface); + struct d2d_factory *factory = unsafe_impl_from_ID2D1Factory(iface); struct d2d_effect_registration *reg;
+ d2d_effects_init_builtins(factory); + LIST_FOR_EACH_ENTRY(reg, &factory->effects, struct d2d_effect_registration, entry) { if (IsEqualGUID(id, ®->id)) return reg; @@ -884,10 +904,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Facto TRACE("iface %p, effect_id %s, property_xml %p, bindings %p, binding_count %u, effect_factory %p.\n", iface, debugstr_guid(effect_id), property_xml, bindings, binding_count, effect_factory);
- LIST_FOR_EACH_ENTRY(effect, &factory->effects, struct d2d_effect_registration, entry) + d2d_factory_init_builtin_effects(factory); + + LIST_FOR_EACH_ENTRY_REV(effect, &factory->effects, struct d2d_effect_registration, entry) { if (IsEqualGUID(effect_id, &effect->id)) { + if (effect->builtin) return E_INVALIDARG; ++effect->registration_count; return S_OK; } @@ -948,7 +971,12 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Facto effect->registration_count = 1; effect->id = *effect_id; effect->factory = effect_factory; - list_add_tail(&factory->effects, &effect->entry); + d2d_effect_properties_add(&effect->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS, + D2D1_PROPERTY_TYPE_UINT32, L"1"); + d2d_effect_properties_add(&effect->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, + D2D1_PROPERTY_TYPE_UINT32, L"1" /* FIXME */); + effect->default_input_count = 1; + d2d_factory_register_effect(factory, effect);
return S_OK; } @@ -987,10 +1015,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_UnregisterEffect(ID2D1Factory3 *ifa
TRACE("iface %p, effect_id %s.\n", iface, debugstr_guid(effect_id));
- LIST_FOR_EACH_ENTRY(effect, &factory->effects, struct d2d_effect_registration, entry) + d2d_factory_init_builtin_effects(factory); + + LIST_FOR_EACH_ENTRY_REV(effect, &factory->effects, struct d2d_effect_registration, entry) { if (IsEqualGUID(effect_id, &effect->id)) { + if (effect->builtin) break; if (!--effect->registration_count) { list_remove(&effect->entry); @@ -1156,6 +1187,7 @@ static void d2d_factory_init(struct d2d_factory *factory, D2D1_FACTORY_TYPE fact d2d_factory_reload_sysmetrics(factory); list_init(&factory->effects); InitializeCriticalSection(&factory->cs); + InitOnceInitialize(&factory->init_builtins); }
HRESULT WINAPI D2D1CreateFactory(D2D1_FACTORY_TYPE factory_type, REFIID iid, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 05ebf10e666..585016890a6 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10848,6 +10848,11 @@ static void test_effect_register(BOOL d3d11) return; }
+ /* Using builtin effect CLSID. */ + hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_D2D1Crop, effect_xml_a, NULL, + 0, effect_impl_create); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + /* Register effect once */ for (i = 0; i < ARRAY_SIZE(xml_tests); ++i) {
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/factory.c | 30 ++++++++++++++++++-- dlls/d2d1/tests/d2d1.c | 64 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 856af97cd43..a160d7071c2 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -1037,10 +1037,36 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_UnregisterEffect(ID2D1Factory3 *ifa static HRESULT STDMETHODCALLTYPE d2d_factory_GetRegisteredEffects(ID2D1Factory3 *iface, CLSID *effects, UINT32 effect_count, UINT32 *returned, UINT32 *registered) { - FIXME("iface %p, effects %p, effect_count %u, returned %p, registered %p stub!\n", + struct d2d_factory *factory = impl_from_ID2D1Factory3(iface); + struct d2d_effect_registration *effect; + UINT32 ret, reg; + + TRACE("iface %p, effects %p, effect_count %u, returned %p, registered %p.\n", iface, effects, effect_count, returned, registered);
- return E_NOTIMPL; + if (!returned) returned = &ret; + if (!registered) registered = ® + + *registered = 0; + *returned = 0; + + d2d_factory_init_builtin_effects(factory); + + LIST_FOR_EACH_ENTRY(effect, &factory->effects, struct d2d_effect_registration, entry) + { + if (effects && effect_count) + { + *effects = effect->id; + effects++; + effect_count--; + *returned += 1; + } + + *registered += 1; + } + + if (!effects) return S_OK; + return *returned == *registered ? S_OK : D2DERR_INSUFFICIENT_BUFFER; }
static HRESULT STDMETHODCALLTYPE d2d_factory_GetEffectProperties(ID2D1Factory3 *iface, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 585016890a6..335659c24b3 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -11935,6 +11935,69 @@ static void test_effect_grayscale(BOOL d3d11) release_test_context(&ctx); }
+static void test_registered_effects(BOOL d3d11) +{ + UINT32 ret, count, count2, count3; + struct d2d1_test_context ctx; + ID2D1Factory1 *factory; + CLSID *effects; + HRESULT hr; + + if (!init_test_context(&ctx, d3d11)) + return; + + factory = ctx.factory1; + + count = 0; + hr = ID2D1Factory1_GetRegisteredEffects(factory, NULL, 0, NULL, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count > 0, "Unexpected effect count %u.\n", count); + + hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, effect_xml_a, + NULL, 0, effect_impl_create); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + count2 = 0; + hr = ID2D1Factory1_GetRegisteredEffects(factory, NULL, 0, NULL, &count2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count2 == count + 1, "Unexpected effect count %u.\n", count2); + + effects = calloc(count2, sizeof(*effects)); + + count3 = 0; + hr = ID2D1Factory1_GetRegisteredEffects(factory, effects, 0, NULL, &count3); + ok(hr == D2DERR_INSUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr); + ok(count2 == count3, "Unexpected effect count %u.\n", count3); + + ret = 999; + hr = ID2D1Factory1_GetRegisteredEffects(factory, effects, 0, &ret, NULL); + ok(hr == D2DERR_INSUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr); + ok(!ret, "Unexpected count %u.\n", ret); + + ret = 0; + hr = ID2D1Factory1_GetRegisteredEffects(factory, effects, 1, &ret, NULL); + ok(hr == D2DERR_INSUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr); + ok(ret == 1, "Unexpected count %u.\n", ret); + ok(!IsEqualGUID(effects, &CLSID_TestEffect), "Unexpected clsid.\n"); + + ret = 0; + hr = ID2D1Factory1_GetRegisteredEffects(factory, effects, count2, &ret, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(ret == count2, "Unexpected count %u.\n", ret); + ok(IsEqualGUID(&effects[ret - 1], &CLSID_TestEffect), "Unexpected clsid.\n"); + + free(effects); + + ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); + + count2 = 0; + hr = ID2D1Factory1_GetRegisteredEffects(factory, NULL, 0, NULL, &count2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count2 == count, "Unexpected effect count %u.\n", count2); + + release_test_context(&ctx); +} + static void test_stroke_contains_point(BOOL d3d11) { ID2D1TransformedGeometry *transformed_geometry; @@ -12749,6 +12812,7 @@ START_TEST(d2d1) queue_test(test_effect_2d_affine); queue_test(test_effect_crop); queue_test(test_effect_grayscale); + queue_test(test_registered_effects); queue_d3d10_test(test_stroke_contains_point); queue_test(test_image_bounds); queue_test(test_bitmap_map);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 335659c24b3..1a964475168 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -28,7 +28,6 @@ #include "initguid.h" #include "dwrite.h" #include "wincodec.h" -#include "wine/heap.h"
DEFINE_GUID(CLSID_TestEffect, 0xb9ee12e9,0x32d9,0xe659,0xac,0x61,0x2d,0x7c,0xea,0x69,0x28,0x78); DEFINE_GUID(GUID_TestVertexShader, 0x5bcdcfae,0x1e92,0x4dc1,0x94,0xfa,0x3b,0x01,0xca,0x54,0x59,0x20); @@ -358,7 +357,7 @@ static void queue_d3d1x_test(void (*test)(BOOL d3d11), BOOL d3d11) if (mt_test_count >= mt_tests_size) { mt_tests_size = max(16, mt_tests_size * 2); - mt_tests = heap_realloc(mt_tests, mt_tests_size * sizeof(*mt_tests)); + mt_tests = realloc(mt_tests, mt_tests_size * sizeof(*mt_tests)); } mt_tests[mt_test_count].test = test; mt_tests[mt_test_count++].d3d11 = d3d11; @@ -408,7 +407,7 @@ static void run_queued_tests(void)
GetSystemInfo(&si); thread_count = si.dwNumberOfProcessors; - threads = heap_calloc(thread_count, sizeof(*threads)); + threads = calloc(thread_count, sizeof(*threads)); for (i = 0, test_idx = 0; i < thread_count; ++i) { threads[i] = CreateThread(NULL, 0, thread_func, &test_idx, 0, NULL); @@ -419,7 +418,7 @@ static void run_queued_tests(void) { CloseHandle(threads[i]); } - heap_free(threads); + free(threads); }
static void set_point(D2D1_POINT_2F *point, float x, float y) @@ -10680,7 +10679,7 @@ static ULONG STDMETHODCALLTYPE effect_impl_Release(ID2D1EffectImpl *iface) { if (effect_impl->effect_context) ID2D1EffectContext_Release(effect_impl->effect_context); - heap_free(effect_impl); + free(effect_impl); }
return refcount; @@ -10718,7 +10717,7 @@ static HRESULT STDMETHODCALLTYPE effect_impl_create(IUnknown **effect_impl) { struct effect_impl *object;
- if (!(object = heap_alloc(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
object->ID2D1EffectImpl_iface.lpVtbl = &effect_impl_vtbl;