[PATCH 1/3] d2d1: Support registering builtin effect.

Ziqing Hui zhui at codeweavers.com
Mon Jun 20 22:17:06 CDT 2022


Signed-off-by: Ziqing Hui <zhui at codeweavers.com>
---
 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 <assert.h>
 #include <limits.h>
@@ -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, &reg->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




More information about the wine-devel mailing list