[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60863] trunk/blender/source/blender/ compositor: Applied patch [#34178] tile rendering for fast gaussian blur

Jeroen Bakker j.bakker at atmind.nl
Sat Oct 19 19:45:59 CEST 2013


Revision: 60863
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60863
Author:   jbakker
Date:     2013-10-19 17:45:58 +0000 (Sat, 19 Oct 2013)
Log Message:
-----------
Applied patch [#34178] tile rendering for fast gaussian blur

Thanks to David M (erwin94)
only added some comments.

https://projects.blender.org/tracker/?func=detail&aid=34178&group_id=9&atid=127
 

Modified Paths:
--------------
    trunk/blender/source/blender/compositor/nodes/COM_BlurNode.cpp
    trunk/blender/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
    trunk/blender/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h

Modified: trunk/blender/source/blender/compositor/nodes/COM_BlurNode.cpp
===================================================================
--- trunk/blender/source/blender/compositor/nodes/COM_BlurNode.cpp	2013-10-19 16:51:35 UTC (rev 60862)
+++ trunk/blender/source/blender/compositor/nodes/COM_BlurNode.cpp	2013-10-19 17:45:58 UTC (rev 60863)
@@ -53,6 +53,7 @@
 	if (data->filtertype == R_FILTER_FAST_GAUSS) {
 		FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation();
 		operationfgb->setData(data);
+		operationfgb->setChunksize(context->getChunksize());
 		operationfgb->setbNode(editorNode);
 		this->getInputSocket(1)->relinkConnections(operationfgb->getInputSocket(1), 1, graph);
 		graph->addOperation(operationfgb);

Modified: trunk/blender/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp	2013-10-19 16:51:35 UTC (rev 60862)
+++ trunk/blender/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp	2013-10-19 17:45:58 UTC (rev 60863)
@@ -29,6 +29,7 @@
 FastGaussianBlurOperation::FastGaussianBlurOperation() : BlurBaseOperation(COM_DT_COLOR)
 {
 	this->m_iirgaus = NULL;
+	this->m_chunksize = 256;
 }
 
 void FastGaussianBlurOperation::executePixel(float output[4], int x, int y, void *data)
@@ -37,22 +38,56 @@
 	newData->read(output, x, y);
 }
 
+// Calculate the depending area of interest. This depends on the
+// size of the blur operation; if the blur is large it is faster
+// to just calculate the whole image at once.
+// Returns true if the area is just a tile and false if it is
+// the whole image.
+bool FastGaussianBlurOperation::getDAI(rcti *rect, rcti *output)
+{
+	// m_data->sizex * m_size should be enough? For some reason there
+	// seem to be errors in the boundary between tiles.
+	int sx = this->m_data->sizex * this->m_size * 2;
+	if (sx < 1)
+		sx = 1;
+	int sy = this->m_data->sizey * this->m_size * 2;
+	if (sy < 1)
+		sy = 1;
+
+	if (sx >= this->m_chunksize || sy >= this->m_chunksize) {
+		output->xmin = 0;
+		output->xmax = this->getWidth();
+		output->ymin = 0;
+		output->ymax = this->getHeight();
+		return false;
+	}
+	else {
+		output->xmin = rect->xmin - sx - 1;
+		output->xmax = rect->xmax + sx + 1;
+		output->ymin = rect->ymin - sy - 1;
+		output->ymax = rect->ymax + sy + 1;
+		return true;
+	}
+}
+
 bool FastGaussianBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
 {
 	rcti newInput;
-	rcti sizeInput;
-	sizeInput.xmin = 0;
-	sizeInput.ymin = 0;
-	sizeInput.xmax = 5;
-	sizeInput.ymax = 5;
 	
-	NodeOperation *operation = this->getInputOperation(1);
-	if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) {
-		return true;
+	if (!this->m_sizeavailable) {
+		rcti sizeInput;
+		sizeInput.xmin = 0;
+		sizeInput.ymin = 0;
+		sizeInput.xmax = 5;
+		sizeInput.ymax = 5;
+		NodeOperation *operation = this->getInputOperation(1);
+		if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) {
+			return true;
+		}
 	}
-	else {
-		if (this->m_iirgaus) {
-			return false;
+	{
+		if (this->m_sizeavailable) {
+			getDAI(input, &newInput);
 		}
 		else {
 			newInput.xmin = 0;
@@ -81,7 +116,7 @@
 
 void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
 {
-	lockMutex();
+/*	lockMutex();
     if (!this->m_iirgaus) {
         MemoryBuffer *newBuf = (MemoryBuffer *)this->m_inputProgram->initializeTileData(rect);
 		MemoryBuffer *copy = newBuf->duplicate();
@@ -109,8 +144,67 @@
 	}
 	unlockMutex();
 	return this->m_iirgaus;
+}*/
+
+ 	lockMutex();
+	if (this->m_iirgaus) {
+		// if this->m_iirgaus is set, we don't do tile rendering, so
+		// we can return the already calculated cache
+		unlockMutex();
+		return this->m_iirgaus;
+	}
+	updateSize();
+	rcti dai;
+	bool use_tiles = getDAI(rect, &dai);
+	if (use_tiles) {
+		unlockMutex();
+	}
+ 
+	MemoryBuffer *buffer = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
+	rcti *buf_rect = buffer->getRect();
+
+	dai.xmin = max(dai.xmin, buf_rect->xmin);
+	dai.xmax = min(dai.xmax, buf_rect->xmax);
+	dai.ymin = max(dai.ymin, buf_rect->ymin);
+	dai.ymax = min(dai.ymax, buf_rect->ymax);
+
+	MemoryBuffer *tile = new MemoryBuffer(NULL, &dai);
+	tile->copyContentFrom(buffer);
+
+	int c;
+	float sx = this->m_data->sizex * this->m_size / 2.0f;
+	float sy = this->m_data->sizey * this->m_size / 2.0f;
+
+	if ((sx == sy) && (sx > 0.f)) {
+		for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
+			IIR_gauss(tile, sx, c, 3);
+	}
+	else {
+		if (sx > 0.0f) {
+ 			for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
+				IIR_gauss(tile, sx, c, 1);
+ 		}
+		if (sy > 0.0f) {
+			for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
+				IIR_gauss(tile, sy, c, 2);
+ 		}
+ 	}
+	if (!use_tiles) {
+		this->m_iirgaus = tile;
+		unlockMutex();
+	}
+	return tile;
 }
 
+void FastGaussianBlurOperation::deinitializeTileData(rcti *rect, void *data)
+{
+	if (!this->m_iirgaus && data) {
+		MemoryBuffer *tile = (MemoryBuffer *)data;
+		delete tile;
+	}
+}
+
+
 void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsigned int chan, unsigned int xy)
 {
 	double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3];

Modified: trunk/blender/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
===================================================================
--- trunk/blender/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h	2013-10-19 16:51:35 UTC (rev 60862)
+++ trunk/blender/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h	2013-10-19 17:45:58 UTC (rev 60863)
@@ -28,16 +28,19 @@
 
 class FastGaussianBlurOperation : public BlurBaseOperation {
 private:
-	float m_sx;
-	float m_sy;
 	MemoryBuffer *m_iirgaus;
+	int m_chunksize;
+
 public:
 	FastGaussianBlurOperation();
 	bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
 	void executePixel(float output[4], int x, int y, void *data);
+    void setChunksize(int size) { this->m_chunksize = size; }
 	
 	static void IIR_gauss(MemoryBuffer *src, float sigma, unsigned int channel, unsigned int xy);
+	bool getDAI(rcti *rect, rcti *output);
 	void *initializeTileData(rcti *rect);
+	void deinitializeTileData(rcti *rect, void *data);
 	void deinitExecution();
 	void initExecution();
 };




More information about the Bf-blender-cvs mailing list