Fix T40448: Blurring bug in the compositor

This commit pretty much reverts all the changes related on tile-ability
of the fast gaussian blur. It's not tilable by definition and would almost
always give you seams on the tile boundaries.

Atmind already met the issue and tried to solve it by increasing some
magic constant, which is pretty much likely simply made it so compositor
switched to full-frame calculation in that particular .blend file.

Fast gaussian is really not a production thing and need to be avoided.
We're to improve speed of normal gaussian blur instead.
This commit is contained in:
Sergey Sharybin 2014-06-02 18:33:19 +06:00
parent fd781c1095
commit 9016d6d7a0
Notes: blender-bot 2023-02-14 10:34:07 +01:00
Referenced by issue #40569, Image user count is not decreased when deleting a background image
Referenced by issue #40448, blurring bug in the compositor
4 changed files with 14 additions and 124 deletions

View File

@ -109,13 +109,4 @@ typedef enum OrderOfChunks {
#define COM_BLUR_BOKEH_PIXELS 512
/**
* The fast gaussien blur is not an accurate blur.
* This setting can be used to increase/decrease the
* amount of the input data. (dependent area of interest)
*
* Fix for: T39307
*/
#define COM_FAST_GAUSSIAN_MULTIPLIER 3
#endif /* __COM_DEFINES_H__ */

View File

@ -53,7 +53,6 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon
if (data->filtertype == R_FILTER_FAST_GAUSS) {
FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation();
operationfgb->setData(data);
operationfgb->setChunksize(context.getChunksize());
converter.addOperation(operationfgb);
converter.mapInputSocket(getInputSocket(1), operationfgb->getInputSocket(1));

View File

@ -29,7 +29,6 @@
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)
@ -38,57 +37,22 @@ 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.
float size = this->m_size * COM_FAST_GAUSSIAN_MULTIPLIER;
int sx = this->m_data.sizex * size;
if (sx < 1)
sx = 1;
int sy = this->m_data.sizey * size;
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;
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;
}
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) {
getDAI(input, &newInput);
else {
if (this->m_iirgaus) {
return false;
}
else {
newInput.xmin = 0;
@ -117,7 +81,6 @@ void FastGaussianBlurOperation::deinitExecution()
void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
{
#if 0
lockMutex();
if (!this->m_iirgaus) {
MemoryBuffer *newBuf = (MemoryBuffer *)this->m_inputProgram->initializeTileData(rect);
@ -146,68 +109,8 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
}
unlockMutex();
return this->m_iirgaus;
#else
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;
#endif
}
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];

View File

@ -28,19 +28,16 @@
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();
};