diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2013-10-19 21:45:58 +0400 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2013-10-19 21:45:58 +0400 |
commit | 0410eff30606473ab106f49cca8a83abf599dacf (patch) | |
tree | 8ee5e51405c8f24759dc1dfbee84896c05d02a65 /source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp | |
parent | 1c675034c1a5439cc515b273f1b5f233749fb407 (diff) |
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
Diffstat (limited to 'source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp')
-rw-r--r-- | source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp | 118 |
1 files changed, 106 insertions, 12 deletions
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index d0c3d1b25ab..aec1e1387c3 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -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 @@ void FastGaussianBlurOperation::executePixel(float output[4], int x, int y, void 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::deinitExecution() 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 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect) } 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]; |