Compositor: Fallback to a black color for invalid outputs

Currently, some compositor operations produce en empty output buffer by
specifying a COM_AREA_NONE canvas to indicate an invalid output, for
instance, when the Mask operation references an invalid mask. The
intention is that this buffer would signal that a fallback value should
fill the canvas of consumer operations.

The aforementioned behavior is currently implemented in a rather hacky
way, where it is implemented using the Translate operation as part of
canvas conversion in COM_convert_canvas, where the operation would clear
the entire buffer with zeros since out of bounds checking would always
take the out of bound case due to the empty buffer.

This behavior is problematic because we can't control the fallback
value, which would ideally be an opaque black color. Moreover, since
implicit type conversion happen before canvas conversion by design,
value typed buffers would eventually become transparent, which is rather
unexpected to the end user since float/value outputs can't have
transparency.

This is not a good design or implementation, but a redesign will be too
complex for now. So to fix this, we workaround it by handling the empty
buffer case explicitly in the Translate operation and fill the output
using a fallback black color, which works for both value and color typed
buffers, since this would also be the output of the value to color
implicit conversion.

Pull Request: https://projects.blender.org/blender/blender/pulls/118340
This commit is contained in:
Omar Emara
2024-02-16 15:32:59 +01:00
committed by Omar Emara
parent eabb4f16ce
commit 0906201a4c

View File

@@ -117,6 +117,18 @@ void TranslateOperation::update_memory_buffer_partial(MemoryBuffer *output,
return;
}
/* Some compositor operations produce an empty output buffer by specifying a COM_AREA_NONE canvas
* to indicate an invalid output, for instance, when the Mask operation reference an invalid
* mask. The intention is that this buffer would signal that a fallback value would fill the
* canvas of consumer operations. Since the aforementioned filling is achieved through the
* Translate operation as part of canvas conversion in COM_convert_canvas, we handle the empty
* buffer case here and fill the output using a fallback black color. */
if (BLI_rcti_is_empty(&input->get_rect())) {
const float value[4] = {0.0f, 0.0f, 0.0f, 1.0f};
output->fill(area, value);
return;
}
const int delta_x = this->get_delta_x();
const int delta_y = this->get_delta_y();
for (int y = area.ymin; y < area.ymax; y++) {