Optimize inner loop of pixel transfer in TrueColor

Testing bits-per-pixel in the inner loop is suboptimal, especially since
that value does not change. A little helper macro helps to keep the code
readable, also improves the situation for StaticGray and PseudoColor.
This commit is contained in:
Mathias Gumz 2013-01-13 12:37:20 +01:00
parent eb725c5c2d
commit 5f7acf3fb6

View file

@ -872,11 +872,17 @@ Pixmap TextureRender::renderPixmap(const FbTk::Texture &src_texture) {
return pm_copy.release(); return pm_copy.release();
} }
XImage *TextureRender::renderXImage() { XImage *TextureRender::renderXImage() {
Display *disp = FbTk::App::instance()->display(); Display *disp = FbTk::App::instance()->display();
XImage *image = XImage *image = XCreateImage(disp,
XCreateImage(disp,
control.visual(), control.depth(), ZPixmap, 0, 0, control.visual(), control.depth(), ZPixmap, 0, 0,
width, height, 32, 0); width, height, 32, 0);
@ -903,98 +909,86 @@ XImage *TextureRender::renderXImage() {
0, 0, 0); 0, 0, 0);
unsigned char *d = new unsigned char[image->bytes_per_line * (height + 1)]; unsigned char *d = new unsigned char[image->bytes_per_line * (height + 1)];
register unsigned int x, y, r, g, b, o, offset; unsigned int x, y, r, g, b, offset;
unsigned char *pixel_data = d, *ppixel_data = d; unsigned char *pixel_data = d, *ppixel_data = d;
unsigned long pixel; unsigned long pixel;
o = image->bits_per_pixel + ((image->byte_order == MSBFirst) ? 1 : 0); unsigned int o = image->bits_per_pixel + ((image->byte_order == MSBFirst) ? 1 : 0);
#define TRANSFER_PIXELS(pixel_stmt, transfer_stmt) { \
RGBA _rgba; \
for (y = 0, offset = 0; y < height; y++) { \
for (x = 0; x < width; x++, offset++) { \
_rgba = rgba[offset]; \
r = red_table[_rgba.r]; \
g = green_table[_rgba.g]; \
b = blue_table[_rgba.b]; \
pixel = pixel_stmt; \
transfer_stmt; \
} \
pixel_data = (ppixel_data += image->bytes_per_line); \
} }
switch (control.visual()->c_class) { switch (control.visual()->c_class) {
case StaticColor: case StaticColor:
case PseudoColor: case PseudoColor:
for (y = 0, offset = 0; y < height; y++) { TRANSFER_PIXELS((r * cpccpc) + (g * cpc) + b,
for (x = 0; x < width; x++, offset++) { *pixel_data++ = control.colors()[pixel].pixel);
r = red_table[rgba[offset].r];
g = green_table[rgba[offset].g];
b = blue_table[rgba[offset].b];
pixel_data = (ppixel_data += image->bytes_per_line);
}
}
break; break;
case TrueColor: case TrueColor:
for (y = 0, offset = 0; y < height; y++) {
for (x = 0; x < width; x++, offset++) {
r = red_table[rgba[offset].r];
g = green_table[rgba[offset].g];
b = blue_table[rgba[offset].b];
pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset);
switch (o) { switch (o) {
case 8: // 8bpp case 8:
*pixel_data++ = pixel; TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset),
*pixel_data++ = pixel);
break; break;
case 16:
case 16: // 16bpp LSB TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset),
*pixel_data++ = pixel;
*pixel_data++ = pixel >> 8);
break;
case 17:
TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset),
*pixel_data++ = pixel >> 8;
*pixel_data++ = pixel);
break;
case 24:
TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset),
*pixel_data++ = pixel; *pixel_data++ = pixel;
*pixel_data++ = pixel >> 8; *pixel_data++ = pixel >> 8;
*pixel_data++ = pixel >> 16);
break; break;
case 25:
case 17: // 16bpp MSB TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset),
*pixel_data++ = pixel >> 16;
*pixel_data++ = pixel >> 8; *pixel_data++ = pixel >> 8;
*pixel_data++ = pixel; *pixel_data++ = pixel);
break; break;
case 32:
case 24: // 24bpp LSB TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset),
*pixel_data++ = pixel; *pixel_data++ = pixel;
*pixel_data++ = pixel >> 8; *pixel_data++ = pixel >> 8;
*pixel_data++ = pixel >> 16; *pixel_data++ = pixel >> 16;
*pixel_data++ = pixel >> 24);
break; break;
case 33:
case 25: // 24bpp MSB TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset),
*pixel_data++ = pixel >> 16;
*pixel_data++ = pixel >> 8;
*pixel_data++ = pixel;
break;
case 32: // 32bpp LSB
*pixel_data++ = pixel;
*pixel_data++ = pixel >> 8;
*pixel_data++ = pixel >> 16;
*pixel_data++ = pixel >> 24;
break;
case 33: // 32bpp MSB
*pixel_data++ = pixel >> 24; *pixel_data++ = pixel >> 24;
*pixel_data++ = pixel >> 16; *pixel_data++ = pixel >> 16;
*pixel_data++ = pixel >> 8; *pixel_data++ = pixel >> 8;
*pixel_data++ = pixel; *pixel_data++ = pixel);
break; break;
} }
}
pixel_data = (ppixel_data += image->bytes_per_line);
}
break; break;
case StaticGray: case StaticGray:
case GrayScale: case GrayScale:
for (y = 0, offset = 0; y < height; y++) { TRANSFER_PIXELS(((r * 30) + (g * 59) + (b * 11)) / 100,
for (x = 0; x < width; x++, offset++) { *pixel_data++ = control.colors()[pixel].pixel);
r = *(red_table + rgba[offset].r);
g = *(green_table + rgba[offset].g);
b = *(blue_table + rgba[offset].b);
g = ((r * 30) + (g * 59) + (b * 11)) / 100;
*pixel_data++ = control.colors()[g].pixel;
}
pixel_data = (ppixel_data += image->bytes_per_line);
}
break; break;
@ -1007,6 +1001,8 @@ XImage *TextureRender::renderXImage() {
return (XImage *) 0; return (XImage *) 0;
} }
#undef TRANSFER_PIXELS
image->data = (char *) d; image->data = (char *) d;
return image; return image;
} }