[Bf-codereview] Fix for #36468, "Buffer Groups" option changes compositing output (issue 12740045)
lukas.toenne at gmail.com
lukas.toenne at gmail.com
Thu Aug 15 08:25:43 CEST 2013
Reviewers: bf-codereview_blender.org, j.bakker,
Description:
Problem is that the read/write buffer operations only work with actual
image inputs. If a singular value is used as group input no actual
buffer will be created, the write operation does not schedule any chunks
and the ReadBufferOperation subsequently returns zero
(MemoryBuffer::read).
The fix uses the (0,0) resolution to detect single value input of the
WriteBufferOperation. The actual resolution is then clamped to (1,1) to
ensure we have a single pixel to store the value in. A m_single_value
flag is also set, so we can reliably distinguish this from genuine image
resolutions without having to check m_width/m_height later on.
The ReadBufferOperation copies this flag from the associated
WriteBufferOperation and if set will always return the single value from
pixel (0,0).
Please review this at https://codereview.appspot.com/12740045/
Affected files:
source/blender/compositor/operations/COM_ReadBufferOperation.cpp
source/blender/compositor/operations/COM_ReadBufferOperation.h
source/blender/compositor/operations/COM_WriteBufferOperation.cpp
source/blender/compositor/operations/COM_WriteBufferOperation.h
Index: source/blender/compositor/operations/COM_ReadBufferOperation.cpp
===================================================================
--- source/blender/compositor/operations/COM_ReadBufferOperation.cpp
(revision 59138)
+++ source/blender/compositor/operations/COM_ReadBufferOperation.cpp
(working copy)
@@ -27,6 +27,7 @@
ReadBufferOperation::ReadBufferOperation() : NodeOperation()
{
this->addOutputSocket(COM_DT_COLOR);
+ this->m_single_value = false;
this->m_offset = 0;
this->m_buffer = NULL;
}
@@ -47,11 +48,17 @@
if (this->m_memoryProxy->getExecutor()) {
this->m_memoryProxy->getExecutor()->setResolution(resolution);
}
+
+ m_single_value = operation->isSingleValue();
}
}
void ReadBufferOperation::executePixel(float output[4], float x, float y,
PixelSampler sampler)
{
- if (sampler == COM_PS_NEAREST) {
+ if (m_single_value) {
+ /* write buffer has a single value stored at (0,0) */
+ m_buffer->read(output, 0, 0);
+ }
+ else if (sampler == COM_PS_NEAREST) {
m_buffer->read(output, x, y);
}
else {
@@ -61,7 +68,13 @@
void ReadBufferOperation::executePixel(float output[4], float x, float y,
float dx, float dy, PixelSampler sampler)
{
- m_buffer->readEWA(output, x, y, dx, dy, sampler);
+ if (m_single_value) {
+ /* write buffer has a single value stored at (0,0) */
+ m_buffer->read(output, 0, 0);
+ }
+ else {
+ m_buffer->readEWA(output, x, y, dx, dy, sampler);
+ }
}
bool ReadBufferOperation::determineDependingAreaOfInterest(rcti *input,
ReadBufferOperation *readOperation, rcti *output)
Index: source/blender/compositor/operations/COM_ReadBufferOperation.h
===================================================================
--- source/blender/compositor/operations/COM_ReadBufferOperation.h
(revision 59138)
+++ source/blender/compositor/operations/COM_ReadBufferOperation.h (working
copy)
@@ -29,6 +29,7 @@
class ReadBufferOperation : public NodeOperation {
private:
MemoryProxy *m_memoryProxy;
+ bool m_single_value; /* single value stored in buffer, copied from
associated write operation */
unsigned int m_offset;
MemoryBuffer *m_buffer;
public:
Index: source/blender/compositor/operations/COM_WriteBufferOperation.cpp
===================================================================
--- source/blender/compositor/operations/COM_WriteBufferOperation.cpp
(revision 59138)
+++ source/blender/compositor/operations/COM_WriteBufferOperation.cpp
(working copy)
@@ -174,6 +174,21 @@
delete clKernelsToCleanUp;
}
+void WriteBufferOperation::determineResolution(unsigned int resolution[2],
unsigned int preferredResolution[2])
+{
+ NodeOperation::determineResolution(resolution, preferredResolution);
+ /* make sure there is at least one pixel stored in case the input is a
single value */
+ m_single_value = false;
+ if (resolution[0] == 0) {
+ resolution[0] = 1;
+ m_single_value = true;
+ }
+ if (resolution[1] == 0) {
+ resolution[1] = 1;
+ m_single_value = true;
+ }
+}
+
void WriteBufferOperation::readResolutionFromInputSocket()
{
NodeOperation *inputOperation = this->getInputOperation(0);
Index: source/blender/compositor/operations/COM_WriteBufferOperation.h
===================================================================
--- source/blender/compositor/operations/COM_WriteBufferOperation.h
(revision 59138)
+++ source/blender/compositor/operations/COM_WriteBufferOperation.h
(working copy)
@@ -32,6 +32,7 @@
*/
class WriteBufferOperation : public NodeOperation {
MemoryProxy *m_memoryProxy;
+ bool m_single_value; /* single value stored in buffer */
NodeOperation *m_input;
public:
WriteBufferOperation();
@@ -40,11 +41,13 @@
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
void executePixel(float output[4], float x, float y, PixelSampler
sampler);
const bool isWriteBufferOperation() const { return true; }
+ bool isSingleValue() const { return m_single_value; }
void executeRegion(rcti *rect, unsigned int tileNumber);
void initExecution();
void deinitExecution();
void executeOpenCLRegion(OpenCLDevice *device, rcti *rect, unsigned int
chunkNumber, MemoryBuffer **memoryBuffers, MemoryBuffer *outputBuffer);
+ void determineResolution(unsigned int resolution[2], unsigned int
preferredResolution[2]);
void readResolutionFromInputSocket();
inline NodeOperation *getInput() {
return m_input;
More information about the Bf-codereview
mailing list