From 047346224155211ab86faaebc9d31f9dc457f9a7 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 23 Jun 2022 12:33:58 -0500 Subject: Geometry Nodes: Speed up Separate color node in RGB mode This applies the same optimization as b8bd304bd45397b8c to the separate color node. I observed about a 50% improvement with 10 million values when only extracting one channel-- from about 17ms to 11ms. --- .../nodes/function/nodes/node_fn_separate_color.cc | 41 ++++++++++++++++------ 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/source/blender/nodes/function/nodes/node_fn_separate_color.cc b/source/blender/nodes/function/nodes/node_fn_separate_color.cc index 1701dfdc6fa..19613427835 100644 --- a/source/blender/nodes/function/nodes/node_fn_separate_color.cc +++ b/source/blender/nodes/function/nodes/node_fn_separate_color.cc @@ -60,22 +60,41 @@ class SeparateRGBAFunction : public fn::MultiFunction { { const VArray &colors = params.readonly_single_input(0, "Color"); - MutableSpan red = params.uninitialized_single_output(1, "Red"); - MutableSpan green = params.uninitialized_single_output(2, "Green"); - MutableSpan blue = params.uninitialized_single_output(3, "Blue"); + + MutableSpan red = params.uninitialized_single_output_if_required(1, "Red"); + MutableSpan green = params.uninitialized_single_output_if_required(2, "Green"); + MutableSpan blue = params.uninitialized_single_output_if_required(3, "Blue"); MutableSpan alpha = params.uninitialized_single_output_if_required(4, "Alpha"); - for (int64_t i : mask) { - red[i] = colors[i].r; - green[i] = colors[i].g; - blue[i] = colors[i].b; + std::array, 4> outputs = {red, green, blue, alpha}; + Vector used_outputs; + if (!red.is_empty()) { + used_outputs.append(0); + } + if (!green.is_empty()) { + used_outputs.append(1); + } + if (!blue.is_empty()) { + used_outputs.append(2); } - if (!alpha.is_empty()) { - for (int64_t i : mask) { - alpha[i] = colors[i].a; - } + used_outputs.append(3); } + + devirtualize_varray(colors, [&](auto colors) { + mask.to_best_mask_type([&](auto mask) { + const int used_outputs_num = used_outputs.size(); + const int *used_outputs_data = used_outputs.data(); + + for (const int64_t i : mask) { + const ColorGeometry4f &color = colors[i]; + for (const int out_i : IndexRange(used_outputs_num)) { + const int channel = used_outputs_data[out_i]; + outputs[channel][i] = color[channel]; + } + } + }); + }); } }; -- cgit v1.2.3