From: Ziqing Hui Subject: [PATCH 1/3] d2d1: Support registering builtin effect. Message-Id: <20220621031708.2241872-1-zhui@codeweavers.com> Date: Tue, 21 Jun 2022 11:17:06 +0800 Signed-off-by: Ziqing Hui --- dlls/d2d1/d2d1_private.h | 44 +++++++++++++++++++++++-- dlls/d2d1/effect.c | 69 ++++++++++++++++++++++++++++++---------- dlls/d2d1/factory.c | 44 ++----------------------- 3 files changed, 96 insertions(+), 61 deletions(-) diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 9be553c72d8..75a9c4f9366 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -20,6 +20,7 @@ #define __WINE_D2D1_PRIVATE_H #include "wine/debug.h" +#include "wine/list.h" #include #include @@ -61,6 +62,22 @@ struct d2d_settings }; extern struct d2d_settings d2d_settings DECLSPEC_HIDDEN; +struct d2d_factory +{ + ID2D1Factory3 ID2D1Factory3_iface; + ID2D1Multithread ID2D1Multithread_iface; + LONG refcount; + + ID3D10Device1 *device; + + float dpi_x; + float dpi_y; + + struct list effects; + + CRITICAL_SECTION cs; +}; + struct d2d_clip_stack { D2D1_RECT_F *stack; @@ -602,12 +619,30 @@ struct d2d_effect_context void d2d_effect_context_init(struct d2d_effect_context *effect_context, struct d2d_device_context *device_context) DECLSPEC_HIDDEN; -struct d2d_effect_info +struct d2d_effect_property { - const CLSID *clsid; + 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; + BOOL is_builtin; + PD2D1_EFFECT_FACTORY factory; + UINT32 registration_count; + CLSID id; + UINT32 default_input_count; UINT32 min_inputs; UINT32 max_inputs; + + struct d2d_effect_property *properties; + size_t property_size; + size_t property_count; }; struct d2d_effect @@ -616,7 +651,9 @@ struct d2d_effect ID2D1Image ID2D1Image_iface; LONG refcount; - const struct d2d_effect_info *info; + CLSID id; + UINT32 min_inputs; + UINT32 max_inputs; struct d2d_effect_context *effect_context; ID2D1Image **inputs; @@ -626,6 +663,7 @@ struct d2d_effect HRESULT d2d_effect_init(struct d2d_effect *effect, struct d2d_effect_context *effect_context, const CLSID *effect_id) DECLSPEC_HIDDEN; +HRESULT d2d_register_builtin_effects(struct d2d_factory *factory) DECLSPEC_HIDDEN; static inline BOOL d2d_array_reserve(void **elements, size_t *capacity, size_t count, size_t size) { diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index f5d5494c67a..a87fedd0742 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -20,14 +20,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(d2d); -static const struct d2d_effect_info builtin_effects[] = +struct d2d_builtin_effect_registration { - {&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}, + const CLSID *id; + PD2D1_EFFECT_FACTORY factory; + UINT32 default_input_count; + UINT32 min_inputs; + UINT32 max_inputs; +}; + +static const struct d2d_builtin_effect_registration builtin_effects[] = +{ + {&CLSID_D2D12DAffineTransform, NULL, 1, 1, 1}, + {&CLSID_D2D13DPerspectiveTransform, NULL, 1, 1, 1}, + {&CLSID_D2D1Composite, NULL, 2, 1, 0xffffffff}, + {&CLSID_D2D1Crop, NULL, 1, 1, 1}, + {&CLSID_D2D1Shadow, NULL, 1, 1, 1}, + {&CLSID_D2D1Grayscale, NULL, 1, 1, 1}, }; static inline struct d2d_effect_context *impl_from_ID2D1EffectContext(ID2D1EffectContext *iface) @@ -554,21 +563,21 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_GetValue(ID2D1Effect *iface, UINT32 { case D2D1_PROPERTY_CLSID: if ((type != D2D1_PROPERTY_TYPE_UNKNOWN && type != D2D1_PROPERTY_TYPE_CLSID) - || value_size != sizeof(*effect->info->clsid)) + || value_size != sizeof(effect->id)) return E_INVALIDARG; - src = effect->info->clsid; + src = &effect->id; break; case D2D1_PROPERTY_MIN_INPUTS: if ((type != D2D1_PROPERTY_TYPE_UNKNOWN && type != D2D1_PROPERTY_TYPE_UINT32) - || value_size != sizeof(effect->info->min_inputs)) + || value_size != sizeof(effect->min_inputs)) return E_INVALIDARG; - src = &effect->info->min_inputs; + src = &effect->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)) + || value_size != sizeof(effect->max_inputs)) return E_INVALIDARG; - src = &effect->info->max_inputs; + src = &effect->max_inputs; break; default: if (index < D2D1_PROPERTY_CLSID) @@ -619,7 +628,7 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_SetInputCount(ID2D1Effect *iface, UI TRACE("iface %p, count %u.\n", iface, count); - if (count < effect->info->min_inputs || count > effect->info->max_inputs) + if (count < effect->min_inputs || count > effect->max_inputs) return E_INVALIDARG; if (count == effect->input_count) return S_OK; @@ -760,10 +769,11 @@ HRESULT d2d_effect_init(struct d2d_effect *effect, struct d2d_effect_context *ef for (i = 0; i < ARRAY_SIZE(builtin_effects); ++i) { - if (IsEqualGUID(effect_id, builtin_effects[i].clsid)) + if (IsEqualGUID(effect_id, &builtin_effects[i].id)) { - effect->info = &builtin_effects[i]; - d2d_effect_SetInputCount(&effect->ID2D1Effect_iface, effect->info->default_input_count); + effect->min_inputs = builtin_effects[i].min_inputs; + effect->max_inputs = 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; @@ -773,3 +783,28 @@ HRESULT d2d_effect_init(struct d2d_effect *effect, struct d2d_effect_context *ef WARN("Unsupported effect clsid %s.\n", debugstr_guid(effect_id)); return E_FAIL; } + +HRESULT d2d_register_builtin_effects(struct d2d_factory *factory) +{ + struct d2d_effect_registration *reg; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(builtin_effects); ++i) + { + const struct d2d_builtin_effect_registration *builtin_reg = &builtin_effects[i]; + + if (!(reg = calloc(1, sizeof(*reg)))) + return E_OUTOFMEMORY; + + reg->is_builtin = TRUE; + reg->factory = builtin_reg->factory; + reg->registration_count = 1; + reg->id = *builtin_reg->id; + reg->default_input_count = builtin_reg->default_input_count; + reg->min_inputs = builtin_reg->min_inputs; + reg->max_inputs = builtin_reg->max_inputs; + list_add_tail(&factory->effects, ®->entry); + } + + return S_OK; +} diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 5c79d1791ff..7eec52c01a1 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -20,7 +20,6 @@ #include "d2d1_private.h" #include "xmllite.h" -#include "wine/list.h" WINE_DECLARE_DEBUG_CHANNEL(winediag); WINE_DEFAULT_DEBUG_CHANNEL(d2d); @@ -30,29 +29,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; - PD2D1_EFFECT_FACTORY factory; - UINT32 registration_count; - CLSID id; - - UINT32 input_count; - - struct d2d_effect_property *properties; - size_t property_size; - size_t property_count; -}; - static void d2d_effect_registration_cleanup(struct d2d_effect_registration *reg) { size_t i; @@ -66,22 +42,6 @@ static void d2d_effect_registration_cleanup(struct d2d_effect_registration *reg) free(reg); } -struct d2d_factory -{ - ID2D1Factory3 ID2D1Factory3_iface; - ID2D1Multithread ID2D1Multithread_iface; - LONG refcount; - - ID3D10Device1 *device; - - float dpi_x; - float dpi_y; - - struct list effects; - - CRITICAL_SECTION cs; -}; - static inline struct d2d_factory *impl_from_ID2D1Factory3(ID2D1Factory3 *iface) { return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Factory3_iface); @@ -916,6 +876,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Facto property->set_function = bindings[i].setFunction; } + effect->is_builtin = FALSE; effect->registration_count = 1; effect->id = *effect_id; effect->factory = effect_factory; @@ -960,7 +921,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_UnregisterEffect(ID2D1Factory3 *ifa LIST_FOR_EACH_ENTRY(effect, &factory->effects, struct d2d_effect_registration, entry) { - if (IsEqualGUID(effect_id, &effect->id)) + if (!effect->is_builtin && IsEqualGUID(effect_id, &effect->id)) { if (!--effect->registration_count) { @@ -1126,6 +1087,7 @@ static void d2d_factory_init(struct d2d_factory *factory, D2D1_FACTORY_TYPE fact factory->refcount = 1; d2d_factory_reload_sysmetrics(factory); list_init(&factory->effects); + d2d_register_builtin_effects(factory); InitializeCriticalSection(&factory->cs); } -- 2.25.1