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:
parent
eb725c5c2d
commit
5f7acf3fb6
1 changed files with 63 additions and 67 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue