diff options
author | Lukas Toenne <lukas.toenne@googlemail.com> | 2013-08-16 17:11:15 +0400 |
---|---|---|
committer | Lukas Toenne <lukas.toenne@googlemail.com> | 2013-08-16 17:11:15 +0400 |
commit | 8d1c0b6f0f4012b379023b96b4c426b3432c018b (patch) | |
tree | a06f8d870de918fba20f3b8cfe5b615337dc4938 /source/blender | |
parent | fd7bffa3c5276229a0ca06e4ff59319fbfc674f9 (diff) |
Fix for #36468, "Buffer Groups" option changes compositing output.
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).
Diffstat (limited to 'source/blender')
4 files changed, 34 insertions, 2 deletions
diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp index 03d41edda64..22820375831 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp @@ -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 @@ void ReadBufferOperation::determineResolution(unsigned int resolution[2], unsign 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, PixelS 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) diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.h b/source/blender/compositor/operations/COM_ReadBufferOperation.h index 7e3ac147ee3..c8dcfb7c33d 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.h +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.h @@ -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: diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index 17c8f4d9fd1..f18493dc334 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -174,6 +174,21 @@ void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect, 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); diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h index d89444045d4..157543fcb72 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.h +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h @@ -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 @@ public: 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; |