Nikolay Sivov : d2d1/effect: Reserve a buffer for property values.
Alexandre Julliard
julliard at winehq.org
Mon Jun 27 16:12:51 CDT 2022
Module: wine
Branch: master
Commit: 727878630b23ec046a91e4ce20d3686975c85a76
URL: https://source.winehq.org/git/wine.git/?a=commit;h=727878630b23ec046a91e4ce20d3686975c85a76
Author: Nikolay Sivov <nsivov at 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 at 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;
}
More information about the wine-cvs
mailing list