diff options
author | Mathias Gumz <akira at fluxbox dot org> | 2013-01-13 11:37:20 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2013-01-13 11:37:26 (GMT) |
commit | 5f7acf3fb6fd1fd24242ecdee241f439d33ec743 (patch) | |
tree | 1276de19336834c4b9dae81d9b400bdac1b80ba8 | |
parent | eb725c5c2dad513d12c08bba9a68ea640af5e355 (diff) | |
download | fluxbox-5f7acf3fb6fd1fd24242ecdee241f439d33ec743.zip fluxbox-5f7acf3fb6fd1fd24242ecdee241f439d33ec743.tar.bz2 |
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.
-rw-r--r-- | src/FbTk/TextureRender.cc | 126 |
1 files 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) { | |||
872 | return pm_copy.release(); | 872 | return pm_copy.release(); |
873 | } | 873 | } |
874 | 874 | ||
875 | |||
876 | |||
877 | |||
878 | |||
879 | |||
880 | |||
881 | |||
875 | XImage *TextureRender::renderXImage() { | 882 | XImage *TextureRender::renderXImage() { |
876 | 883 | ||
877 | Display *disp = FbTk::App::instance()->display(); | 884 | Display *disp = FbTk::App::instance()->display(); |
878 | XImage *image = | 885 | XImage *image = XCreateImage(disp, |
879 | XCreateImage(disp, | ||
880 | control.visual(), control.depth(), ZPixmap, 0, 0, | 886 | control.visual(), control.depth(), ZPixmap, 0, 0, |
881 | width, height, 32, 0); | 887 | width, height, 32, 0); |
882 | 888 | ||
@@ -903,98 +909,86 @@ XImage *TextureRender::renderXImage() { | |||
903 | 0, 0, 0); | 909 | 0, 0, 0); |
904 | 910 | ||
905 | unsigned char *d = new unsigned char[image->bytes_per_line * (height + 1)]; | 911 | unsigned char *d = new unsigned char[image->bytes_per_line * (height + 1)]; |
906 | register unsigned int x, y, r, g, b, o, offset; | 912 | unsigned int x, y, r, g, b, offset; |
907 | 913 | ||
908 | unsigned char *pixel_data = d, *ppixel_data = d; | 914 | unsigned char *pixel_data = d, *ppixel_data = d; |
909 | unsigned long pixel; | 915 | unsigned long pixel; |
910 | 916 | ||
911 | o = image->bits_per_pixel + ((image->byte_order == MSBFirst) ? 1 : 0); | 917 | unsigned int o = image->bits_per_pixel + ((image->byte_order == MSBFirst) ? 1 : 0); |
918 | |||
919 | |||
920 | #define TRANSFER_PIXELS(pixel_stmt, transfer_stmt) { \ | ||
921 | RGBA _rgba; \ | ||
922 | for (y = 0, offset = 0; y < height; y++) { \ | ||
923 | for (x = 0; x < width; x++, offset++) { \ | ||
924 | _rgba = rgba[offset]; \ | ||
925 | r = red_table[_rgba.r]; \ | ||
926 | g = green_table[_rgba.g]; \ | ||
927 | b = blue_table[_rgba.b]; \ | ||
928 | pixel = pixel_stmt; \ | ||
929 | transfer_stmt; \ | ||
930 | } \ | ||
931 | pixel_data = (ppixel_data += image->bytes_per_line); \ | ||
932 | } } | ||
933 | |||
912 | 934 | ||
913 | switch (control.visual()->c_class) { | 935 | switch (control.visual()->c_class) { |
914 | case StaticColor: | 936 | case StaticColor: |
915 | case PseudoColor: | 937 | case PseudoColor: |
916 | for (y = 0, offset = 0; y < height; y++) { | 938 | TRANSFER_PIXELS((r * cpccpc) + (g * cpc) + b, |
917 | for (x = 0; x < width; x++, offset++) { | 939 | *pixel_data++ = control.colors()[pixel].pixel); |
918 | r = red_table[rgba[offset].r]; | ||
919 | g = green_table[rgba[offset].g]; | ||
920 | b = blue_table[rgba[offset].b]; | ||
921 | |||
922 | pixel_data = (ppixel_data += image->bytes_per_line); | ||
923 | } | ||
924 | } | ||
925 | break; | 940 | break; |
926 | 941 | ||
927 | case TrueColor: | 942 | case TrueColor: |
928 | for (y = 0, offset = 0; y < height; y++) { | 943 | switch (o) { |
929 | for (x = 0; x < width; x++, offset++) { | 944 | case 8: |
930 | r = red_table[rgba[offset].r]; | 945 | TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset), |
931 | g = green_table[rgba[offset].g]; | 946 | *pixel_data++ = pixel); |
932 | b = blue_table[rgba[offset].b]; | 947 | break; |
933 | 948 | case 16: | |
934 | pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset); | 949 | TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset), |
935 | |||
936 | switch (o) { | ||
937 | case 8: // 8bpp | ||
938 | *pixel_data++ = pixel; | ||
939 | break; | ||
940 | |||
941 | case 16: // 16bpp LSB | ||
942 | *pixel_data++ = pixel; | 950 | *pixel_data++ = pixel; |
951 | *pixel_data++ = pixel >> 8); | ||
952 | break; | ||
953 | case 17: | ||
954 | TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset), | ||
943 | *pixel_data++ = pixel >> 8; | 955 | *pixel_data++ = pixel >> 8; |
944 | break; | 956 | *pixel_data++ = pixel); |
945 | 957 | break; | |
946 | case 17: // 16bpp MSB | 958 | case 24: |
947 | *pixel_data++ = pixel >> 8; | 959 | TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset), |
948 | *pixel_data++ = pixel; | ||
949 | break; | ||
950 | |||
951 | case 24: // 24bpp LSB | ||
952 | *pixel_data++ = pixel; | 960 | *pixel_data++ = pixel; |
953 | *pixel_data++ = pixel >> 8; | 961 | *pixel_data++ = pixel >> 8; |
954 | *pixel_data++ = pixel >> 16; | 962 | *pixel_data++ = pixel >> 16); |
955 | break; | 963 | break; |
956 | 964 | case 25: | |
957 | case 25: // 24bpp MSB | 965 | TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset), |
958 | *pixel_data++ = pixel >> 16; | 966 | *pixel_data++ = pixel >> 16; |
959 | *pixel_data++ = pixel >> 8; | 967 | *pixel_data++ = pixel >> 8; |
960 | *pixel_data++ = pixel; | 968 | *pixel_data++ = pixel); |
961 | break; | 969 | break; |
962 | 970 | case 32: | |
963 | case 32: // 32bpp LSB | 971 | TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset), |
964 | *pixel_data++ = pixel; | 972 | *pixel_data++ = pixel; |
965 | *pixel_data++ = pixel >> 8; | 973 | *pixel_data++ = pixel >> 8; |
966 | *pixel_data++ = pixel >> 16; | 974 | *pixel_data++ = pixel >> 16; |
967 | *pixel_data++ = pixel >> 24; | 975 | *pixel_data++ = pixel >> 24); |
968 | break; | 976 | break; |
969 | 977 | case 33: | |
970 | case 33: // 32bpp MSB | 978 | TRANSFER_PIXELS((r << red_offset)|(g << green_offset)|(b << blue_offset), |
971 | *pixel_data++ = pixel >> 24; | 979 | *pixel_data++ = pixel >> 24; |
972 | *pixel_data++ = pixel >> 16; | 980 | *pixel_data++ = pixel >> 16; |
973 | *pixel_data++ = pixel >> 8; | 981 | *pixel_data++ = pixel >> 8; |
974 | *pixel_data++ = pixel; | 982 | *pixel_data++ = pixel); |
975 | break; | 983 | break; |
976 | } | ||
977 | } | ||
978 | |||
979 | pixel_data = (ppixel_data += image->bytes_per_line); | ||
980 | } | 984 | } |
981 | 985 | ||
982 | break; | 986 | break; |
983 | 987 | ||
984 | case StaticGray: | 988 | case StaticGray: |
985 | case GrayScale: | 989 | case GrayScale: |
986 | for (y = 0, offset = 0; y < height; y++) { | 990 | TRANSFER_PIXELS(((r * 30) + (g * 59) + (b * 11)) / 100, |
987 | for (x = 0; x < width; x++, offset++) { | 991 | *pixel_data++ = control.colors()[pixel].pixel); |
988 | r = *(red_table + rgba[offset].r); | ||
989 | g = *(green_table + rgba[offset].g); | ||
990 | b = *(blue_table + rgba[offset].b); | ||
991 | |||
992 | g = ((r * 30) + (g * 59) + (b * 11)) / 100; | ||
993 | *pixel_data++ = control.colors()[g].pixel; | ||
994 | } | ||
995 | |||
996 | pixel_data = (ppixel_data += image->bytes_per_line); | ||
997 | } | ||
998 | 992 | ||
999 | break; | 993 | break; |
1000 | 994 | ||
@@ -1007,6 +1001,8 @@ XImage *TextureRender::renderXImage() { | |||
1007 | return (XImage *) 0; | 1001 | return (XImage *) 0; |
1008 | } | 1002 | } |
1009 | 1003 | ||
1004 | #undef TRANSFER_PIXELS | ||
1005 | |||
1010 | image->data = (char *) d; | 1006 | image->data = (char *) d; |
1011 | return image; | 1007 | return image; |
1012 | } | 1008 | } |