From 8b8bc164dafdfc5fd2f5967ea3cfe07c0193f570 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 12 Jul 2012 19:19:03 +0000 Subject: Small optimizations in compositor. Most of them are not noticeable. --- .../operations/COM_GaussianBokehBlurOperation.cpp | 153 +++++++++++++++++++++ 1 file changed, 153 insertions(+) (limited to 'source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp') diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index ac91d3336e2..a9e8de25297 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -194,3 +194,156 @@ bool GaussianBokehBlurOperation::determineDependingAreaOfInterest(rcti *input, R return BlurBaseOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } } + +// reference image +GaussianBokehBlurReferenceOperation::GaussianBokehBlurReferenceOperation() : NodeOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + this->setComplex(true); + this->m_gausstab = NULL; + this->m_inputImage = NULL; + this->m_inputSize = NULL; +} + +void *GaussianBokehBlurReferenceOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + void *buffer = getInputOperation(0)->initializeTileData(NULL, memoryBuffers); + return buffer; +} + +void GaussianBokehBlurReferenceOperation::initExecution() +{ + // setup gaustab + this->m_data->image_in_width = this->getWidth(); + this->m_data->image_in_height = this->getHeight(); + if (this->m_data->relative) { + switch (this->m_data->aspect) { + case CMP_NODE_BLUR_ASPECT_NONE: + this->m_data->sizex = (int)(this->m_data->percentx * 0.01f * this->m_data->image_in_width); + this->m_data->sizey = (int)(this->m_data->percenty * 0.01f * this->m_data->image_in_height); + break; + case CMP_NODE_BLUR_ASPECT_Y: + this->m_data->sizex = (int)(this->m_data->percentx * 0.01f * this->m_data->image_in_width); + this->m_data->sizey = (int)(this->m_data->percenty * 0.01f * this->m_data->image_in_width); + break; + case CMP_NODE_BLUR_ASPECT_X: + this->m_data->sizex = (int)(this->m_data->percentx * 0.01f * this->m_data->image_in_height); + this->m_data->sizey = (int)(this->m_data->percenty * 0.01f * this->m_data->image_in_height); + break; + } + } + + updateGauss(); + this->m_inputImage = this->getInputSocketReader(0); + this->m_inputSize = this->getInputSocketReader(1); +} + +void GaussianBokehBlurReferenceOperation::updateGauss() +{ + int n; + float *dgauss; + float *ddgauss; + int j, i; + + n = (2 * radx + 1) * (2 * rady + 1); + + /* create a full filter image */ + ddgauss = new float[n]; + dgauss = ddgauss; + for (j = -rady; j <= rady; j++) { + for (i = -radx; i <= radx; i++, dgauss++) { + float fj = (float)j / radyf; + float fi = (float)i / radxf; + float dist = sqrt(fj * fj + fi * fi); + *dgauss = RE_filter_value(this->m_data->filtertype, dist); + } + } + this->m_gausstab = ddgauss; +} + +void GaussianBokehBlurReferenceOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + float tempColor[4]; + float tempSize[4]; + tempColor[0] = 0; + tempColor[1] = 0; + tempColor[2] = 0; + tempColor[3] = 0; + float multiplier_accum = 0; + MemoryBuffer *inputBuffer = (MemoryBuffer *)data; + float *buffer = inputBuffer->getBuffer(); + int bufferwidth = inputBuffer->getWidth(); + int bufferstartx = inputBuffer->getRect()->xmin; + int bufferstarty = inputBuffer->getRect()->ymin; + this->m_inputSize->read(tempSize, x, y, inputBuffers, data); + float size = tempSize[0]; + CLAMP(size, 0.0f, 1.0f); + float sizeX = ceil(this->m_data->sizex * size); + float sizeY = ceil(this->m_data->sizey * size); + + if (sizeX <= 0.5f && sizeY <= 0.5f) { + this->m_inputImage->read(color, x, y, inputBuffers, data); + return; + } + + int miny = y - sizeY; + int maxy = y + sizeY; + int minx = x - sizeX; + int maxx = x + sizeX; + miny = max(miny, inputBuffer->getRect()->ymin); + minx = max(minx, inputBuffer->getRect()->xmin); + maxy = min(maxy, inputBuffer->getRect()->ymax); + maxx = min(maxx, inputBuffer->getRect()->xmax); + + int step = QualityStepHelper::getStep(); + int offsetadd = QualityStepHelper::getOffsetAdd(); + for (int ny = miny; ny < maxy; ny += step) { + int u = ny - y; + float uf = ((u/sizeY)*radyf)+radyf; + int indexu = uf * (radx*2+1); + int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth); + for (int nx = minx; nx < maxx; nx += step) { + int v = nx - x; + float vf = ((v/sizeX)*radxf)+radxf; + int index = indexu + vf; + const float multiplier = this->m_gausstab[index]; + madd_v4_v4fl(tempColor, &buffer[bufferindex], multiplier); + multiplier_accum += multiplier; + index += step; + bufferindex += offsetadd; + } + } + + mul_v4_v4fl(color, tempColor, 1.0f / multiplier_accum); +} + +void GaussianBokehBlurReferenceOperation::deinitExecution() +{ + delete [] this->m_gausstab; + this->m_gausstab = NULL; + this->m_inputImage = NULL; + this->m_inputSize = NULL; + +} + +bool GaussianBokehBlurReferenceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +{ + rcti newInput; + NodeOperation *operation = this->getInputOperation(1); + + if (operation->determineDependingAreaOfInterest(input, readOperation, output)) { + return true; + } + else { + int addx = this->m_data->sizex+2; + int addy = this->m_data->sizey+2; + newInput.xmax = input->xmax + addx; + newInput.xmin = input->xmin - addx; + newInput.ymax = input->ymax + addy; + newInput.ymin = input->ymin - addy; + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + } +} + -- cgit v1.2.3