From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/d2d1/tests/d2d1.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 61177aba9de..935cb73e7fa 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -220,6 +220,21 @@ L"<?xml version='1.0'?> \ </Effect> \ ";
+static const WCHAR *effect_variable_input_count = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='VariableInputs'/> \ + <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 minimum='2' maximum='5' > \ + <Input name='Source1'/> \ + <Input name='Source2'/> \ + <Input name='Source3'/> \ + </Inputs> \ + </Effect> \ +"; + static const DWORD test_vs[] = { #if 0 @@ -11451,6 +11466,33 @@ static void test_effect_register(BOOL d3d11) hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_D2D1Composite); ok(hr == D2DERR_EFFECT_IS_NOT_REGISTERED, "Got unexpected hr %#lx.\n", hr);
+ /* Variable input count. */ + hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, + effect_variable_input_count, NULL, 0, effect_impl_create); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1DeviceContext_CreateEffect(device_context, &CLSID_TestEffect, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + integer = 0; + hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, + (BYTE *)&integer, sizeof(integer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + todo_wine + ok(integer == 2, "Unexpected value %u.\n", integer); + hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, + (BYTE *)&integer, sizeof(integer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + todo_wine + ok(integer == 5, "Unexpected value %u.\n", integer); + hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_INPUTS, D2D1_PROPERTY_TYPE_ARRAY, + (BYTE *)&integer, sizeof(integer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(integer == 3, "Unexpected data %u.\n", integer); + ID2D1Effect_Release(effect); + + hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + release_test_context(&ctx); }
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/d2d1/d2d1_private.h | 2 + dlls/d2d1/effect.c | 7 ++++ dlls/d2d1/factory.c | 90 +++++++++++++++++++++++++++++++++------- dlls/d2d1/tests/d2d1.c | 2 - 4 files changed, 83 insertions(+), 18 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 36bedf8331c..645fea197f6 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -707,6 +707,8 @@ struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory const GUID *effect_id); void d2d_factory_register_effect(struct d2d_factory *factory, struct d2d_effect_registration *effect); +HRESULT d2d_effect_property_get_uint32_value(const struct d2d_effect_properties *properties, + const struct d2d_effect_property *prop, UINT32 *value);
struct d2d_transform_graph { diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index ddc9eee9236..a3de883dfbe 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -570,6 +570,13 @@ static HRESULT d2d_effect_property_get_value(const struct d2d_effect_properties return S_OK; }
+HRESULT d2d_effect_property_get_uint32_value(const struct d2d_effect_properties *properties, + const struct d2d_effect_property *prop, UINT32 *value) +{ + return d2d_effect_property_get_value(properties, prop, D2D1_PROPERTY_TYPE_UINT32, + (BYTE *)value, sizeof(*value)); +} + static HRESULT d2d_effect_property_set_value(struct d2d_effect_properties *properties, struct d2d_effect_property *prop, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 size) { diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index d349da376fc..938c62e4fb0 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -788,12 +788,13 @@ static HRESULT parse_effect_property(IXmlReader *reader, struct d2d_effect_regis
static HRESULT parse_effect_inputs(IXmlReader *reader, struct d2d_effect_registration *effect) { + struct d2d_effect_property *inputs, *min_inputs, *max_inputs; struct d2d_effect_properties *subproperties; + UINT32 min_inputs_value, max_inputs_value; unsigned int depth, input_count = 0; - struct d2d_effect_property *inputs; XmlNodeType node_type; - WCHAR nameW[16]; - WCHAR *name; + WCHAR *name, *value; + WCHAR buffW[16]; HRESULT hr;
if (FAILED(hr = d2d_effect_properties_add(&effect->properties, L"Inputs", @@ -811,28 +812,85 @@ static HRESULT parse_effect_inputs(IXmlReader *reader, struct d2d_effect_registr d2d_effect_subproperties_add(subproperties, L"DisplayName", D2D1_SUBPROPERTY_DISPLAYNAME, D2D1_PROPERTY_TYPE_STRING, L"Inputs");
- if (IXmlReader_IsEmptyElement(reader)) return S_OK; + if (SUCCEEDED(parse_effect_get_attribute(reader, L"minimum", &value))) + { + hr = d2d_effect_properties_add(&effect->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS, + D2D1_PROPERTY_TYPE_UINT32, value); + free(value); + if (FAILED(hr)) return hr; + } + if (SUCCEEDED(parse_effect_get_attribute(reader, L"maximum", &value))) + { + hr = d2d_effect_properties_add(&effect->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, + D2D1_PROPERTY_TYPE_UINT32, value); + free(value); + if (FAILED(hr)) return hr; + } + + min_inputs = d2d_effect_properties_get_property_by_name(&effect->properties, L"MinInputs"); + max_inputs = d2d_effect_properties_get_property_by_name(&effect->properties, L"MaxInputs");
- while (parse_effect_get_next_xml_node(reader, XmlNodeType_None, L"Input", &depth) == S_OK) + if (!IXmlReader_IsEmptyElement(reader)) { + while (parse_effect_get_next_xml_node(reader, XmlNodeType_None, L"Input", &depth) == S_OK) + { + if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr; + if (node_type == XmlNodeType_EndElement) continue; + if (node_type != XmlNodeType_Element) return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + if (FAILED(hr = parse_effect_get_attribute(reader, L"name", &name))) return hr; + + swprintf(buffW, ARRAY_SIZE(buffW), L"%lu", input_count); + d2d_effect_subproperties_add(subproperties, buffW, input_count, D2D1_PROPERTY_TYPE_STRING, name); + input_count++; + + free(name); + } + *(UINT32 *)(effect->properties.data.ptr + inputs->data.offset) = input_count; + if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr; - if (node_type == XmlNodeType_EndElement) continue; - if (node_type != XmlNodeType_Element) return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + if (node_type != XmlNodeType_EndElement) return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + }
- if (FAILED(hr = parse_effect_get_attribute(reader, L"name", &name))) return hr; + if (min_inputs) + d2d_effect_property_get_uint32_value(&effect->properties, min_inputs, &min_inputs_value); + if (max_inputs) + d2d_effect_property_get_uint32_value(&effect->properties, max_inputs, &max_inputs_value);
- swprintf(nameW, ARRAY_SIZE(nameW), L"%lu", input_count); - d2d_effect_subproperties_add(subproperties, nameW, input_count, D2D1_PROPERTY_TYPE_STRING, name); - input_count++; + /* Validate the range */ + if (min_inputs && max_inputs) + { + if (min_inputs_value > max_inputs_value) + { + WARN("Invalid input count range %u - %u.\n", min_inputs_value, max_inputs_value); + return E_INVALIDARG; + } + }
- free(name); + /* Validate actual input count with specified range. */ + if (min_inputs && min_inputs_value > input_count) + { + WARN("Too few inputs were declared, expected at least %u.\n", min_inputs_value); + return E_INVALIDARG; + } + + if (max_inputs && max_inputs_value < input_count) + { + WARN("Too many inputs were declared, expected at most %u.\n", max_inputs_value); + return E_INVALIDARG; } - *(UINT32 *)(effect->properties.data.ptr + inputs->data.offset) = input_count;
- if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr; - if (node_type != XmlNodeType_EndElement) return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + /* Apply default value to a missing property. */ + if (min_inputs != max_inputs) + { + swprintf(buffW, ARRAY_SIZE(buffW), L"%lu", min_inputs ? min_inputs_value : max_inputs_value); + if (min_inputs) + hr = d2d_effect_properties_add(&effect->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, buffW); + else + hr = d2d_effect_properties_add(&effect->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, buffW); + }
- return S_OK; + return hr; }
static HRESULT parse_effect_xml(IXmlReader *reader, struct d2d_effect_registration *effect) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 935cb73e7fa..ef4187d50c0 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -11477,12 +11477,10 @@ static void test_effect_register(BOOL d3d11) hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine ok(integer == 2, "Unexpected value %u.\n", integer); hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine ok(integer == 5, "Unexpected value %u.\n", integer); hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_INPUTS, D2D1_PROPERTY_TYPE_ARRAY, (BYTE *)&integer, sizeof(integer));
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/d2d1/d2d1_private.h | 5 +- dlls/d2d1/effect.c | 176 ++++++++++++++++++++++++++++----------- dlls/d2d1/factory.c | 76 ++++++++++++----- dlls/d2d1/tests/d2d1.c | 73 ++++++++++++---- 4 files changed, 240 insertions(+), 90 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 645fea197f6..dced9847390 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -674,8 +674,6 @@ struct d2d_effect_registration BOOL builtin; CLSID id;
- UINT32 input_count; - UINT32 default_input_count; struct d2d_effect_properties properties; };
@@ -740,6 +738,9 @@ HRESULT d2d_effect_subproperties_add(struct d2d_effect_properties *props, const struct d2d_effect_property * d2d_effect_properties_get_property_by_name( const struct d2d_effect_properties *properties, const WCHAR *name); void d2d_effect_properties_cleanup(struct d2d_effect_properties *props); +HRESULT d2d_factory_register_builtin_effect(struct d2d_factory *factory, REFCLSID effect_id, + const WCHAR *property_xml, const D2D1_PROPERTY_BINDING *bindings, UINT32 binding_count, + PD2D1_EFFECT_FACTORY effect_factory);
enum d2d_command_list_state { diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index a3de883dfbe..f857afb401d 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -211,48 +211,105 @@ static HRESULT STDMETHODCALLTYPE builtin_factory_stub(IUnknown **effect_impl) return S_OK; }
-struct d2d_effect_info -{ - const CLSID *clsid; - UINT32 default_input_count; - UINT32 min_inputs; - UINT32 max_inputs; -}; - -static const struct d2d_effect_info builtin_effects[] = -{ - {&CLSID_D2D12DAffineTransform, 1, 1, 1}, - {&CLSID_D2D13DPerspectiveTransform, 1, 1, 1}, - {&CLSID_D2D1Composite, 2, 1, 0xffffffff}, - {&CLSID_D2D1Crop, 1, 1, 1}, - {&CLSID_D2D1Shadow, 1, 1, 1}, - {&CLSID_D2D1Grayscale, 1, 1, 1}, -}; +static const WCHAR * const _2d_affine_transform_description = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='2D Affine Transform'/> \ + <Property name='Author' type='string' value='The Wine Project'/> \ + <Property name='Category' type='string' value='Stub'/> \ + <Property name='Description' type='string' value='2D Affine Transform'/> \ + <Inputs> \ + <Input name='Source'/> \ + </Inputs> \ + </Effect>"; + +static const WCHAR * const _3d_perspective_transform_description = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='3D Perspective Transform'/> \ + <Property name='Author' type='string' value='The Wine Project'/> \ + <Property name='Category' type='string' value='Stub'/> \ + <Property name='Description' type='string' value='3D Perspective Transform'/> \ + <Inputs> \ + <Input name='Source'/> \ + </Inputs> \ + </Effect>"; + +static const WCHAR * const composite_description = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='Composite'/> \ + <Property name='Author' type='string' value='The Wine Project'/> \ + <Property name='Category' type='string' value='Stub'/> \ + <Property name='Description' type='string' value='Composite'/> \ + <Inputs minimum='1' maximum='0xffffffff' > \ + <Input name='Source1'/> \ + <Input name='Source2'/> \ + </Inputs> \ + </Effect>"; + +static const WCHAR * const crop_description = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='Crop'/> \ + <Property name='Author' type='string' value='The Wine Project'/> \ + <Property name='Category' type='string' value='Stub'/> \ + <Property name='Description' type='string' value='Crop'/> \ + <Inputs > \ + <Input name='Source'/> \ + </Inputs> \ + </Effect>"; + +static const WCHAR * const shadow_description = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='Shadow'/> \ + <Property name='Author' type='string' value='The Wine Project'/> \ + <Property name='Category' type='string' value='Stub'/> \ + <Property name='Description' type='string' value='Shadow'/> \ + <Inputs > \ + <Input name='Source'/> \ + </Inputs> \ + </Effect>"; + +static const WCHAR * const grayscale_description = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='Grayscale'/> \ + <Property name='Author' type='string' value='The Wine Project'/> \ + <Property name='Category' type='string' value='Stub'/> \ + <Property name='Description' type='string' value='Grayscale'/> \ + <Inputs > \ + <Input name='Source'/> \ + </Inputs> \ + </Effect>";
void d2d_effects_init_builtins(struct d2d_factory *factory) { - struct d2d_effect_registration *effect; + static const struct builtin_description + { + const CLSID *clsid; + const WCHAR *description; + } + builtin_effects[] = + { + { &CLSID_D2D12DAffineTransform, _2d_affine_transform_description }, + { &CLSID_D2D13DPerspectiveTransform, _3d_perspective_transform_description}, + { &CLSID_D2D1Composite, composite_description }, + { &CLSID_D2D1Crop, crop_description }, + { &CLSID_D2D1Shadow, shadow_description }, + { &CLSID_D2D1Grayscale, grayscale_description }, + }; unsigned int i; + HRESULT hr;
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); + if (FAILED(hr = d2d_factory_register_builtin_effect(factory, builtin_effects[i].clsid, builtin_effects[i].description, + NULL, 0, builtin_factory_stub))) + { + WARN("Failed to register the effect %s, hr %#lx.\n", wine_dbgstr_guid(builtin_effects[i].clsid), hr); + } } }
@@ -387,6 +444,9 @@ static HRESULT d2d_effect_properties_internal_add(struct d2d_effect_properties * { case D2D1_PROPERTY_TYPE_UINT32: case D2D1_PROPERTY_TYPE_INT32: + _uint32 = wcstoul(value, NULL, 0); + src = &_uint32; + break; case D2D1_PROPERTY_TYPE_ENUM: _uint32 = wcstoul(value, NULL, 10); src = &_uint32; @@ -1127,6 +1187,12 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_GetValueByName(ID2D1Effect *iface, c value, value_size); }
+static HRESULT d2d_effect_get_value(struct d2d_effect *effect, UINT32 index, D2D1_PROPERTY_TYPE type, + BYTE *value, UINT32 value_size) +{ + return ID2D1Properties_GetValue(&effect->properties.ID2D1Properties_iface, index, type, value, value_size); +} + static HRESULT STDMETHODCALLTYPE d2d_effect_GetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size) { @@ -1134,8 +1200,7 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_GetValue(ID2D1Effect *iface, UINT32
TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size);
- return ID2D1Properties_GetValue(&effect->properties.ID2D1Properties_iface, index, type, - value, value_size); + return d2d_effect_get_value(effect, index, type, value, value_size); }
static UINT32 STDMETHODCALLTYPE d2d_effect_GetValueSize(ID2D1Effect *iface, UINT32 index) @@ -1172,20 +1237,10 @@ static void STDMETHODCALLTYPE d2d_effect_SetInput(ID2D1Effect *iface, UINT32 ind effect->inputs[index] = input; }
-static HRESULT STDMETHODCALLTYPE d2d_effect_SetInputCount(ID2D1Effect *iface, UINT32 count) +static HRESULT d2d_effect_set_input_count(struct d2d_effect *effect, UINT32 count) { - struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - unsigned int i, min_inputs, max_inputs; - - TRACE("iface %p, count %u.\n", iface, count); - - d2d_effect_GetValue(iface, D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, - (BYTE *)&min_inputs, sizeof(min_inputs)); - d2d_effect_GetValue(iface, D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, - (BYTE *)&max_inputs, sizeof(max_inputs)); + unsigned int i;
- if (count < min_inputs || count > max_inputs) - return E_INVALIDARG; if (count == effect->input_count) return S_OK;
@@ -1213,6 +1268,24 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_SetInputCount(ID2D1Effect *iface, UI return S_OK; }
+static HRESULT STDMETHODCALLTYPE d2d_effect_SetInputCount(ID2D1Effect *iface, UINT32 count) +{ + struct d2d_effect *effect = impl_from_ID2D1Effect(iface); + unsigned int min_inputs, max_inputs; + + TRACE("iface %p, count %u.\n", iface, count); + + d2d_effect_get_value(effect, D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, + (BYTE *)&min_inputs, sizeof(min_inputs)); + d2d_effect_get_value(effect, D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, + (BYTE *)&max_inputs, sizeof(max_inputs)); + + if (count < min_inputs || count > max_inputs) + return E_INVALIDARG; + + return d2d_effect_set_input_count(effect, count); +} + static void STDMETHODCALLTYPE d2d_effect_GetInput(ID2D1Effect *iface, UINT32 index, ID2D1Image **input) { struct d2d_effect *effect = impl_from_ID2D1Effect(iface); @@ -1539,6 +1612,7 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec const struct d2d_effect_registration *reg; struct d2d_transform_graph *graph; struct d2d_effect *object; + UINT32 input_count; WCHAR clsidW[39]; HRESULT hr;
@@ -1581,7 +1655,9 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec 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, reg->default_input_count); + /* Sync instance input count with default input count from the description. */ + d2d_effect_get_value(object, D2D1_PROPERTY_INPUTS, D2D1_PROPERTY_TYPE_ARRAY, (BYTE *)&input_count, sizeof(input_count)); + d2d_effect_set_input_count(object, input_count);
if (FAILED(hr = reg->factory((IUnknown **)&object->impl))) { diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 938c62e4fb0..0d74becf5a1 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -69,7 +69,7 @@ struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory struct d2d_factory *factory = unsafe_impl_from_ID2D1Factory(iface); struct d2d_effect_registration *reg;
- d2d_effects_init_builtins(factory); + d2d_factory_init_builtin_effects(factory);
LIST_FOR_EACH_ENTRY(reg, &factory->effects, struct d2d_effect_registration, entry) { @@ -880,7 +880,7 @@ static HRESULT parse_effect_inputs(IXmlReader *reader, struct d2d_effect_registr return E_INVALIDARG; }
- /* Apply default value to a missing property. */ + /* Apply default value to a missing property. If both properties are missing, add them. */ if (min_inputs != max_inputs) { swprintf(buffW, ARRAY_SIZE(buffW), L"%lu", min_inputs ? min_inputs_value : max_inputs_value); @@ -889,6 +889,13 @@ static HRESULT parse_effect_inputs(IXmlReader *reader, struct d2d_effect_registr else hr = d2d_effect_properties_add(&effect->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, buffW); } + else if (!min_inputs) + { + swprintf(buffW, ARRAY_SIZE(buffW), L"%lu", input_count); + hr = d2d_effect_properties_add(&effect->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, buffW); + if (SUCCEEDED(hr)) + hr = d2d_effect_properties_add(&effect->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, buffW); + }
return hr; } @@ -933,21 +940,15 @@ static HRESULT parse_effect_xml(IXmlReader *reader, struct d2d_effect_registrati return hr; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Factory3 *iface, +static HRESULT d2d_factory_register_effect_from_stream(struct d2d_factory *factory, REFCLSID effect_id, IStream *property_xml, const D2D1_PROPERTY_BINDING *bindings, - UINT32 binding_count, PD2D1_EFFECT_FACTORY effect_factory) + UINT32 binding_count, PD2D1_EFFECT_FACTORY effect_factory, BOOL builtin) { - struct d2d_factory *factory = impl_from_ID2D1Factory3(iface); struct d2d_effect_registration *effect; IXmlReader *reader; unsigned int i; HRESULT hr;
- 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); - - 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)) @@ -972,6 +973,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Facto IXmlReader_Release(reader); return E_OUTOFMEMORY; } + effect->builtin = builtin;
hr = parse_effect_xml(reader, effect); IXmlReader_Release(reader); @@ -1013,28 +1015,35 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Facto effect->registration_count = 1; effect->id = *effect_id; effect->factory = effect_factory; - 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; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromString(ID2D1Factory3 *iface, - REFCLSID effect_id, const WCHAR *property_xml, const D2D1_PROPERTY_BINDING *bindings, +static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Factory3 *iface, + REFCLSID effect_id, IStream *property_xml, const D2D1_PROPERTY_BINDING *bindings, UINT32 binding_count, PD2D1_EFFECT_FACTORY effect_factory) +{ + struct d2d_factory *factory = impl_from_ID2D1Factory3(iface); + + 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); + + d2d_factory_init_builtin_effects(factory); + + return d2d_factory_register_effect_from_stream(factory, effect_id, property_xml, bindings, + binding_count, effect_factory, FALSE); +} + +static HRESULT d2d_factory_register_effect_from_string(struct d2d_factory *factory, + REFCLSID effect_id, const WCHAR *property_xml, const D2D1_PROPERTY_BINDING *bindings, + UINT32 binding_count, PD2D1_EFFECT_FACTORY effect_factory, BOOL builtin) { static const LARGE_INTEGER zero; IStream *stream; ULONG size; HRESULT hr;
- TRACE("iface %p, effect_id %s, property_xml %s, bindings %p, binding_count %u, effect_factory %p.\n", - iface, debugstr_guid(effect_id), debugstr_w(property_xml), bindings, binding_count, effect_factory); - if (FAILED(hr = CreateStreamOnHGlobal(NULL, TRUE, &stream))) return hr;
@@ -1043,13 +1052,36 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromString(ID2D1Facto hr = IStream_Seek(stream, zero, SEEK_SET, NULL);
if (SUCCEEDED(hr)) - hr = ID2D1Factory3_RegisterEffectFromStream(iface, effect_id, stream, bindings, - binding_count, effect_factory); + hr = d2d_factory_register_effect_from_stream(factory, effect_id, stream, bindings, + binding_count, effect_factory, builtin);
IStream_Release(stream); return hr; }
+HRESULT d2d_factory_register_builtin_effect(struct d2d_factory *factory, REFCLSID effect_id, + const WCHAR *property_xml, const D2D1_PROPERTY_BINDING *bindings, UINT32 binding_count, + PD2D1_EFFECT_FACTORY effect_factory) +{ + return d2d_factory_register_effect_from_string(factory, effect_id, property_xml, bindings, + binding_count, effect_factory, TRUE); +} + +static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromString(ID2D1Factory3 *iface, + REFCLSID effect_id, const WCHAR *property_xml, const D2D1_PROPERTY_BINDING *bindings, + UINT32 binding_count, PD2D1_EFFECT_FACTORY effect_factory) +{ + struct d2d_factory *factory = impl_from_ID2D1Factory3(iface); + + TRACE("iface %p, effect_id %s, property_xml %s, bindings %p, binding_count %u, effect_factory %p.\n", + iface, debugstr_guid(effect_id), debugstr_w(property_xml), bindings, binding_count, effect_factory); + + d2d_factory_init_builtin_effects(factory); + + return d2d_factory_register_effect_from_string(factory, effect_id, property_xml, bindings, + binding_count, effect_factory, FALSE); +} + static HRESULT STDMETHODCALLTYPE d2d_factory_UnregisterEffect(ID2D1Factory3 *iface, REFCLSID effect_id) { struct d2d_factory *factory = impl_from_ID2D1Factory3(iface); diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index ef4187d50c0..6586f61bc6a 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -53,10 +53,22 @@ L"<?xml version='1.0'?> \ <Property name='DisplayName' type='string' value='Int32 prop'/> \ <Property name='Default' type='int32' value='10'/> \ </Property> \ + <Property name='Int32PropHex' type='int32' value='0xffff0001'> \ + <Property name='DisplayName' type='string' value='Int32 prop hex'/> \ + </Property> \ + <Property name='Int32PropOct' type='int32' value='012'> \ + <Property name='DisplayName' type='string' value='Int32 prop oct'/> \ + </Property> \ <Property name='UInt32Prop' type='uint32' value='-3'> \ <Property name='DisplayName' type='string' value='UInt32 prop'/> \ <Property name='Default' type='uint32' value='10'/> \ </Property> \ + <Property name='UInt32PropHex' type='uint32' value='0xfff'> \ + <Property name='DisplayName' type='string' value='UInt32 prop hex'/> \ + </Property> \ + <Property name='UInt32PropOct' type='uint32' value='013'> \ + <Property name='DisplayName' type='string' value='UInt32 prop oct'/> \ + </Property> \ <Property name='Bool' type='bool'> \ <Property name='DisplayName' type='string' value='Bool property'/> \ <Property name='Default' type='bool' value='false'/> \ @@ -10820,8 +10832,8 @@ static void test_mt_factory(BOOL d3d11) release_test_context(&ctx); }
-#define check_system_properties(effect, is_builtin) check_system_properties_(__LINE__, effect, is_builtin) -static void check_system_properties_(unsigned int line, ID2D1Effect *effect, BOOL is_builtin) +#define check_system_properties(effect) check_system_properties_(__LINE__, effect) +static void check_system_properties_(unsigned int line, ID2D1Effect *effect) { UINT i, value_size, str_size; WCHAR name[32], buffer[256]; @@ -10863,7 +10875,6 @@ static void check_system_properties_(unsigned int line, ID2D1Effect *effect, BOO
name[0] = 0; hr = ID2D1Effect_GetPropertyName(effect, test->index, name, sizeof(name)); - todo_wine_if((is_builtin && (test->type == D2D1_PROPERTY_TYPE_ARRAY || test->type == D2D1_PROPERTY_TYPE_STRING))) ok_(__FILE__, line)(hr == S_OK, "Failed to get property name, hr %#lx\n", hr); if (hr == D2DERR_INVALID_PROPERTY) { @@ -10874,7 +10885,6 @@ static void check_system_properties_(unsigned int line, ID2D1Effect *effect, BOO debugstr_w(name), debugstr_w(test->name));
type = ID2D1Effect_GetType(effect, test->index); - todo_wine_if((is_builtin && (test->type == D2D1_PROPERTY_TYPE_ARRAY || test->type == D2D1_PROPERTY_TYPE_STRING))) ok_(__FILE__, line)(type == test->type, "Got unexpected property type %#x, expected %#x.\n", type, test->type);
@@ -10882,17 +10892,15 @@ static void check_system_properties_(unsigned int line, ID2D1Effect *effect, BOO value_size = ID2D1Effect_GetValueSize(effect, test->index); if (test->value_size != 0) { - todo_wine_if(is_builtin && test->type == D2D1_PROPERTY_TYPE_ARRAY) ok_(__FILE__, line)(value_size == test->value_size, "Got unexpected value size %u, expected %u.\n", value_size, test->value_size); } else if (test->type == D2D1_PROPERTY_TYPE_STRING) { hr = ID2D1Effect_GetValue(effect, test->index, D2D1_PROPERTY_TYPE_STRING, (BYTE *)buffer, sizeof(buffer)); - todo_wine_if(is_builtin) ok_(__FILE__, line)(hr == S_OK, "Failed to get value, hr %#lx.\n", hr); str_size = (wcslen((WCHAR *)buffer) + 1) * sizeof(WCHAR); - todo_wine_if(is_builtin || buffer[0] == 0) + todo_wine_if(buffer[0] == 0) ok_(__FILE__, line)(value_size == str_size, "Got unexpected value size %u, expected %u.\n", value_size, str_size); } @@ -10982,12 +10990,12 @@ static void test_builtin_effect(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_DISPLAYNAME, D2D1_PROPERTY_TYPE_STRING, buffer, sizeof(buffer)); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); str_size = (wcslen((WCHAR *)buffer) + 1) * sizeof(WCHAR); hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_DISPLAYNAME, D2D1_PROPERTY_TYPE_STRING, buffer, str_size); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_DISPLAYNAME, D2D1_PROPERTY_TYPE_STRING, buffer, str_size - 1); - todo_wine ok(hr == D2DERR_INSUFFICIENT_BUFFER, "Got unexpected hr %#lx.\n", hr); + ok(hr == D2DERR_INSUFFICIENT_BUFFER, "Got unexpected hr %#lx.\n", hr);
hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID, 0xdeadbeef, (BYTE *)&clsid, sizeof(clsid)); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); @@ -11472,6 +11480,8 @@ static void test_effect_register(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1DeviceContext_CreateEffect(device_context, &CLSID_TestEffect, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + integer = ID2D1Effect_GetInputCount(effect); + ok(integer == 3, "Unexpected input count %u.\n", integer);
integer = 0; hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, @@ -11740,6 +11750,28 @@ static void test_effect_properties(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(val == -2, "Unexpected value %d.\n", val);
+ /* Int32 property, hex literal. */ + index = ID2D1Effect_GetPropertyIndex(effect, L"Int32PropHex"); + hr = ID2D1Effect_GetPropertyName(effect, index, buffer, ARRAY_SIZE(buffer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(buffer, L"Int32PropHex"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); + prop_type = ID2D1Effect_GetType(effect, index); + ok(prop_type == D2D1_PROPERTY_TYPE_INT32, "Unexpected type %u.\n", prop_type); + hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_INT32, (BYTE *)&val, sizeof(val)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(val == -65535, "Unexpected value %d.\n", val); + + /* Int32 property, octal literal. */ + index = ID2D1Effect_GetPropertyIndex(effect, L"Int32PropOct"); + hr = ID2D1Effect_GetPropertyName(effect, index, buffer, ARRAY_SIZE(buffer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(buffer, L"Int32PropOct"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); + prop_type = ID2D1Effect_GetType(effect, index); + ok(prop_type == D2D1_PROPERTY_TYPE_INT32, "Unexpected type %u.\n", prop_type); + hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_INT32, (BYTE *)&val, sizeof(val)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(val == 10, "Unexpected value %d.\n", val); + /* UInt32 property. */ index = ID2D1Effect_GetPropertyIndex(effect, L"UInt32Prop"); hr = ID2D1Effect_GetPropertyName(effect, index, buffer, ARRAY_SIZE(buffer)); @@ -11751,6 +11783,17 @@ static void test_effect_properties(BOOL d3d11) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(integer == -3, "Unexpected value %u.\n", integer);
+ /* UInt32 property, hex literal. */ + index = ID2D1Effect_GetPropertyIndex(effect, L"UInt32PropHex"); + hr = ID2D1Effect_GetPropertyName(effect, index, buffer, ARRAY_SIZE(buffer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(buffer, L"UInt32PropHex"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); + prop_type = ID2D1Effect_GetType(effect, index); + ok(prop_type == D2D1_PROPERTY_TYPE_UINT32, "Unexpected type %u.\n", prop_type); + hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(integer == 0xfff, "Unexpected value %x.\n", integer); + /* Vector2 property. */ index = ID2D1Effect_GetPropertyIndex(effect, L"Vec2Prop"); hr = ID2D1Effect_GetPropertyName(effect, index, buffer, ARRAY_SIZE(buffer)); @@ -11854,7 +11897,7 @@ static void test_effect_properties(BOOL d3d11) hr = ID2D1DeviceContext_CreateEffect(ctx.context, &CLSID_TestEffect, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- check_system_properties(effect, FALSE); + check_system_properties(effect);
hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_CLSID, (BYTE *)&clsid, sizeof(clsid)); @@ -11899,14 +11942,12 @@ static void test_effect_properties(BOOL d3d11) hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_MIN_INPUTS, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&min_inputs, sizeof(min_inputs)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine_if(test->min_inputs == 0) ok(min_inputs == test->min_inputs, "Got unexpected min inputs %u, expected %u.\n", min_inputs, test->min_inputs);
hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&max_inputs, sizeof(max_inputs)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine_if(test->max_inputs == 0) ok(max_inputs == test->max_inputs, "Got unexpected max inputs %u, expected %u.\n", max_inputs, test->max_inputs);
@@ -12226,7 +12267,7 @@ static void test_effect_2d_affine(BOOL d3d11) hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D12DAffineTransform, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- check_system_properties(effect, TRUE); + check_system_properties(effect);
count = ID2D1Effect_GetPropertyCount(effect); todo_wine ok(count == 4, "Got unexpected property count %u.\n", count); @@ -12369,7 +12410,7 @@ static void test_effect_crop(BOOL d3d11) hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1Crop, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- check_system_properties(effect, TRUE); + check_system_properties(effect);
count = ID2D1Effect_GetPropertyCount(effect); todo_wine ok(count == 2, "Got unexpected property count %u.\n", count); @@ -12453,7 +12494,7 @@ static void test_effect_grayscale(BOOL d3d11) hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1Grayscale, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- check_system_properties(effect, TRUE); + check_system_properties(effect);
count = ID2D1Effect_GetPropertyCount(effect); ok(!count, "Got unexpected property count %u.\n", count);
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/d2d1/effect.c | 40 ++++++++++++++++++++++++++++------------ dlls/d2d1/tests/d2d1.c | 14 +++++++++++++- 2 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index f857afb401d..755b2821df4 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -189,7 +189,7 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_impl_PrepareForRender(ID2D1EffectImp
static HRESULT STDMETHODCALLTYPE d2d_effect_impl_SetGraph(ID2D1EffectImpl *iface, ID2D1TransformGraph *graph) { - return E_NOTIMPL; + return S_OK; }
static const ID2D1EffectImplVtbl d2d_effect_impl_vtbl = @@ -1045,7 +1045,8 @@ static void d2d_effect_cleanup(struct d2d_effect *effect) } free(effect->inputs); ID2D1EffectContext_Release(&effect->effect_context->ID2D1EffectContext_iface); - ID2D1TransformGraph_Release(&effect->graph->ID2D1TransformGraph_iface); + if (effect->graph) + ID2D1TransformGraph_Release(&effect->graph->ID2D1TransformGraph_iface); d2d_effect_properties_cleanup(&effect->properties); if (effect->impl) ID2D1EffectImpl_Release(effect->impl); @@ -1239,6 +1240,8 @@ static void STDMETHODCALLTYPE d2d_effect_SetInput(ID2D1Effect *iface, UINT32 ind
static HRESULT d2d_effect_set_input_count(struct d2d_effect *effect, UINT32 count) { + bool initialized = effect->inputs != NULL; + HRESULT hr = S_OK; unsigned int i;
if (count == effect->input_count) @@ -1251,21 +1254,34 @@ static HRESULT d2d_effect_set_input_count(struct d2d_effect *effect, UINT32 coun if (effect->inputs[i]) ID2D1Image_Release(effect->inputs[i]); } - effect->input_count = count; - return S_OK; } - - if (!d2d_array_reserve((void **)&effect->inputs, &effect->inputs_size, - count, sizeof(*effect->inputs))) + else { - ERR("Failed to resize inputs array.\n"); - return E_OUTOFMEMORY; - } + if (!d2d_array_reserve((void **)&effect->inputs, &effect->inputs_size, + count, sizeof(*effect->inputs))) + { + ERR("Failed to resize inputs array.\n"); + return E_OUTOFMEMORY; + }
- memset(&effect->inputs[effect->input_count], 0, sizeof(*effect->inputs) * (count - effect->input_count)); + memset(&effect->inputs[effect->input_count], 0, sizeof(*effect->inputs) * (count - effect->input_count)); + } effect->input_count = count;
- return S_OK; + if (initialized) + { + ID2D1TransformGraph_Release(&effect->graph->ID2D1TransformGraph_iface); + effect->graph = NULL; + + if (!(effect->graph = calloc(1, sizeof(*effect->graph)))) + return E_OUTOFMEMORY; + d2d_transform_graph_init(effect->graph); + + if (FAILED(hr = ID2D1EffectImpl_SetGraph(effect->impl, &effect->graph->ID2D1TransformGraph_iface))) + WARN("Failed to set a new transform graph, hr %#lx.\n", hr); + } + + return hr; }
static HRESULT STDMETHODCALLTYPE d2d_effect_SetInputCount(ID2D1Effect *iface, UINT32 count) diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 6586f61bc6a..efa4da54fd2 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -11166,7 +11166,12 @@ static HRESULT STDMETHODCALLTYPE effect_impl_PrepareForRender(ID2D1EffectImpl *i
static HRESULT STDMETHODCALLTYPE effect_impl_SetGraph(ID2D1EffectImpl *iface, ID2D1TransformGraph *graph) { - return E_NOTIMPL; + struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl(iface); + + ID2D1TransformGraph_Release(effect_impl->transform_graph); + ID2D1TransformGraph_AddRef(effect_impl->transform_graph = graph); + + return S_OK; }
static const ID2D1EffectImplVtbl effect_impl_vtbl = @@ -11496,6 +11501,13 @@ static void test_effect_register(BOOL d3d11) (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(integer == 3, "Unexpected data %u.\n", integer); + hr = ID2D1Effect_SetInputCount(effect, 4); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_INPUTS, D2D1_PROPERTY_TYPE_ARRAY, + (BYTE *)&integer, sizeof(integer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(integer == 3, "Unexpected data %u.\n", integer); + ID2D1Effect_Release(effect);
hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
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=142208
Your paranoid android.
=== debian11b (64 bit WoW report) ===
Report validation errors: mshtml:events has no test summary line (early exit of the main process?) mshtml:events has unaccounted for todo messages mshtml:events returned a non-zero exit code despite reporting no failures