mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-02 15:43:38 +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
|
@ -643,14 +643,20 @@ struct d2d_effect_registration
|
|||
struct list entry;
|
||||
PD2D1_EFFECT_FACTORY factory;
|
||||
UINT32 registration_count;
|
||||
BOOL builtin;
|
||||
CLSID id;
|
||||
|
||||
UINT32 input_count;
|
||||
UINT32 default_input_count;
|
||||
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,
|
||||
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
|
||||
{
|
||||
|
|
|
@ -229,6 +229,33 @@ static const struct d2d_effect_info builtin_effects[] =
|
|||
{&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. */
|
||||
static HRESULT d2d_effect_parse_float_array(D2D1_PROPERTY_TYPE type, const WCHAR *value,
|
||||
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,
|
||||
ID2D1Effect **effect)
|
||||
{
|
||||
const struct d2d_effect_info *builtin = NULL;
|
||||
struct d2d_effect_context *effect_context;
|
||||
const struct d2d_effect_registration *reg;
|
||||
unsigned int i, default_input_count;
|
||||
struct d2d_transform_graph *graph;
|
||||
PD2D1_EFFECT_FACTORY factory;
|
||||
struct d2d_effect *object;
|
||||
WCHAR clsidW[39];
|
||||
HRESULT hr;
|
||||
|
||||
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));
|
||||
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;
|
||||
|
||||
/* 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_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"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_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);
|
||||
ID2D1Effect_Release(&object->ID2D1Effect_iface);
|
||||
|
|
|
@ -48,6 +48,7 @@ struct d2d_factory
|
|||
float dpi_y;
|
||||
|
||||
struct list effects;
|
||||
INIT_ONCE init_builtins;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
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;
|
||||
|
||||
d2d_effects_init_builtins(factory);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(reg, &factory->effects, struct d2d_effect_registration, entry)
|
||||
{
|
||||
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",
|
||||
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 (effect->builtin) return E_INVALIDARG;
|
||||
++effect->registration_count;
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -948,7 +971,12 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_RegisterEffectFromStream(ID2D1Facto
|
|||
effect->registration_count = 1;
|
||||
effect->id = *effect_id;
|
||||
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;
|
||||
}
|
||||
|
@ -987,10 +1015,13 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_UnregisterEffect(ID2D1Factory3 *ifa
|
|||
|
||||
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 (effect->builtin) break;
|
||||
if (!--effect->registration_count)
|
||||
{
|
||||
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);
|
||||
list_init(&factory->effects);
|
||||
InitializeCriticalSection(&factory->cs);
|
||||
InitOnceInitialize(&factory->init_builtins);
|
||||
}
|
||||
|
||||
HRESULT WINAPI D2D1CreateFactory(D2D1_FACTORY_TYPE factory_type, REFIID iid,
|
||||
|
|
|
@ -10848,6 +10848,11 @@ static void test_effect_register(BOOL d3d11)
|
|||
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 */
|
||||
for (i = 0; i < ARRAY_SIZE(xml_tests); ++i)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue