On Thu, 5 Aug 2021 at 10:06, Ziqing Hui <zhui(a)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.