From 5f7acf3fb6fd1fd24242ecdee241f439d33ec743 Mon Sep 17 00:00:00 2001 From: Mathias Gumz Date: Sun, 13 Jan 2013 12:37:20 +0100 Subject: 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. --- src/FbTk/TextureRender.cc | 126 ++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 65 deletions(-) diff --git a/src/FbTk/TextureRender.cc b/src/FbTk/TextureRender.cc index 75c937e..ea126f5 100644 --- a/src/FbTk/TextureRender.cc +++ b/src/FbTk/TextureRender.cc @@ -872,11 +872,17 @@ Pixmap TextureRender::renderPixmap(const FbTk::Texture &src_texture) { return pm_copy.release(); } + + + + + + + XImage *TextureRender::renderXImage() { Display *disp = FbTk::App::instance()->display(); - XImage *image = - XCreateImage(disp, + XImage *image = XCreateImage(disp, control.visual(), control.depth(), ZPixmap, 0, 0, width, height, 32, 0); @@ -903,98 +909,86 @@ XImage *TextureRender::renderXImage() { 0, 0, 0); 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 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) { case StaticColor: case PseudoColor: - 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_data = (ppixel_data += image->bytes_per_line); - } - } + TRANSFER_PIXELS((r * cpccpc) + (g * cpc) + b, + *pixel_data++ = control.colors()[pixel].pixel); break; 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) { - case 8: // 8bpp - *pixel_data++ = pixel; - break; - - case 16: // 16bpp LSB + switch (o) { + case 8: + TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset), + *pixel_data++ = pixel); + break; + case 16: + 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; - break; - - case 17: // 16bpp MSB - *pixel_data++ = pixel >> 8; - *pixel_data++ = pixel; - break; - - case 24: // 24bpp LSB + *pixel_data++ = pixel); + break; + case 24: + TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset), *pixel_data++ = pixel; *pixel_data++ = pixel >> 8; - *pixel_data++ = pixel >> 16; - break; - - case 25: // 24bpp MSB + *pixel_data++ = pixel >> 16); + break; + case 25: + 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); + break; + case 32: + TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset), *pixel_data++ = pixel; *pixel_data++ = pixel >> 8; *pixel_data++ = pixel >> 16; - *pixel_data++ = pixel >> 24; - break; - - case 33: // 32bpp MSB + *pixel_data++ = pixel >> 24); + break; + case 33: + TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset), *pixel_data++ = pixel >> 24; *pixel_data++ = pixel >> 16; *pixel_data++ = pixel >> 8; - *pixel_data++ = pixel; - break; - } - } - - pixel_data = (ppixel_data += image->bytes_per_line); + *pixel_data++ = pixel); + break; } break; case StaticGray: case GrayScale: - 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); - - g = ((r * 30) + (g * 59) + (b * 11)) / 100; - *pixel_data++ = control.colors()[g].pixel; - } - - pixel_data = (ppixel_data += image->bytes_per_line); - } + TRANSFER_PIXELS(((r * 30) + (g * 59) + (b * 11)) / 100, + *pixel_data++ = control.colors()[pixel].pixel); break; @@ -1007,6 +1001,8 @@ XImage *TextureRender::renderXImage() { return (XImage *) 0; } +#undef TRANSFER_PIXELS + image->data = (char *) d; return image; } -- cgit v0.11.2