summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2011-08-18 06:16:09 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2011-09-02 18:00:04 -0400
commit99ee6e0b2283ebed633f09180f645fc47f74f53b (patch)
tree76ab8d02d8650f1c395230f386ec89e212b83c01
parentd0f84466366aab0555015b322c210514c4465f5d (diff)
Add some fast paths to convert_pixel()fetchers
All the inlining going on makes gcc generate slightly suboptimal code, so add some special cases for the common formats a8r8g8b8, x8r8g8b8, a8, and r5g6b5.
-rw-r--r--pixman/pixman-access.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 189b1915..9ebcc1fa 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -271,6 +271,56 @@ convert_channel (uint32_t pixel, uint32_t def_value,
return (v & ((1 << n_to_bits) - 1)) << to_shift;
}
+static force_inline pixman_bool_t
+convert_special_cases (pixman_format_code_t from, pixman_format_code_t to, uint32_t *pixel)
+{
+ /* A couple of special cases for performance */
+ if ((from == to) || (from == PIXMAN_a8r8g8b8 && to == PIXMAN_x8r8g8b8))
+ {
+ return TRUE;
+ }
+ else if (from == PIXMAN_x8r8g8b8 && to == PIXMAN_a8r8g8b8)
+ {
+ *pixel |= 0xff000000;
+ return TRUE;
+ }
+ else if (from == PIXMAN_a8 && to == PIXMAN_a8r8g8b8)
+ {
+ *pixel <<= 24;
+ return TRUE;
+ }
+ else if (from == PIXMAN_r5g6b5 && to == PIXMAN_a8r8g8b8)
+ {
+ uint32_t r;
+
+ r = ((*pixel << 3) & 0xf8) |
+ ((*pixel << 5) & 0xfc00) |
+ ((*pixel << 8) & 0xf80000);
+
+ r |= (r >> 5) & 0x70007;
+ r |= (r >> 6) & 0x300;
+
+ *pixel = r | 0xff000000;
+ return TRUE;
+ }
+ else if (from == PIXMAN_a8r8g8b8 && to == PIXMAN_a8)
+ {
+ *pixel >>= 24;
+ return TRUE;
+ }
+ else if (from == PIXMAN_a8r8g8b8 && to == PIXMAN_r5g6b5)
+ {
+ *pixel =
+ ((*pixel >> 3) & 0x001f) |
+ ((*pixel >> 5) & 0x07e0) |
+ ((*pixel >> 8) & 0xf800);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static force_inline uint32_t
convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixel)
{
@@ -278,6 +328,9 @@ convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixe
int a_to_shift, r_to_shift, g_to_shift, b_to_shift;
uint32_t a, r, g, b;
+ if (convert_special_cases (from, to, &pixel))
+ return pixel;
+
get_shifts (from, &a_from_shift, &r_from_shift, &g_from_shift, &b_from_shift);
get_shifts (to, &a_to_shift, &r_to_shift, &g_to_shift, &b_to_shift);