diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2013-08-16 14:01:09 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2013-08-16 14:01:09 +0400 |
commit | a8353530be6c2e61243110fcf469f7b70834bdd9 (patch) | |
tree | a6ed401b2a71fd5399f2c6db2df738cfcad79ca7 /source/blender/compositor/operations/COM_ImageOperation.cpp | |
parent | 970c80e473fd390dff329acb7f3a08fc2edfd26d (diff) |
Make byte-float conversion threaded in compositor
In fact, there's no need to get float buffer at all,
conversion could be done in pixel processor level
after interpolation.
It might give slightly worse interpolation results
(which i'm not sure would be visible by eye) but
it gives more than 2x speedup on my laptop on node
setups used for warping image.
--
svn merge -r58988:58989 ^/branches/soc-2011-tomato
Diffstat (limited to 'source/blender/compositor/operations/COM_ImageOperation.cpp')
-rw-r--r-- | source/blender/compositor/operations/COM_ImageOperation.cpp | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp index c8e3dbf993d..89a56af6b15 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cpp +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -40,7 +40,8 @@ BaseImageOperation::BaseImageOperation() : NodeOperation() { this->m_image = NULL; this->m_buffer = NULL; - this->m_imageBuffer = NULL; + this->m_imageFloatBuffer = NULL; + this->m_imageByteBuffer = NULL; this->m_imageUser = NULL; this->m_imagewidth = 0; this->m_imageheight = 0; @@ -70,10 +71,6 @@ ImBuf *BaseImageOperation::getImBuf() BKE_image_release_ibuf(this->m_image, ibuf, NULL); return NULL; } - - if (ibuf->rect_float == NULL) { - IMB_float_from_rect(ibuf); - } return ibuf; } @@ -83,7 +80,8 @@ void BaseImageOperation::initExecution() ImBuf *stackbuf = getImBuf(); this->m_buffer = stackbuf; if (stackbuf) { - this->m_imageBuffer = stackbuf->rect_float; + this->m_imageFloatBuffer = stackbuf->rect_float; + this->m_imageByteBuffer = stackbuf->rect; this->m_depthBuffer = stackbuf->zbuf_float; this->m_imagewidth = stackbuf->x; this->m_imageheight = stackbuf->y; @@ -93,7 +91,8 @@ void BaseImageOperation::initExecution() void BaseImageOperation::deinitExecution() { - this->m_imageBuffer = NULL; + this->m_imageFloatBuffer = NULL; + this->m_imageByteBuffer = NULL; BKE_image_release_ibuf(this->m_image, this->m_buffer, NULL); } @@ -112,23 +111,48 @@ void BaseImageOperation::determineResolution(unsigned int resolution[2], unsigne BKE_image_release_ibuf(this->m_image, stackbuf, NULL); } -void ImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +static void sampleImageAtLocation(ImBuf *ibuf, float x, float y, PixelSampler sampler, bool make_linear_rgb, float color[4]) { - if (this->m_imageBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { - zero_v4(output); + if (ibuf->rect_float) { + switch (sampler) { + case COM_PS_NEAREST: + nearest_interpolation_color(ibuf, NULL, color, x, y); + break; + case COM_PS_BILINEAR: + bilinear_interpolation_color(ibuf, NULL, color, x, y); + break; + case COM_PS_BICUBIC: + bicubic_interpolation_color(ibuf, NULL, color, x, y); + break; + } } else { + unsigned char byte_color[4]; switch (sampler) { case COM_PS_NEAREST: - nearest_interpolation_color(this->m_buffer, NULL, output, x, y); + nearest_interpolation_color(ibuf, byte_color, NULL, x, y); break; case COM_PS_BILINEAR: - bilinear_interpolation_color(this->m_buffer, NULL, output, x, y); + bilinear_interpolation_color(ibuf, byte_color, NULL, x, y); break; case COM_PS_BICUBIC: - bicubic_interpolation_color(this->m_buffer, NULL, output, x, y); + bicubic_interpolation_color(ibuf, byte_color, NULL, x, y); break; } + rgba_uchar_to_float(color, byte_color); + if (make_linear_rgb) { + IMB_colormanagement_colorspace_to_scene_linear_v4(color, FALSE, ibuf->rect_colorspace); + } + } +} + +void ImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +{ + if ((this->m_imageFloatBuffer == NULL && this->m_imageByteBuffer == NULL) || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { + zero_v4(output); + } + else { + sampleImageAtLocation(this->m_buffer, x, y, sampler, true, output); } } @@ -136,22 +160,12 @@ void ImageAlphaOperation::executePixel(float output[4], float x, float y, PixelS { float tempcolor[4]; - if (this->m_imageBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { + if ((this->m_imageFloatBuffer == NULL && this->m_imageByteBuffer == NULL) || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { output[0] = 0.0f; } else { tempcolor[3] = 1.0f; - switch (sampler) { - case COM_PS_NEAREST: - nearest_interpolation_color(this->m_buffer, NULL, tempcolor, x, y); - break; - case COM_PS_BILINEAR: - bilinear_interpolation_color(this->m_buffer, NULL, tempcolor, x, y); - break; - case COM_PS_BICUBIC: - bicubic_interpolation_color(this->m_buffer, NULL, tempcolor, x, y); - break; - } + sampleImageAtLocation(this->m_buffer, x, y, sampler, false, tempcolor); output[0] = tempcolor[3]; } } |