forked from bartvdbraak/blender
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
This commit is contained in:
parent
970c80e473
commit
a8353530be
@ -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);
|
||||
}
|
||||
|
||||
static void sampleImageAtLocation(ImBuf *ibuf, float x, float y, PixelSampler sampler, bool make_linear_rgb, float color[4])
|
||||
{
|
||||
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(ibuf, byte_color, NULL, x, y);
|
||||
break;
|
||||
case COM_PS_BILINEAR:
|
||||
bilinear_interpolation_color(ibuf, byte_color, NULL, x, y);
|
||||
break;
|
||||
case COM_PS_BICUBIC:
|
||||
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_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() ) {
|
||||
zero_v4(output);
|
||||
}
|
||||
else {
|
||||
switch (sampler) {
|
||||
case COM_PS_NEAREST:
|
||||
nearest_interpolation_color(this->m_buffer, NULL, output, x, y);
|
||||
break;
|
||||
case COM_PS_BILINEAR:
|
||||
bilinear_interpolation_color(this->m_buffer, NULL, output, x, y);
|
||||
break;
|
||||
case COM_PS_BICUBIC:
|
||||
bicubic_interpolation_color(this->m_buffer, NULL, output, x, y);
|
||||
break;
|
||||
}
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,8 @@ protected:
|
||||
ImBuf *m_buffer;
|
||||
Image *m_image;
|
||||
ImageUser *m_imageUser;
|
||||
float *m_imageBuffer;
|
||||
float *m_imageFloatBuffer;
|
||||
unsigned int *m_imageByteBuffer;
|
||||
float *m_depthBuffer;
|
||||
int m_imageheight;
|
||||
int m_imagewidth;
|
||||
|
@ -47,7 +47,7 @@ void MultilayerColorOperation::executePixel(float output[4], float x, float y, P
|
||||
{
|
||||
int yi = y;
|
||||
int xi = x;
|
||||
if (this->m_imageBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) {
|
||||
if (this->m_imageFloatBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) {
|
||||
zero_v4(output);
|
||||
}
|
||||
else {
|
||||
@ -66,7 +66,7 @@ void MultilayerColorOperation::executePixel(float output[4], float x, float y, P
|
||||
}
|
||||
else {
|
||||
int offset = (yi * this->getWidth() + xi) * 3;
|
||||
copy_v3_v3(output, &this->m_imageBuffer[offset]);
|
||||
copy_v3_v3(output, &this->m_imageFloatBuffer[offset]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,11 +75,11 @@ void MultilayerValueOperation::executePixel(float output[4], float x, float y, P
|
||||
{
|
||||
int yi = y;
|
||||
int xi = x;
|
||||
if (this->m_imageBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) {
|
||||
if (this->m_imageFloatBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) {
|
||||
output[0] = 0.0f;
|
||||
}
|
||||
else {
|
||||
float result = this->m_imageBuffer[yi * this->getWidth() + xi];
|
||||
float result = this->m_imageFloatBuffer[yi * this->getWidth() + xi];
|
||||
output[0] = result;
|
||||
}
|
||||
}
|
||||
@ -88,11 +88,11 @@ void MultilayerVectorOperation::executePixel(float output[4], float x, float y,
|
||||
{
|
||||
int yi = y;
|
||||
int xi = x;
|
||||
if (this->m_imageBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) {
|
||||
if (this->m_imageFloatBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) {
|
||||
output[0] = 0.0f;
|
||||
}
|
||||
else {
|
||||
int offset = (yi * this->getWidth() + xi) * 3;
|
||||
copy_v3_v3(output, &this->m_imageBuffer[offset]);
|
||||
copy_v3_v3(output, &this->m_imageFloatBuffer[offset]);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user