From: Ziqing Hui zhui@codeweavers.com
--- dlls/d2d1/tests/d2d1.c | 55 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 665c3200e21..caedfdd552e 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -12024,6 +12024,7 @@ static void test_registered_effects(BOOL d3d11)
static void test_transform_graph(BOOL d3d11) { + UINT i, effect_input_count, transform_input_count; ID2D1OffsetTransform *offset_transform = NULL; ID2D1BlendTransform *blend_transform = NULL; D2D1_BLEND_DESCRIPTION blend_desc = {0}; @@ -12033,7 +12034,6 @@ static void test_transform_graph(BOOL d3d11) ID2D1Factory1 *factory; POINT point = {0 ,0}; ID2D1Effect *effect; - UINT i, count; HRESULT hr;
const D2D1_PROPERTY_BINDING binding[] = @@ -12090,6 +12090,15 @@ static void test_transform_graph(BOOL d3d11) hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)blend_transform); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ /* Clear nodes */ + hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ID2D1TransformGraph_Clear(graph); + hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + /* Connect nodes which are both un-added */ ID2D1TransformGraph_Clear(graph); hr = ID2D1TransformGraph_ConnectNode(graph, @@ -12112,13 +12121,13 @@ static void test_transform_graph(BOOL d3d11) ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr);
/* Connect nodes */ + transform_input_count = ID2D1BlendTransform_GetInputCount(blend_transform); ID2D1TransformGraph_Clear(graph); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)offset_transform); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)blend_transform); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - count = ID2D1BlendTransform_GetInputCount(blend_transform); - for (i = 0; i < count; ++i) + for (i = 0; i < transform_input_count; ++i) { hr = ID2D1TransformGraph_ConnectNode(graph, (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, i); @@ -12127,7 +12136,45 @@ static void test_transform_graph(BOOL d3d11)
/* Connect node to out-of-bounds index */ hr = ID2D1TransformGraph_ConnectNode(graph, - (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, count); + (ID2D1TransformNode *)offset_transform, (ID2D1TransformNode *)blend_transform, transform_input_count); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + + /* Set output */ + hr = ID2D1TransformGraph_SetOutputNode(graph, (ID2D1TransformNode *)blend_transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_SetOutputNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Single node transform graph */ + effect_input_count = ID2D1TransformGraph_GetInputCount(graph); + + transform_input_count = ID2D1BlendTransform_GetInputCount(blend_transform); + ok(transform_input_count != effect_input_count, "Input count should not be equal.\n"); + hr = ID2D1TransformGraph_SetSingleTransformNode(graph, (ID2D1TransformNode *)blend_transform); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)blend_transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); + + transform_input_count = ID2D1OffsetTransform_GetInputCount(offset_transform); + ok(transform_input_count == effect_input_count, "Input count should be equal.\n"); + hr = ID2D1TransformGraph_SetSingleTransformNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)offset_transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_RemoveNode(graph, (ID2D1TransformNode *)blend_transform); + ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got unexpected hr %#lx.\n", hr); + + /* Connect effect inputs to node inputs */ + transform_input_count = ID2D1BlendTransform_GetInputCount(blend_transform); + hr = ID2D1TransformGraph_AddNode(graph, (ID2D1TransformNode *)blend_transform); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_ConnectToEffectInput(graph, 0, (ID2D1TransformNode *)blend_transform, 0); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_ConnectToEffectInput(graph, 0, (ID2D1TransformNode *)blend_transform, transform_input_count); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1TransformGraph_ConnectToEffectInput(graph, effect_input_count, (ID2D1TransformNode *)blend_transform, 0); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
done:
From: Ziqing Hui zhui@codeweavers.com
--- dlls/d2d1/d2d1_private.h | 7 +++++ dlls/d2d1/effect.c | 61 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 5 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 085febe95e7..8de2f6de79f 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -674,10 +674,17 @@ struct d2d_effect_registration * d2d_factory_get_registered_effect(ID2D1Factory void d2d_factory_register_effect(struct d2d_factory *factory, struct d2d_effect_registration *effect) DECLSPEC_HIDDEN;
+struct d2d_transform_node +{ + ID2D1TransformNode *node; + struct list entry; +}; + struct d2d_transform_graph { ID2D1TransformGraph ID2D1TransformGraph_iface; LONG refcount; + struct list nodes; };
struct d2d_effect diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 7b086e20b9b..0ac2d4b3ade 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -20,6 +20,26 @@
WINE_DEFAULT_DEBUG_CHANNEL(d2d);
+static struct d2d_transform_node *d2d_transform_graph_find_node(const struct d2d_transform_graph *graph, + const ID2D1TransformNode *node) +{ + struct d2d_transform_node *entry; + + LIST_FOR_EACH_ENTRY_REV(entry, &graph->nodes, struct d2d_transform_node, entry) + { + if (entry->node == node) + return entry; + } + return NULL; +} + +static void d2d_transform_graph_remove_node(struct d2d_transform_graph *graph, struct d2d_transform_node *node) +{ + list_remove(&node->entry); + ID2D1TransformNode_Release(node->node); + free(node); +} + static inline struct d2d_transform_graph *impl_from_ID2D1TransformGraph(ID2D1TransformGraph *iface) { return CONTAINING_RECORD(iface, struct d2d_transform_graph, ID2D1TransformGraph_iface); @@ -59,7 +79,10 @@ static ULONG STDMETHODCALLTYPE d2d_transform_graph_Release(ID2D1TransformGraph * TRACE("%p decreasing refcount to %lu.\n", iface, refcount);
if (!refcount) + { + ID2D1TransformGraph_Clear(iface); free(graph); + }
return refcount; } @@ -81,16 +104,35 @@ static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetSingleTransformNode(ID2D
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_AddNode(ID2D1TransformGraph *iface, ID2D1TransformNode *node) { - FIXME("iface %p, node %p stub!\n", iface, node); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *entry;
- return E_NOTIMPL; + TRACE("iface %p, node %p.\n", iface, node); + + if (d2d_transform_graph_find_node(graph, node)) + return E_INVALIDARG; + + if (!(entry = calloc(1, sizeof(*entry)))) + return E_OUTOFMEMORY; + + ID2D1TransformNode_AddRef(entry->node = node); + list_add_tail(&graph->nodes, &entry->entry); + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_RemoveNode(ID2D1TransformGraph *iface, ID2D1TransformNode *node) { - FIXME("iface %p, node %p stub!\n", iface, node); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *entry;
- return E_NOTIMPL; + TRACE("iface %p, node %p.\n", iface, node); + + if (!(entry = d2d_transform_graph_find_node(graph, node))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + d2d_transform_graph_remove_node(graph, entry); + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetOutputNode(ID2D1TransformGraph *iface, ID2D1TransformNode *node) @@ -118,7 +160,15 @@ static HRESULT STDMETHODCALLTYPE d2d_transform_graph_ConnectToEffectInput(ID2D1T
static void STDMETHODCALLTYPE d2d_transform_graph_Clear(ID2D1TransformGraph *iface) { - FIXME("iface %p stub!\n", iface); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *entry, *entry2; + + TRACE("iface %p.\n", iface); + + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &graph->nodes, struct d2d_transform_node, entry) + { + d2d_transform_graph_remove_node(graph, entry); + } }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetPassthroughGraph(ID2D1TransformGraph *iface, UINT32 index) @@ -148,6 +198,7 @@ static void d2d_transform_graph_init(struct d2d_transform_graph *graph) { graph->ID2D1TransformGraph_iface.lpVtbl = &d2d_transform_graph_vtbl; graph->refcount = 1; + list_init(&graph->nodes); }
static HRESULT STDMETHODCALLTYPE d2d_effect_impl_QueryInterface(ID2D1EffectImpl *iface, REFIID iid, void **out)
From: Ziqing Hui zhui@codeweavers.com
--- dlls/d2d1/d2d1_private.h | 14 ++++- dlls/d2d1/effect.c | 133 ++++++++++++++++++++++++++++++++++----- 2 files changed, 131 insertions(+), 16 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 8de2f6de79f..8970a4b7f28 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -676,7 +676,16 @@ void d2d_factory_register_effect(struct d2d_factory *factory,
struct d2d_transform_node { - ID2D1TransformNode *node; + BOOL effect_input; + union + { + ID2D1TransformNode *transform; + ID2D1Bitmap *bitmap; + } u; + struct d2d_transform_node **inputs; + UINT32 input_count; + struct d2d_transform_node *output; + UINT32 output_to_index; struct list entry; };
@@ -684,6 +693,9 @@ struct d2d_transform_graph { ID2D1TransformGraph ID2D1TransformGraph_iface; LONG refcount; + struct d2d_transform_node *input_nodes; + UINT32 input_count; + struct d2d_transform_node *output_node; struct list nodes; };
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 0ac2d4b3ade..cdae0455755 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -27,7 +27,7 @@ static struct d2d_transform_node *d2d_transform_graph_find_node(const struct d2d
LIST_FOR_EACH_ENTRY_REV(entry, &graph->nodes, struct d2d_transform_node, entry) { - if (entry->node == node) + if (entry->u.transform == node) return entry; } return NULL; @@ -35,8 +35,26 @@ static struct d2d_transform_node *d2d_transform_graph_find_node(const struct d2d
static void d2d_transform_graph_remove_node(struct d2d_transform_graph *graph, struct d2d_transform_node *node) { + UINT32 i; + + for (i = 0; i < graph->input_count; ++i) + { + if (graph->input_nodes[i].output == node) + graph->input_nodes[i].output = NULL; + } + if (graph->output_node == node) + graph->output_node = NULL; + for (i = 0; i < node->input_count; ++i) + { + if (node->inputs[i]) + node->inputs[i]->output = NULL; + } + if (node->output) + node->output->inputs[node->output_to_index] = NULL; list_remove(&node->entry); - ID2D1TransformNode_Release(node->node); + + ID2D1TransformNode_Release(node->u.transform); + free(node->inputs); free(node); }
@@ -75,12 +93,19 @@ static ULONG STDMETHODCALLTYPE d2d_transform_graph_Release(ID2D1TransformGraph * { struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); ULONG refcount = InterlockedDecrement(&graph->refcount); + UINT32 i;
TRACE("%p decreasing refcount to %lu.\n", iface, refcount);
if (!refcount) { ID2D1TransformGraph_Clear(iface); + for (i = 0; i < graph->input_count; ++i) + { + if (graph->input_nodes[i].u.bitmap) + ID2D1Bitmap_Release(graph->input_nodes[i].u.bitmap); + } + free(graph->input_nodes); free(graph); }
@@ -89,17 +114,39 @@ static ULONG STDMETHODCALLTYPE d2d_transform_graph_Release(ID2D1TransformGraph *
static UINT32 STDMETHODCALLTYPE d2d_transform_graph_GetInputCount(ID2D1TransformGraph *iface) { - FIXME("iface %p stub!\n", iface); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface);
- return 0; + TRACE("iface %p\n", iface); + + return graph->input_count; }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetSingleTransformNode(ID2D1TransformGraph *iface, ID2D1TransformNode *node) { - FIXME("iface %p, node %p stub!\n", iface, node); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + UINT32 input_count, i; + HRESULT hr;
- return E_NOTIMPL; + TRACE("iface %p, node %p.\n", iface, node); + + input_count = ID2D1TransformNode_GetInputCount(node); + if (input_count != graph->input_count) + return E_INVALIDARG; + + ID2D1TransformGraph_Clear(iface); + + if (FAILED(hr = ID2D1TransformGraph_AddNode(iface, node))) + return hr; + if (FAILED(hr = ID2D1TransformGraph_SetOutputNode(iface, node))) + return hr; + for (i = 0; i < input_count; ++i) + { + if (FAILED(hr = ID2D1TransformGraph_ConnectToEffectInput(iface, i, node, i))) + return hr; + } + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_AddNode(ID2D1TransformGraph *iface, ID2D1TransformNode *node) @@ -115,7 +162,13 @@ static HRESULT STDMETHODCALLTYPE d2d_transform_graph_AddNode(ID2D1TransformGraph if (!(entry = calloc(1, sizeof(*entry)))) return E_OUTOFMEMORY;
- ID2D1TransformNode_AddRef(entry->node = node); + entry->input_count = ID2D1TransformNode_GetInputCount(node); + if (!(entry->inputs = calloc(entry->input_count, sizeof(*entry->inputs)))) + { + free(entry); + return E_OUTOFMEMORY; + } + ID2D1TransformNode_AddRef(entry->u.transform = node); list_add_tail(&graph->nodes, &entry->entry);
return S_OK; @@ -137,25 +190,58 @@ static HRESULT STDMETHODCALLTYPE d2d_transform_graph_RemoveNode(ID2D1TransformGr
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_SetOutputNode(ID2D1TransformGraph *iface, ID2D1TransformNode *node) { - FIXME("iface %p, node %p stub!\n", iface, node); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *entry;
- return E_NOTIMPL; + TRACE("iface %p, node %p.\n", iface, node); + + if (!(entry = d2d_transform_graph_find_node(graph, node))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + graph->output_node = entry; + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_ConnectNode(ID2D1TransformGraph *iface, ID2D1TransformNode *from_node, ID2D1TransformNode *to_node, UINT32 index) { - FIXME("iface %p, from_node %p, to_node %p, index %u stub!\n", iface, from_node, to_node, index); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *from, *to;
- return E_NOTIMPL; + TRACE("iface %p, from_node %p, to_node %p, index %u.\n", iface, from_node, to_node, index); + + if (!(from = d2d_transform_graph_find_node(graph, from_node)) + || !(to = d2d_transform_graph_find_node(graph, to_node))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + if (index >= to->input_count) + return E_INVALIDARG; + + from->output = to; + from->output_to_index = index; + to->inputs[index] = from; + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_transform_graph_ConnectToEffectInput(ID2D1TransformGraph *iface, UINT32 input_index, ID2D1TransformNode *node, UINT32 node_index) { - FIXME("iface %p, input_index %u, node %p, node_index %u stub!\n", iface, input_index, node, node_index); + struct d2d_transform_graph *graph = impl_from_ID2D1TransformGraph(iface); + struct d2d_transform_node *entry;
- return E_NOTIMPL; + TRACE("iface %p, input_index %u, node %p, node_index %u.\n", iface, input_index, node, node_index); + + if (!(entry = d2d_transform_graph_find_node(graph, node))) + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + if (input_index >= graph->input_count || node_index >= entry->input_count) + return E_INVALIDARG; + + graph->input_nodes[input_index].output = entry; + graph->input_nodes[input_index].output_to_index = node_index; + entry->inputs[node_index] = &graph->input_nodes[input_index]; + + return S_OK; }
static void STDMETHODCALLTYPE d2d_transform_graph_Clear(ID2D1TransformGraph *iface) @@ -194,11 +280,23 @@ static const ID2D1TransformGraphVtbl d2d_transform_graph_vtbl = d2d_transform_graph_SetPassthroughGraph, };
-static void d2d_transform_graph_init(struct d2d_transform_graph *graph) +static HRESULT d2d_transform_graph_init(struct d2d_transform_graph *graph, UINT32 input_count) { + UINT32 i; + graph->ID2D1TransformGraph_iface.lpVtbl = &d2d_transform_graph_vtbl; graph->refcount = 1; + + if (!(graph->input_nodes = calloc(input_count, sizeof(*graph->input_nodes)))) + return E_OUTOFMEMORY; + for (i = 0; i < input_count; ++i) + { + graph->input_nodes[i].effect_input = TRUE; + } + graph->input_count = input_count; + list_init(&graph->nodes); + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_effect_impl_QueryInterface(ID2D1EffectImpl *iface, REFIID iid, void **out) @@ -1639,7 +1737,12 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec ID2D1EffectContext_Release(&effect_context->ID2D1EffectContext_iface); return E_OUTOFMEMORY; } - d2d_transform_graph_init(graph); + if (FAILED(hr = d2d_transform_graph_init(graph, reg->default_input_count))) + { + free(graph); + ID2D1EffectContext_Release(&effect_context->ID2D1EffectContext_iface); + return hr; + }
if (!(object = calloc(1, sizeof(*object)))) {
Nikolay Sivov (@nsivov) commented about dlls/d2d1/d2d1_private.h:
struct d2d_transform_node {
- ID2D1TransformNode *node;
- BOOL effect_input;
- union
- {
ID2D1TransformNode *transform;
ID2D1Bitmap *bitmap;
- } u;
"bitmap" field is not used anywhere. Same for effect_input I think.
Nikolay Sivov (@nsivov) commented about dlls/d2d1/d2d1_private.h:
struct d2d_transform_node {
- ID2D1TransformNode *node;
- BOOL effect_input;
- union
- {
ID2D1TransformNode *transform;
ID2D1Bitmap *bitmap;
- } u;
- struct d2d_transform_node **inputs;
- UINT32 input_count;
- struct d2d_transform_node *output;
- UINT32 output_to_index;
This one seems to be unused as well.
Nikolay Sivov (@nsivov) commented about dlls/d2d1/effect.c:
-static void d2d_transform_graph_init(struct d2d_transform_graph *graph) +static HRESULT d2d_transform_graph_init(struct d2d_transform_graph *graph, UINT32 input_count) {
- UINT32 i;
- graph->ID2D1TransformGraph_iface.lpVtbl = &d2d_transform_graph_vtbl; graph->refcount = 1;
- if (!(graph->input_nodes = calloc(input_count, sizeof(*graph->input_nodes))))
return E_OUTOFMEMORY;
- for (i = 0; i < input_count; ++i)
- {
graph->input_nodes[i].effect_input = TRUE;
- }
- graph->input_count = input_count;
This should probably be integrated with SetInputCount().
Nikolay Sivov (@nsivov) commented about dlls/d2d1/effect.c:
if (!(entry = calloc(1, sizeof(*entry)))) return E_OUTOFMEMORY;
- ID2D1TransformNode_AddRef(entry->node = node);
- entry->input_count = ID2D1TransformNode_GetInputCount(node);
- if (!(entry->inputs = calloc(entry->input_count, sizeof(*entry->inputs))))
- {
free(entry);
return E_OUTOFMEMORY;
- }
Is it possible for node input count to change? If it's constant, this array could be created on node creation.
On Fri Sep 2 05:29:29 2022 +0000, Nikolay Sivov wrote:
This one seems to be unused as well.
Do you mean `output_to_index`?
`output_to_index` is used in `d2d_transform_graph_remove_node()`.
If we don't record the index to which our node connects, in `d2d_transform_graph_remove_node()`, we have to replace:
``` if (node->output) node->output->inputs[node->output_to_index] = NULL; ```
with
``` if (node->output) { for (i = 0; i < node->output->input_count; ++i) { if (node->output->inputs[i] == node) { node->output->inputs[i] = NULL; break; } } } ```
Which one would be better? Remove `output_to_index` or not?
On Fri Sep 2 05:29:31 2022 +0000, Nikolay Sivov wrote:
Is it possible for node input count to change? If it's constant, this array could be created on node creation.
Node input count is a constant. And `AddNode()` is the place where we create `d2d_transform_node`.
`d2d_transform_node` is not node object itself. In fact it is a wrapper of `ID2D1TransformNode` and holds a reference to it. `ID2D1TransformNode` is the real node object.
I think `d2d_transform_node` should relies on `ID2D1TransformNode` interface, instead of concrete implementation of `ID2D1TransformNode`. So this array should be in `d2d_transform_node`. And we create this array in `AddNode()` where we create our `d2d_transform_node`.