Module: wine Branch: master Commit: 727878630b23ec046a91e4ce20d3686975c85a76 URL: https://source.winehq.org/git/wine.git/?a=commit;h=727878630b23ec046a91e4ce2...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Sun Jun 26 13:20:23 2022 +0300
d2d1/effect: Reserve a buffer for property values.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
---
dlls/d2d1/factory.c | 130 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 100 insertions(+), 30 deletions(-)
diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 5c79d1791ff..0cb4b5df7d6 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -34,11 +34,30 @@ struct d2d_effect_property { WCHAR *name; D2D1_PROPERTY_TYPE type; - BYTE *value; + union + { + size_t offset; + void *ptr; + } data; + UINT32 size; PD2D1_PROPERTY_SET_FUNCTION set_function; PD2D1_PROPERTY_GET_FUNCTION get_function; };
+struct d2d_effect_properties +{ + struct d2d_effect_property *properties; + size_t offset; + size_t size; + size_t count; + struct + { + BYTE *ptr; + size_t size; + size_t count; + } data; +}; + struct d2d_effect_registration { struct list entry; @@ -47,22 +66,28 @@ struct d2d_effect_registration CLSID id;
UINT32 input_count; - - struct d2d_effect_property *properties; - size_t property_size; - size_t property_count; + struct d2d_effect_properties properties; };
-static void d2d_effect_registration_cleanup(struct d2d_effect_registration *reg) +static void d2d_effect_properties_cleanup(struct d2d_effect_properties *props) { + struct d2d_effect_property *p; size_t i;
- for (i = 0; i < reg->property_count; ++i) + for (i = 0; i < props->count; ++i) { - free(reg->properties[i].name); - free(reg->properties[i].value); + p = &props->properties[i]; + free(p->name); + if (p->type == D2D1_PROPERTY_TYPE_STRING) + free(p->data.ptr); } - free(reg->properties); + free(props->properties); + free(props->data.ptr); +} + +static void d2d_effect_registration_cleanup(struct d2d_effect_registration *reg) +{ + d2d_effect_properties_cleanup(®->properties); free(reg); }
@@ -731,32 +756,80 @@ static struct d2d_effect_property * parse_effect_get_property(const struct d2d_e { unsigned int i;
- for (i = 0; i < effect->property_count; ++i) + for (i = 0; i < effect->properties.count; ++i) { - if (!wcscmp(name, effect->properties[i].name)) - return &effect->properties[i]; + if (!wcscmp(name, effect->properties.properties[i].name)) + return &effect->properties.properties[i]; }
return NULL; }
-static HRESULT parse_effect_add_property(struct d2d_effect_registration *effect, WCHAR *name, - D2D1_PROPERTY_TYPE type, BYTE *value) +static HRESULT parse_effect_add_property(struct d2d_effect_properties *props, const WCHAR *name, + D2D1_PROPERTY_TYPE type, const WCHAR *value) { - struct d2d_effect_property *property; + static const UINT32 sizes[] = + { + 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_IN32 */ + sizeof(float), /* D2D1_PROPERTY_TYPE_FLOAT */ + 2 * sizeof(float), /* D2D1_PROPERTY_TYPE_VECTOR2 */ + 3 * sizeof(float), /* D2D1_PROPERTY_TYPE_VECTOR3 */ + 4 * sizeof(float), /* D2D1_PROPERTY_TYPE_VECTOR4 */ + 0, /* FIXME: D2D1_PROPERTY_TYPE_BLOB */ + sizeof(void *), /* D2D1_PROPERTY_TYPE_IUNKNOWN */ + sizeof(UINT32), /* D2D1_PROPERTY_TYPE_ENUM */ + 0, /* FIXME: D2D1_PROPERTY_TYPE_ARRAY */ + sizeof(CLSID), /* D2D1_PROPERTY_TYPE_CLSID */ + 6 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_3X2 */ + 12 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_4X3 */ + 16 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_4X4 */ + 20 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_5X4 */ + sizeof(void *), /* D2D1_PROPERTY_TYPE_COLOR_CONTEXT */ + }; + struct d2d_effect_property *p; + + assert(type >= D2D1_PROPERTY_TYPE_STRING && type <= D2D1_PROPERTY_TYPE_COLOR_CONTEXT); + + if (type == D2D1_PROPERTY_TYPE_BLOB || type == D2D1_PROPERTY_TYPE_ARRAY) + { + FIXME("Ignoring property %s of type %u.\n", wine_dbgstr_w(name), type); + return S_OK; + }
- if (!d2d_array_reserve((void **)&effect->properties, &effect->property_size, - effect->property_count + 1, sizeof(*effect->properties))) + if (!d2d_array_reserve((void **)&props->properties, &props->size, props->count + 1, + sizeof(*props->properties))) { return E_OUTOFMEMORY; }
- property = &effect->properties[effect->property_count++]; - property->name = name; - property->type = type; - property->value = value; - property->set_function = NULL; - property->get_function = NULL; + /* TODO: we could save some space for properties that have both getter and setter. */ + if (!d2d_array_reserve((void **)&props->data.ptr, &props->data.size, + props->data.size + sizes[type], sizeof(*props->data.ptr))) + { + return E_OUTOFMEMORY; + } + + p = &props->properties[props->count++]; + p->name = wcsdup(name); + p->type = type; + if (p->type == D2D1_PROPERTY_TYPE_STRING) + { + p->data.ptr = value ? wcsdup(value) : NULL; + p->size = value ? (wcslen(value) + 1) * sizeof(WCHAR) : 0; + } + else + { + p->data.offset = props->offset; + p->size = sizes[type]; + props->offset += p->size; + /* FIXME: convert and write initial value */ + } + p->set_function = NULL; + p->get_function = NULL;
return S_OK; } @@ -792,13 +865,10 @@ static HRESULT parse_effect_property(IXmlReader *reader, struct d2d_effect_regis }
if (SUCCEEDED(hr)) - hr = parse_effect_add_property(effect, name, type, (BYTE *)value); + hr = parse_effect_add_property(&effect->properties, name, type, value);
- if (FAILED(hr)) - { - free(value); - free(name); - } + free(value); + free(name);
return hr; }