Signed-off-by: Ziqing Hui zhui@codeweavers.com ---
PS: I'll submit v2 version of the patch set I sent yesterday after this patch set is approved.
dlls/d2d1/tests/d2d1.c | 77 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index f1cec1d7a0b..68d2716a118 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10310,19 +10310,21 @@ static void test_mt_factory(BOOL d3d11) ID2D1Factory_Release(factory); }
-static void test_effect(BOOL d3d11) +static void test_builtin_effect(BOOL d3d11) { - unsigned int i, j, min_inputs, max_inputs, str_size, input_count; + unsigned int i, j, min_inputs, max_inputs, str_size, input_count, value_size; D2D1_BITMAP_PROPERTIES bitmap_desc; D2D1_BUFFER_PRECISION precision; ID2D1Image *image_a, *image_b; struct d2d1_test_context ctx; ID2D1DeviceContext *context; + D2D1_PROPERTY_TYPE type; ID2D1Factory1 *factory; ID2D1Bitmap *bitmap; ID2D1Effect *effect; D2D1_SIZE_U size; BYTE buffer[256]; + WCHAR name[32]; BOOL cached; CLSID clsid; HRESULT hr; @@ -10345,6 +10347,27 @@ static void test_effect(BOOL d3d11) {&CLSID_D2D1Grayscale, 3, 1, 1, 1}, };
+ const struct property_test + { + UINT32 index; + const WCHAR *name; + D2D1_PROPERTY_TYPE type; + UINT32 value_size; + } + property_tests[] = + { + {D2D1_PROPERTY_CLSID, L"CLSID", D2D1_PROPERTY_TYPE_CLSID, sizeof(CLSID)}, + {D2D1_PROPERTY_DISPLAYNAME, L"DisplayName", D2D1_PROPERTY_TYPE_STRING, 0}, + {D2D1_PROPERTY_AUTHOR, L"Author", D2D1_PROPERTY_TYPE_STRING, 0}, + {D2D1_PROPERTY_CATEGORY, L"Category", D2D1_PROPERTY_TYPE_STRING, 0}, + {D2D1_PROPERTY_DESCRIPTION, L"Description", D2D1_PROPERTY_TYPE_STRING, 0}, + {D2D1_PROPERTY_INPUTS, L"Inputs", D2D1_PROPERTY_TYPE_ARRAY, sizeof(UINT32)}, + {D2D1_PROPERTY_CACHED, L"Cached", D2D1_PROPERTY_TYPE_BOOL, sizeof(UINT32)}, + {D2D1_PROPERTY_PRECISION, L"Precision", D2D1_PROPERTY_TYPE_ENUM, sizeof(UINT32)}, + {D2D1_PROPERTY_MIN_INPUTS, L"MinInputs", D2D1_PROPERTY_TYPE_UINT32, sizeof(UINT32)}, + {D2D1_PROPERTY_MAX_INPUTS, L"MaxInputs", D2D1_PROPERTY_TYPE_UINT32, sizeof(UINT32)}, + }; + if (!init_test_context(&ctx, d3d11)) return;
@@ -10372,6 +10395,7 @@ static void test_effect(BOOL d3d11) hr = ID2D1DeviceContext_CreateEffect(context, test->clsid, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ /* Test output image pointer */ hr = ID2D1Effect_QueryInterface(effect, &IID_ID2D1Image, (void **)&image_a); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ID2D1Effect_GetOutput(effect, &image_b); @@ -10379,6 +10403,48 @@ static void test_effect(BOOL d3d11) ID2D1Image_Release(image_b); ID2D1Image_Release(image_a);
+ /* Test system property name, type, value size */ + for (j = 0; j < ARRAY_SIZE(property_tests); ++j) + { + const struct property_test *property_test = &property_tests[j]; + winetest_push_context("Property %u", j); + + name[0] = 0; + hr = ID2D1Effect_GetPropertyName(effect, 0xdeadbeef, name, sizeof(name)); + todo_wine ok(hr == D2DERR_INVALID_PROPERTY, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_GetPropertyName(effect, property_test->index, name, sizeof(name)); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + todo_wine ok(!wcscmp(name, property_test->name), "Got unexpected property name %s, expected %s.\n", + debugstr_w(name), debugstr_w(property_test->name)); + + type = ID2D1Effect_GetType(effect, 0xdeadbeef); + ok(type == D2D1_PROPERTY_TYPE_UNKNOWN, "Got unexpected property type %#x.\n", type); + type = ID2D1Effect_GetType(effect, property_test->index); + todo_wine ok(type == property_test->type, "Got unexpected property type %#x, expected %#x.\n", + type, property_test->type); + + value_size = ID2D1Effect_GetValueSize(effect, 0xdeadbeef); + ok(value_size == 0, "Got unexpected value size %u.\n", value_size); + value_size = ID2D1Effect_GetValueSize(effect, property_test->index); + if (property_test->value_size != 0) + { + todo_wine ok(value_size == property_test->value_size, "Got unexpected value size %u, expected %u.\n", + value_size, property_test->value_size); + } + else if (property_test->type == D2D1_PROPERTY_TYPE_STRING) + { + hr = ID2D1Effect_GetValue(effect, property_test->index, + D2D1_PROPERTY_TYPE_STRING, buffer, sizeof(buffer)); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + str_size = (wcslen((WCHAR *)buffer) + 1) * sizeof(WCHAR); + todo_wine ok(value_size == str_size, "Got unexpected value size %u, expected %u.\n", + value_size, str_size); + } + + winetest_pop_context(); + } + + /* Test GetValue() */ hr = ID2D1Effect_GetValue(effect, 0xdeadbeef, D2D1_PROPERTY_TYPE_CLSID, (BYTE *)&clsid, sizeof(clsid)); ok(hr == D2DERR_INVALID_PROPERTY, "Got unexpected hr %#lx.\n", hr);
@@ -10436,10 +10502,12 @@ static void test_effect(BOOL d3d11) ok(max_inputs == test->max_inputs, "Got unexpected max inputs %u, expected %u.\n", max_inputs, test->max_inputs);
+ /* Test default input count */ input_count = ID2D1Effect_GetInputCount(effect); ok(input_count == test->default_input_count, "Got unexpected input count %u, expected %u.\n", input_count, test->default_input_count);
+ /* Test SetInputCount() */ input_count = (test->max_inputs < 16 ? test->max_inputs : 16); for (j = 0; j < input_count + 4; ++j) { @@ -10452,6 +10520,7 @@ static void test_effect(BOOL d3d11) winetest_pop_context(); }
+ /* Test GetInput() before any input is set */ input_count = ID2D1Effect_GetInputCount(effect); for (j = 0; j < input_count + 4; ++j) { @@ -10461,6 +10530,7 @@ static void test_effect(BOOL d3d11) winetest_pop_context(); }
+ /* Test GetInput() after an input is set */ set_size_u(&size, 1, 1); bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; @@ -10487,6 +10557,7 @@ static void test_effect(BOOL d3d11) winetest_pop_context(); }
+ /* Test setting inputs with out-of-bounds index */ for (j = input_count; j < input_count + 4; ++j) { winetest_push_context("Input %u", j); @@ -12304,7 +12375,7 @@ START_TEST(d2d1) queue_test(test_effect_register); queue_test(test_effect_context); queue_test(test_effect_properties); - queue_test(test_effect); + queue_test(test_builtin_effect); queue_test(test_effect_2d_affine); queue_test(test_effect_crop); queue_test(test_effect_grayscale);
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 68d2716a118..b144571fb90 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10312,7 +10312,7 @@ static void test_mt_factory(BOOL d3d11)
static void test_builtin_effect(BOOL d3d11) { - unsigned int i, j, min_inputs, max_inputs, str_size, input_count, value_size; + unsigned int i, j, min_inputs, max_inputs, str_size, input_count, value_size, property_count; D2D1_BITMAP_PROPERTIES bitmap_desc; D2D1_BUFFER_PRECISION precision; ID2D1Image *image_a, *image_b; @@ -10333,18 +10333,19 @@ static void test_builtin_effect(BOOL d3d11) { const CLSID *clsid; UINT32 factory_version; + UINT32 property_count; UINT32 default_input_count; UINT32 min_inputs; UINT32 max_inputs; } effect_tests[] = { - {&CLSID_D2D12DAffineTransform, 1, 1, 1, 1}, - {&CLSID_D2D13DPerspectiveTransform, 1, 1, 1, 1}, - {&CLSID_D2D1Composite, 1, 2, 1, 0xffffffff}, - {&CLSID_D2D1Crop, 1, 1, 1, 1}, - {&CLSID_D2D1Shadow, 1, 1, 1, 1}, - {&CLSID_D2D1Grayscale, 3, 1, 1, 1}, + {&CLSID_D2D12DAffineTransform, 1, 4, 1, 1, 1}, + {&CLSID_D2D13DPerspectiveTransform, 1, 8, 1, 1, 1}, + {&CLSID_D2D1Composite, 1, 1, 2, 1, 0xffffffff}, + {&CLSID_D2D1Crop, 1, 2, 1, 1, 1}, + {&CLSID_D2D1Shadow, 1, 3, 1, 1, 1}, + {&CLSID_D2D1Grayscale, 3, 0, 1, 1, 1}, };
const struct property_test @@ -10403,6 +10404,12 @@ static void test_builtin_effect(BOOL d3d11) ID2D1Image_Release(image_b); ID2D1Image_Release(image_a);
+ /* Test property count */ + property_count = ID2D1Effect_GetPropertyCount(effect); + todo_wine_if(test->property_count != 0) + ok(property_count == test->property_count, "Got unexpected property count %u, expected %u.\n", + property_count, test->property_count); + /* Test system property name, type, value size */ for (j = 0; j < ARRAY_SIZE(property_tests); ++j) { @@ -11008,7 +11015,7 @@ done:
static void test_effect_properties(BOOL d3d11) { - UINT32 i, min_inputs, max_inputs, integer, index; + UINT32 i, min_inputs, max_inputs, integer, index, property_count; ID2D1EffectContext *effect_context; D2D1_BUFFER_PRECISION precision; struct d2d1_test_context ctx; @@ -11174,6 +11181,9 @@ static void test_effect_properties(BOOL d3d11) if (hr != S_OK) goto done;
+ property_count = ID2D1Effect_GetPropertyCount(effect); + ok(property_count == 2, "Got unexpected property count %u.\n", property_count); + index = ID2D1Effect_GetPropertyIndex(effect, L"Context"); ok(index == 0, "Got unexpected index %u.\n", index); index = ID2D1Effect_GetPropertyIndex(effect, L"Integer");
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117438
Your paranoid android.
=== debian11 (32 bit report) ===
d2d1: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7d9da2f9).
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index b144571fb90..2f3b4add386 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10672,7 +10672,7 @@ static HRESULT STDMETHODCALLTYPE effect_impl_set_integer(IUnknown *iface, const { struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl((ID2D1EffectImpl *)iface);
- if (!data || data_size != sizeof(effect_impl->integer)) + if (!data) return E_INVALIDARG;
effect_impl->integer = *((UINT *)data); @@ -10685,7 +10685,7 @@ static HRESULT STDMETHODCALLTYPE effect_impl_get_integer(const IUnknown *iface, { struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl((ID2D1EffectImpl *)iface);
- if (!data || data_size != sizeof(effect_impl->integer)) + if (!data) return E_INVALIDARG;
*((UINT *)data) = effect_impl->integer; @@ -10700,7 +10700,7 @@ static HRESULT STDMETHODCALLTYPE effect_impl_get_context(const IUnknown *iface, { struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl((ID2D1EffectImpl *)iface);
- if (!data || data_size != sizeof(effect_impl->effect_context)) + if (!data) return E_INVALIDARG;
*((ID2D1EffectContext **)data) = effect_impl->effect_context; @@ -11190,6 +11190,12 @@ static void test_effect_properties(BOOL d3d11) ok(index == 1, "Got unexpected index %u.\n", index);
effect_context = (ID2D1EffectContext *)0xdeadbeef; + hr = ID2D1Effect_GetValueByName(effect, + L"Context", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) - 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_GetValueByName(effect, + L"Context", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) + 1); + ok(hr == E_INVALIDARG, "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); @@ -11197,6 +11203,10 @@ static void test_effect_properties(BOOL d3d11) "Got unexpected effect context %p.\n", effect_context);
effect_context = (ID2D1EffectContext *)0xdeadbeef; + hr = ID2D1Effect_GetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) - 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_GetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) + 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1Effect_GetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(effect_context != NULL && effect_context != (ID2D1EffectContext *)0xdeadbeef, @@ -11206,16 +11216,28 @@ static void test_effect_properties(BOOL d3d11) ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
integer = 0xdeadbeef; + hr = ID2D1Effect_GetValueByName(effect, L"Integer", D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) - 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_GetValueByName(effect, L"Integer", D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) + 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1Effect_GetValueByName(effect, L"Integer", D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(integer == 10, "Got unexpected integer %u.", integer);
integer = 0xdeadbeef; + hr = ID2D1Effect_GetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) - 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_GetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) + 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1Effect_GetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(integer == 10, "Got unexpected integer %u.", integer);
integer = 20; + hr = ID2D1Effect_SetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) - 1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_SetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) + 1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1Effect_SetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); integer = 0xdeadbeef;
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/d2d1_private.h | 17 ++++- dlls/d2d1/effect.c | 144 ++++++++++++++++++++++++++++++--------- dlls/d2d1/factory.c | 9 --- 3 files changed, 125 insertions(+), 45 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 9be553c72d8..27606e78a42 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -35,6 +35,8 @@ #endif #include "dwrite_2.h"
+#define D2D1_SYSTEM_PROPERTY_COUNT (D2D1_PROPERTY_MAX_INPUTS - D2D1_PROPERTY_CLSID + 1) + enum d2d_brush_type { D2D_BRUSH_TYPE_SOLID, @@ -610,18 +612,29 @@ struct d2d_effect_info UINT32 max_inputs; };
+struct d2d_effect_property +{ + WCHAR *name; + D2D1_PROPERTY_TYPE type; + BYTE *value; + PD2D1_PROPERTY_SET_FUNCTION set_function; + PD2D1_PROPERTY_GET_FUNCTION get_function; +}; + struct d2d_effect { ID2D1Effect ID2D1Effect_iface; ID2D1Image ID2D1Image_iface; LONG refcount;
- const struct d2d_effect_info *info; - struct d2d_effect_context *effect_context; ID2D1Image **inputs; size_t inputs_size; size_t input_count; + + struct d2d_effect_property system_properties[D2D1_SYSTEM_PROPERTY_COUNT]; + struct d2d_effect_property *custom_properties; + size_t custom_property_count; };
HRESULT d2d_effect_init(struct d2d_effect *effect, diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index f5d5494c67a..e0c028664d7 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -30,6 +30,14 @@ static const struct d2d_effect_info builtin_effects[] = {&CLSID_D2D1Grayscale, 1, 1, 1}, };
+static void *memdup(const void *ptr, size_t size) +{ + void *ret = malloc(size); + if (ret) + memcpy(ret, ptr, size); + return ret; +} + static inline struct d2d_effect_context *impl_from_ID2D1EffectContext(ID2D1EffectContext *iface) { return CONTAINING_RECORD(iface, struct d2d_effect_context, ID2D1EffectContext_iface); @@ -413,10 +421,53 @@ static inline struct d2d_effect *impl_from_ID2D1Effect(ID2D1Effect *iface) return CONTAINING_RECORD(iface, struct d2d_effect, ID2D1Effect_iface); }
+static UINT32 d2d_effect_property_get_value_size(struct d2d_effect_property *property) +{ + static const UINT32 value_size[] = + { + 0, /* D2D1_PROPERTY_TYPE_UNKNOWN */ + 0, /* D2D1_PROPERTY_TYPE_STRING */ + sizeof(BOOL), /* D2D1_PROPERTY_TYPE_BOOL */ + sizeof(UINT32), /* D2D1_PROPERTY_TYPE_UINT32 */ + sizeof(INT32), /* D2D1_PROPERTY_TYPE_INT32 */ + sizeof(FLOAT), /* D2D1_PROPERTY_TYPE_FLOAT */ + sizeof(D2D_VECTOR_2F), /* D2D1_PROPERTY_TYPE_VECTOR2 */ + sizeof(D2D_VECTOR_3F), /* D2D1_PROPERTY_TYPE_VECTOR3 */ + sizeof(D2D_VECTOR_4F), /* D2D1_PROPERTY_TYPE_VECTOR4 */ + 0, /* D2D1_PROPERTY_TYPE_BLOB */ + sizeof(IUnknown *), /* D2D1_PROPERTY_TYPE_IUNKNOWN */ + sizeof(UINT32), /* D2D1_PROPERTY_TYPE_ENUM */ + sizeof(UINT32), /* D2D1_PROPERTY_TYPE_ARRAY */ + sizeof(CLSID), /* D2D1_PROPERTY_TYPE_CLSID */ + sizeof(D2D_MATRIX_3X2_F), /* D2D1_PROPERTY_TYPE_MATRIX_3X2 */ + sizeof(D2D_MATRIX_4X3_F), /* D2D1_PROPERTY_TYPE_MATRIX_4X3 */ + sizeof(D2D_MATRIX_4X4_F), /* D2D1_PROPERTY_TYPE_MATRIX_4X4 */ + sizeof(D2D_MATRIX_5X4_F), /* D2D1_PROPERTY_TYPE_MATRIX_5X4 */ + sizeof(ID2D1ColorContext *), /* D2D1_PROPERTY_TYPE_COLOR_CONTEXT */ + }; + + if (property->type == D2D1_PROPERTY_TYPE_STRING) + return sizeof(WCHAR) * (wcslen((WCHAR *)property->value) + 1); + + return value_size[property->type]; +} + static void d2d_effect_cleanup(struct d2d_effect *effect) { unsigned int i;
+ for (i = 0; i < ARRAY_SIZE(effect->system_properties); ++i) + { + free(effect->system_properties[i].name); + free(effect->system_properties[i].value); + } + + for (i = 0; i < effect->custom_property_count; ++i) + { + free(effect->custom_properties[i].name); + free(effect->custom_properties[i].value); + } + for (i = 0; i < effect->input_count; ++i) { if (effect->inputs[i]) @@ -426,6 +477,16 @@ static void d2d_effect_cleanup(struct d2d_effect *effect) ID2D1EffectContext_Release(&effect->effect_context->ID2D1EffectContext_iface); }
+static struct d2d_effect_property *d2d_effect_get_property(struct d2d_effect *effect, UINT32 index) +{ + if (index < effect->custom_property_count) + return &effect->custom_properties[index]; + else if (D2D1_PROPERTY_CLSID <= index && index <= D2D1_PROPERTY_MAX_INPUTS) + return &effect->system_properties[index - D2D1_PROPERTY_CLSID]; + else + return NULL; +} + static HRESULT STDMETHODCALLTYPE d2d_effect_QueryInterface(ID2D1Effect *iface, REFIID iid, void **out) { struct d2d_effect *effect = impl_from_ID2D1Effect(iface); @@ -546,41 +607,34 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_GetValue(ID2D1Effect *iface, UINT32 BYTE *value, UINT32 value_size) { struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - const void *src; + struct d2d_effect_property *property; + UINT32 actual_size;
TRACE("iface %p, index %u, type %#x, value %p, value_size %u.\n", iface, index, type, value, value_size);
- switch (index) - { - case D2D1_PROPERTY_CLSID: - if ((type != D2D1_PROPERTY_TYPE_UNKNOWN && type != D2D1_PROPERTY_TYPE_CLSID) - || value_size != sizeof(*effect->info->clsid)) - return E_INVALIDARG; - src = effect->info->clsid; - break; - case D2D1_PROPERTY_MIN_INPUTS: - if ((type != D2D1_PROPERTY_TYPE_UNKNOWN && type != D2D1_PROPERTY_TYPE_UINT32) - || value_size != sizeof(effect->info->min_inputs)) - return E_INVALIDARG; - src = &effect->info->min_inputs; - break; - case D2D1_PROPERTY_MAX_INPUTS: - if ((type != D2D1_PROPERTY_TYPE_UNKNOWN && type != D2D1_PROPERTY_TYPE_UINT32) - || value_size != sizeof(effect->info->max_inputs)) - return E_INVALIDARG; - src = &effect->info->max_inputs; - break; - default: - if (index < D2D1_PROPERTY_CLSID) - FIXME("Custom properties are not supported.\n"); - else if (index <= D2D1_PROPERTY_MAX_INPUTS) - FIXME("Standard property %#x is not supported.\n", index); - return D2DERR_INVALID_PROPERTY; - } + if (!(property = d2d_effect_get_property(effect, index))) + return D2DERR_INVALID_PROPERTY;
- memcpy(value, src, value_size); + actual_size = d2d_effect_property_get_value_size(property); + if ((type != D2D1_PROPERTY_TYPE_UNKNOWN && type != property->type) + || (type != D2D1_PROPERTY_TYPE_STRING && value_size != actual_size) + || (type == D2D1_PROPERTY_TYPE_STRING && value_size < actual_size)) + return E_INVALIDARG;
- return S_OK; + if (property->get_function) + { + return property->get_function((IUnknown *)iface, value, value_size, NULL); + } + else if (property->value) + { + memcpy(value, property->value, actual_size); + return S_OK; + } + else + { + WARN("Unable to get property value.\n"); + return D2DERR_INVALID_PROPERTY; + } }
static UINT32 STDMETHODCALLTYPE d2d_effect_GetValueSize(ID2D1Effect *iface, UINT32 index) @@ -614,12 +668,18 @@ static void STDMETHODCALLTYPE d2d_effect_SetInput(ID2D1Effect *iface, UINT32 ind
static HRESULT STDMETHODCALLTYPE d2d_effect_SetInputCount(ID2D1Effect *iface, UINT32 count) { + struct d2d_effect_property *min_inputs_property, *max_inputs_property; struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - unsigned int i; + UINT32 min_inputs, max_inputs, i;
TRACE("iface %p, count %u.\n", iface, count);
- if (count < effect->info->min_inputs || count > effect->info->max_inputs) + min_inputs_property = d2d_effect_get_property(effect, D2D1_PROPERTY_MIN_INPUTS); + max_inputs_property = d2d_effect_get_property(effect, D2D1_PROPERTY_MAX_INPUTS); + min_inputs = *((UINT32 *)min_inputs_property->value); + max_inputs = *((UINT32 *)max_inputs_property->value); + + if (count < min_inputs || count > max_inputs) return E_INVALIDARG; if (count == effect->input_count) return S_OK; @@ -752,6 +812,7 @@ static const ID2D1ImageVtbl d2d_effect_image_vtbl =
HRESULT d2d_effect_init(struct d2d_effect *effect, struct d2d_effect_context *effect_context, const CLSID *effect_id) { + struct d2d_effect_property *property; unsigned int i;
effect->ID2D1Effect_iface.lpVtbl = &d2d_effect_vtbl; @@ -762,10 +823,25 @@ HRESULT d2d_effect_init(struct d2d_effect *effect, struct d2d_effect_context *ef { if (IsEqualGUID(effect_id, builtin_effects[i].clsid)) { - effect->info = &builtin_effects[i]; - d2d_effect_SetInputCount(&effect->ID2D1Effect_iface, effect->info->default_input_count); + property = d2d_effect_get_property(effect, D2D1_PROPERTY_CLSID); + property->name = wcsdup(L"ClSID"); + property->type = D2D1_PROPERTY_TYPE_CLSID; + property->value = memdup(effect_id, sizeof(*effect_id)); + + property = d2d_effect_get_property(effect, D2D1_PROPERTY_MIN_INPUTS); + property->name = wcsdup(L"MinInputs"); + property->type = D2D1_PROPERTY_TYPE_UINT32; + property->value = memdup(&builtin_effects[i].min_inputs, sizeof(builtin_effects[i].min_inputs)); + + property = d2d_effect_get_property(effect, D2D1_PROPERTY_MAX_INPUTS); + property->name = wcsdup(L"MaxInputs"); + property->type = D2D1_PROPERTY_TYPE_UINT32; + property->value = memdup(&builtin_effects[i].max_inputs, sizeof(builtin_effects[i].max_inputs)); + + d2d_effect_SetInputCount(&effect->ID2D1Effect_iface, builtin_effects[i].default_input_count); effect->effect_context = effect_context; ID2D1EffectContext_AddRef(&effect_context->ID2D1EffectContext_iface); + return S_OK; } } diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 5c79d1791ff..36feaeb6f29 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -30,15 +30,6 @@ struct d2d_settings d2d_settings = ~0u, /* No ID2D1Factory version limit by default. */ };
-struct d2d_effect_property -{ - WCHAR *name; - D2D1_PROPERTY_TYPE type; - BYTE *value; - PD2D1_PROPERTY_SET_FUNCTION set_function; - PD2D1_PROPERTY_GET_FUNCTION get_function; -}; - struct d2d_effect_registration { struct list entry;
Signed-off-by: Ziqing Hui zhui@codeweavers.com --- dlls/d2d1/effect.c | 8 +++++++- dlls/d2d1/tests/d2d1.c | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index e0c028664d7..139095bae09 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -639,7 +639,13 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_GetValue(ID2D1Effect *iface, UINT32
static UINT32 STDMETHODCALLTYPE d2d_effect_GetValueSize(ID2D1Effect *iface, UINT32 index) { - FIXME("iface %p, index %u stub!\n", iface, index); + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + struct d2d_effect_property *property; + + TRACE("iface %p, index %u.\n", iface, index); + + if ((property = d2d_effect_get_property(effect, index))) + return d2d_effect_property_get_value_size(property);
return 0; } diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 2f3b4add386..f86af6ec1bd 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10435,7 +10435,10 @@ static void test_builtin_effect(BOOL d3d11) value_size = ID2D1Effect_GetValueSize(effect, property_test->index); if (property_test->value_size != 0) { - todo_wine ok(value_size == property_test->value_size, "Got unexpected value size %u, expected %u.\n", + todo_wine_if(property_test->index != D2D1_PROPERTY_CLSID && + property_test->index != D2D1_PROPERTY_MIN_INPUTS && + property_test->index != D2D1_PROPERTY_MAX_INPUTS) + ok(value_size == property_test->value_size, "Got unexpected value size %u, expected %u.\n", value_size, property_test->value_size); } else if (property_test->type == D2D1_PROPERTY_TYPE_STRING)
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117441
Your paranoid android.
=== debian11 (32 bit Hebrew:Israel report) ===
d2d1: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7d9652f9).