On Thu, 5 Aug 2021 at 10:06, Ziqing Hui zhui@codeweavers.com wrote:
+static void d2d_effect_cleanup(struct d2d_effect *effect) +{
- heap_free(effect->inputs);
- ID2D1Factory_Release(effect->factory);
+}
[...]
-void d2d_effect_init(struct d2d_effect *effect, ID2D1Factory *factory) +HRESULT d2d_effect_init(struct d2d_effect *effect, ID2D1Factory *factory) { effect->ID2D1Effect_iface.lpVtbl = &d2d_effect_vtbl; effect->ID2D1Image_iface.lpVtbl = &d2d_effect_image_vtbl; effect->refcount = 1;
- ID2D1Factory_AddRef(effect->factory = factory);
- effect->input_count = 1;
- if (!d2d_array_reserve((void **)&effect->inputs, &effect->inputs_size,
effect->input_count, sizeof(*effect->inputs)))
goto fail;
- memset(effect->inputs, 0, sizeof(*effect->inputs) * effect->inputs_size);
- return S_OK;
+fail:
- d2d_effect_cleanup(effect);
- return E_OUTOFMEMORY;
}
If d2d_array_reserve() were to fail, we'd only need to release the factory reference. (And if we called d2d_array_reserve() before ID2D1Factory_AddRef(), we could avoid that too.) Calling heap_free() on a NULL "effect->inputs" works fine of course, but it becomes more complicated in patch 4/5 of this series. In principle we only ever want to call _cleanup() functions on fully initialised objects.
Note that we only need to memset() "effect->input_count" inputs here; that's what we do for SetInputCount() as well in patch 3/5. And in fact, once we have SetInputCount() in patch 3/5, we can just call it from d2d_effect_init() to set the initial input count.