[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