mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 09:21:14 +00:00
d2d1/effect: Keep builtin effects in the same list as the custom once.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
parent
ffab990bd6
commit
97abb6d2ba
4 changed files with 78 additions and 49 deletions
|
@ -643,14 +643,20 @@ struct d2d_effect_registration
|
||||||
struct list entry;
|
struct list entry;
|
||||||
PD2D1_EFFECT_FACTORY factory;
|
PD2D1_EFFECT_FACTORY factory;
|
||||||
UINT32 registration_count;
|
UINT32 registration_count;
|
||||||
|
BOOL builtin;
|
||||||
CLSID id;
|
CLSID id;
|
||||||
|
|
||||||
UINT32 input_count;
|
UINT32 input_count;
|
||||||
|
UINT32 default_input_count;
|
||||||
struct d2d_effect_properties properties;
|
struct d2d_effect_properties properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct d2d_factory;
|
||||||
|
void d2d_effects_init_builtins(struct d2d_factory *factory) DECLSPEC_HIDDEN;
|
||||||
struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory *factory,
|
struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory *factory,
|
||||||
const GUID *effect_id) DECLSPEC_HIDDEN;
|
const GUID *effect_id) DECLSPEC_HIDDEN;
|
||||||
|
void d2d_factory_register_effect(struct d2d_factory *factory,
|
||||||
|
struct d2d_effect_registration *effect) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
struct d2d_transform_graph
|
struct d2d_transform_graph
|
||||||
{
|
{
|
||||||
|
|
|
@ -229,6 +229,33 @@ static const struct d2d_effect_info builtin_effects[] =
|
||||||
{&CLSID_D2D1Grayscale, 1, 1, 1},
|
{&CLSID_D2D1Grayscale, 1, 1, 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void d2d_effects_init_builtins(struct d2d_factory *factory)
|
||||||
|
{
|
||||||
|
struct d2d_effect_registration *effect;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Same syntax is used for value and default values. */
|
/* Same syntax is used for value and default values. */
|
||||||
static HRESULT d2d_effect_parse_float_array(D2D1_PROPERTY_TYPE type, const WCHAR *value,
|
static HRESULT d2d_effect_parse_float_array(D2D1_PROPERTY_TYPE type, const WCHAR *value,
|
||||||
float *vec)
|
float *vec)
|
||||||
|
@ -1539,31 +1566,14 @@ static void d2d_effect_init_properties_vtbls(struct d2d_effect *effect)
|
||||||
HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effect_id,
|
HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effect_id,
|
||||||
ID2D1Effect **effect)
|
ID2D1Effect **effect)
|
||||||
{
|
{
|
||||||
const struct d2d_effect_info *builtin = NULL;
|
|
||||||
struct d2d_effect_context *effect_context;
|
struct d2d_effect_context *effect_context;
|
||||||
const struct d2d_effect_registration *reg;
|
const struct d2d_effect_registration *reg;
|
||||||
unsigned int i, default_input_count;
|
|
||||||
struct d2d_transform_graph *graph;
|
struct d2d_transform_graph *graph;
|
||||||
PD2D1_EFFECT_FACTORY factory;
|
|
||||||
struct d2d_effect *object;
|
struct d2d_effect *object;
|
||||||
WCHAR clsidW[39];
|
WCHAR clsidW[39];
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (!(reg = d2d_factory_get_registered_effect(context->factory, effect_id)))
|
if (!(reg = d2d_factory_get_registered_effect(context->factory, effect_id)))
|
||||||
{
|
|
||||||
for (i = 0; i < ARRAY_SIZE(builtin_effects); ++i)
|
|
||||||
{
|
|
||||||
const struct d2d_effect_info *info = &builtin_effects[i];
|
|
||||||
|
|
||||||
if (IsEqualGUID(effect_id, info->clsid))
|
|
||||||
{
|
|
||||||
builtin = info;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!reg && !builtin)
|
|
||||||
{
|
{
|
||||||
WARN("Effect id %s not found.\n", wine_dbgstr_guid(effect_id));
|
WARN("Effect id %s not found.\n", wine_dbgstr_guid(effect_id));
|
||||||
return D2DERR_EFFECT_IS_NOT_REGISTERED;
|
return D2DERR_EFFECT_IS_NOT_REGISTERED;
|
||||||
|
@ -1594,41 +1604,17 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec
|
||||||
object->graph = graph;
|
object->graph = graph;
|
||||||
|
|
||||||
/* Create properties */
|
/* Create properties */
|
||||||
StringFromGUID2(effect_id, clsidW, ARRAY_SIZE(clsidW));
|
|
||||||
if (builtin)
|
|
||||||
{
|
|
||||||
WCHAR max_inputs[32];
|
|
||||||
swprintf(max_inputs, ARRAY_SIZE(max_inputs), L"%lu", builtin->max_inputs);
|
|
||||||
d2d_effect_properties_add(&object->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS,
|
|
||||||
D2D1_PROPERTY_TYPE_UINT32, L"1");
|
|
||||||
d2d_effect_properties_add(&object->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS,
|
|
||||||
D2D1_PROPERTY_TYPE_UINT32, max_inputs);
|
|
||||||
|
|
||||||
default_input_count = builtin->default_input_count;
|
|
||||||
|
|
||||||
factory = builtin_factory_stub;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
d2d_effect_duplicate_properties(&object->properties, ®->properties);
|
d2d_effect_duplicate_properties(&object->properties, ®->properties);
|
||||||
d2d_effect_properties_add(&object->properties, L"MinInputs", D2D1_PROPERTY_MIN_INPUTS,
|
|
||||||
D2D1_PROPERTY_TYPE_UINT32, L"1");
|
|
||||||
d2d_effect_properties_add(&object->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS,
|
|
||||||
D2D1_PROPERTY_TYPE_UINT32, L"1" /* FIXME */);
|
|
||||||
|
|
||||||
default_input_count = 1;
|
|
||||||
|
|
||||||
factory = reg->factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
StringFromGUID2(effect_id, clsidW, ARRAY_SIZE(clsidW));
|
||||||
d2d_effect_properties_add(&object->properties, L"CLSID", D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_CLSID, clsidW);
|
d2d_effect_properties_add(&object->properties, L"CLSID", D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_CLSID, clsidW);
|
||||||
d2d_effect_properties_add(&object->properties, L"Cached", D2D1_PROPERTY_CACHED, D2D1_PROPERTY_TYPE_BOOL, L"false");
|
d2d_effect_properties_add(&object->properties, L"Cached", D2D1_PROPERTY_CACHED, D2D1_PROPERTY_TYPE_BOOL, L"false");
|
||||||
d2d_effect_properties_add(&object->properties, L"Precision", D2D1_PROPERTY_PRECISION, D2D1_PROPERTY_TYPE_ENUM, L"0");
|
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_init_properties_vtbls(object);
|
||||||
|
|
||||||
d2d_effect_SetInputCount(&object->ID2D1Effect_iface, default_input_count);
|
d2d_effect_SetInputCount(&object->ID2D1Effect_iface, reg->default_input_count);
|
||||||
|
|
||||||
if (FAILED(hr = factory((IUnknown **)&object->impl)))
|
if (FAILED(hr = reg->factory((IUnknown **)&object->impl)))
|
||||||
{
|
{
|
||||||
WARN("Failed to create implementation object, hr %#lx.\n", hr);
|
WARN("Failed to create implementation object, hr %#lx.\n", hr);
|
||||||
ID2D1Effect_Release(&object->ID2D1Effect_iface);
|
ID2D1Effect_Release(&object->ID2D1Effect_iface);
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct d2d_factory
|
||||||
float dpi_y;
|
float dpi_y;
|
||||||
|
|
||||||
struct list effects;
|
struct list effects;
|
||||||
|
INIT_ONCE init_builtins;
|
||||||
|
|
||||||
CRITICAL_SECTION cs;
|
CRITICAL_SECTION cs;
|
||||||
};
|
};
|
||||||
|
@ -67,12 +68,31 @@ static inline struct d2d_factory *impl_from_ID2D1Multithread(ID2D1Multithread *i
|
||||||
return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Multithread_iface);
|
return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Multithread_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL WINAPI d2d_factory_builtins_initonce(INIT_ONCE *once, void *param, void **context)
|
||||||
|
{
|
||||||
|
d2d_effects_init_builtins(param);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void d2d_factory_init_builtin_effects(struct d2d_factory *factory)
|
||||||
|
{
|
||||||
|
InitOnceExecuteOnce(&factory->init_builtins, d2d_factory_builtins_initonce, factory, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void d2d_factory_register_effect(struct d2d_factory *factory, struct d2d_effect_registration *effect)
|
||||||
|
{
|
||||||
|
list_add_tail(&factory->effects, &effect->entry);
|
||||||
|
}
|
||||||
|
|
||||||
struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory *iface,
|
struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory *iface,
|
||||||
const GUID *id)
|
const GUID *id)
|
||||||
{
|
{
|
||||||
const struct d2d_factory *factory = unsafe_impl_from_ID2D1Factory(iface);
|
struct d2d_factory *factory = unsafe_impl_from_ID2D1Factory(iface);
|
||||||
struct d2d_effect_registration *reg;
|
struct d2d_effect_registration *reg;
|
||||||
|
|
||||||
|
d2d_effects_init_builtins(factory);
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(reg, &factory->effects, struct d2d_effect_registration, entry)
|
LIST_FOR_EACH_ENTRY(reg, &factory->effects, struct d2d_effect_registration, entry)
|
||||||
{
|
{
|
||||||
if (IsEqualGUID(id, ®->id)) return reg;
|
if (IsEqualGUID(id, ®->id)) return reg;
|
||||||
|
@ -884,10 +904,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Facto
|
||||||
TRACE("iface %p, effect_id %s, property_xml %p, bindings %p, binding_count %u, effect_factory %p.\n",
|
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);
|
iface, debugstr_guid(effect_id), property_xml, bindings, binding_count, effect_factory);
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(effect, &factory->effects, struct d2d_effect_registration, entry)
|
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))
|
if (IsEqualGUID(effect_id, &effect->id))
|
||||||
{
|
{
|
||||||
|
if (effect->builtin) return E_INVALIDARG;
|
||||||
++effect->registration_count;
|
++effect->registration_count;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -948,7 +971,12 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Facto
|
||||||
effect->registration_count = 1;
|
effect->registration_count = 1;
|
||||||
effect->id = *effect_id;
|
effect->id = *effect_id;
|
||||||
effect->factory = effect_factory;
|
effect->factory = effect_factory;
|
||||||
list_add_tail(&factory->effects, &effect->entry);
|
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;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -987,10 +1015,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_UnregisterEffect(ID2D1Factory3 *ifa
|
||||||
|
|
||||||
TRACE("iface %p, effect_id %s.\n", iface, debugstr_guid(effect_id));
|
TRACE("iface %p, effect_id %s.\n", iface, debugstr_guid(effect_id));
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(effect, &factory->effects, struct d2d_effect_registration, entry)
|
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))
|
if (IsEqualGUID(effect_id, &effect->id))
|
||||||
{
|
{
|
||||||
|
if (effect->builtin) break;
|
||||||
if (!--effect->registration_count)
|
if (!--effect->registration_count)
|
||||||
{
|
{
|
||||||
list_remove(&effect->entry);
|
list_remove(&effect->entry);
|
||||||
|
@ -1156,6 +1187,7 @@ static void d2d_factory_init(struct d2d_factory *factory, D2D1_FACTORY_TYPE fact
|
||||||
d2d_factory_reload_sysmetrics(factory);
|
d2d_factory_reload_sysmetrics(factory);
|
||||||
list_init(&factory->effects);
|
list_init(&factory->effects);
|
||||||
InitializeCriticalSection(&factory->cs);
|
InitializeCriticalSection(&factory->cs);
|
||||||
|
InitOnceInitialize(&factory->init_builtins);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI D2D1CreateFactory(D2D1_FACTORY_TYPE factory_type, REFIID iid,
|
HRESULT WINAPI D2D1CreateFactory(D2D1_FACTORY_TYPE factory_type, REFIID iid,
|
||||||
|
|
|
@ -10848,6 +10848,11 @@ static void test_effect_register(BOOL d3d11)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Using builtin effect CLSID. */
|
||||||
|
hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_D2D1Crop, effect_xml_a, NULL,
|
||||||
|
0, effect_impl_create);
|
||||||
|
ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
|
||||||
/* Register effect once */
|
/* Register effect once */
|
||||||
for (i = 0; i < ARRAY_SIZE(xml_tests); ++i)
|
for (i = 0; i < ARRAY_SIZE(xml_tests); ++i)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue