From 5f7acf3fb6fd1fd24242ecdee241f439d33ec743 Mon Sep 17 00:00:00 2001
From: Mathias Gumz <akira at fluxbox dot org>
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