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).
This commit is contained in:
parent
fd7bffa3c5
commit
8d1c0b6f0f
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user