From 9f68124263f3bd3bcef56886197b97fc99ad9d82 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 12 May 2010 19:25:41 +0200 Subject: pixman: add generic 565 scanline fetcher --- recipes/xorg-lib/pixman-0.18.0/565-scanline.patch | 257 ++++++++++++++++++++++ recipes/xorg-lib/pixman_0.18.0.bb | 3 +- 2 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 recipes/xorg-lib/pixman-0.18.0/565-scanline.patch diff --git a/recipes/xorg-lib/pixman-0.18.0/565-scanline.patch b/recipes/xorg-lib/pixman-0.18.0/565-scanline.patch new file mode 100644 index 0000000000..8461a46a12 --- /dev/null +++ b/recipes/xorg-lib/pixman-0.18.0/565-scanline.patch @@ -0,0 +1,257 @@ +From deef1daf5896062f47fa61b94e1e77c7c0041820 Mon Sep 17 00:00:00 2001 +From: Siarhei Siamashka +Date: Fri, 04 Dec 2009 16:49:19 +0000 +Subject: A copy-paste version of 16bpp bilinear scanline fetcher + +--- +diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c +index 3d78ff0..1656975 100644 +--- a/pixman/pixman-bits-image.c ++++ b/pixman/pixman-bits-image.c +@@ -535,6 +535,212 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima, + *buffer++ = 0; + } + ++static void ++bits_image_fetch_bilinear_no_repeat_0565 (pixman_image_t * ima, ++ int offset, ++ int line, ++ int width, ++ uint32_t * buffer, ++ const uint32_t * mask, ++ uint32_t mask_bits) ++{ ++ bits_image_t *bits = &ima->bits; ++ pixman_fixed_t x_top, x_bottom, x; ++ pixman_fixed_t ux_top, ux_bottom, ux; ++ pixman_vector_t v; ++ uint32_t top_mask, bottom_mask; ++ uint16_t *top_row; ++ uint16_t *bottom_row; ++ uint32_t *end; ++ uint16_t zero[2] = { 0, 0 }; ++ int y, y1, y2; ++ int disty; ++ int mask_inc; ++ int w; ++ ++ /* reference point is the center of the pixel */ ++ v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; ++ v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; ++ v.vector[2] = pixman_fixed_1; ++ ++ if (!pixman_transform_point_3d (bits->common.transform, &v)) ++ return; ++ ++ ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0]; ++ x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2; ++ ++ y = v.vector[1] - pixman_fixed_1/2; ++ disty = (y >> 8) & 0xff; ++ ++ /* Load the pointers to the first and second lines from the source ++ * image that bilinear code must read. ++ * ++ * The main trick in this code is about the check if any line are ++ * outside of the image; ++ * ++ * When I realize that a line (any one) is outside, I change ++ * the pointer to a dummy area with zeros. Once I change this, I ++ * must be sure the pointer will not change, so I set the ++ * variables to each pointer increments inside the loop. ++ */ ++ y1 = pixman_fixed_to_int (y); ++ y2 = y1 + 1; ++ ++ if (y1 < 0 || y1 >= bits->height) ++ { ++ top_row = zero; ++ x_top = 0; ++ ux_top = 0; ++ } ++ else ++ { ++ top_row = bits->bits + y1 * bits->rowstride; ++ x_top = x; ++ ux_top = ux; ++ } ++ ++ if (y2 < 0 || y2 >= bits->height) ++ { ++ bottom_row = zero; ++ x_bottom = 0; ++ ux_bottom = 0; ++ } ++ else ++ { ++ bottom_row = bits->bits + y2 * bits->rowstride; ++ x_bottom = x; ++ ux_bottom = ux; ++ } ++ ++ /* Instead of checking whether the operation uses the mast in ++ * each loop iteration, verify this only once and prepare the ++ * variables to make the code smaller inside the loop. ++ */ ++ if (!mask) ++ { ++ mask_inc = 0; ++ mask_bits = 1; ++ mask = &mask_bits; ++ } ++ else ++ { ++ /* If have a mask, prepare the variables to check it */ ++ mask_inc = 1; ++ } ++ ++ /* If both are zero, then the whole thing is zero */ ++ if (top_row == zero && bottom_row == zero) ++ { ++ memset (buffer, 0, width * sizeof (uint32_t)); ++ return; ++ } ++ else ++ { ++ if (top_row == zero) ++ { ++ top_mask = 0; ++ bottom_mask = 0xff000000; ++ } ++ else if (bottom_row == zero) ++ { ++ top_mask = 0xff000000; ++ bottom_mask = 0; ++ } ++ else ++ { ++ top_mask = 0xff000000; ++ bottom_mask = 0xff000000; ++ } ++ } ++ ++ end = buffer + width; ++ ++ /* Zero fill to the left of the image */ ++ while (buffer < end && x < pixman_fixed_minus_1) ++ { ++ *buffer++ = 0; ++ x += ux; ++ x_top += ux_top; ++ x_bottom += ux_bottom; ++ mask += mask_inc; ++ } ++ ++ /* Left edge ++ */ ++ while (buffer < end && x < 0) ++ { ++ uint32_t tr, br; ++ int32_t distx; ++ ++ tr = CONVERT_0565_TO_0888 (top_row[pixman_fixed_to_int (x_top) + 1]) | top_mask; ++ br = CONVERT_0565_TO_0888 (bottom_row[pixman_fixed_to_int (x_bottom) + 1]) | bottom_mask; ++ ++ distx = (x >> 8) & 0xff; ++ ++ *buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty); ++ ++ x += ux; ++ x_top += ux_top; ++ x_bottom += ux_bottom; ++ mask += mask_inc; ++ } ++ ++ /* Main part */ ++ w = pixman_int_to_fixed (bits->width - 1); ++ ++ while (buffer < end && x < w) ++ { ++ if (*mask) ++ { ++ uint32_t tl, tr, bl, br; ++ int32_t distx; ++ ++ tl = CONVERT_0565_TO_0888 (top_row [pixman_fixed_to_int (x_top)]) | top_mask; ++ tr = CONVERT_0565_TO_0888 (top_row [pixman_fixed_to_int (x_top) + 1]) | top_mask; ++ bl = CONVERT_0565_TO_0888 (bottom_row [pixman_fixed_to_int (x_bottom)]) | bottom_mask; ++ br = CONVERT_0565_TO_0888 (bottom_row [pixman_fixed_to_int (x_bottom) + 1]) | bottom_mask; ++ ++ distx = (x >> 8) & 0xff; ++ ++ *buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty); ++ } ++ ++ buffer++; ++ x += ux; ++ x_top += ux_top; ++ x_bottom += ux_bottom; ++ mask += mask_inc; ++ } ++ ++ /* Right Edge */ ++ w = pixman_int_to_fixed (bits->width); ++ while (buffer < end && x < w) ++ { ++ if (*mask) ++ { ++ uint32_t tl, bl; ++ int32_t distx; ++ ++ tl = CONVERT_0565_TO_0888 (top_row [pixman_fixed_to_int (x_top)]) | top_mask; ++ bl = CONVERT_0565_TO_0888 (bottom_row [pixman_fixed_to_int (x_bottom)]) | bottom_mask; ++ ++ distx = (x >> 8) & 0xff; ++ ++ *buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty); ++ } ++ ++ buffer++; ++ x += ux; ++ x_top += ux_top; ++ x_bottom += ux_bottom; ++ mask += mask_inc; ++ } ++ ++ /* Zero fill to the left of the image */ ++ while (buffer < end) ++ *buffer++ = 0; ++} ++ + static force_inline uint32_t + bits_image_fetch_pixel_convolution (bits_image_t *image, + pixman_fixed_t x, +@@ -917,14 +1123,26 @@ bits_image_property_changed (pixman_image_t *image) + (bits->common.filter == PIXMAN_FILTER_BILINEAR || + bits->common.filter == PIXMAN_FILTER_GOOD || + bits->common.filter == PIXMAN_FILTER_BEST) && +- bits->common.repeat == PIXMAN_REPEAT_NONE && +- (bits->format == PIXMAN_a8r8g8b8 || +- bits->format == PIXMAN_x8r8g8b8)) ++ bits->common.repeat == PIXMAN_REPEAT_NONE) + { + image->common.get_scanline_64 = + _pixman_image_get_scanline_generic_64; +- image->common.get_scanline_32 = +- bits_image_fetch_bilinear_no_repeat_8888; ++ ++ if (bits->format == PIXMAN_a8r8g8b8 || bits->format == PIXMAN_x8r8g8b8) ++ { ++ image->common.get_scanline_32 = ++ bits_image_fetch_bilinear_no_repeat_8888; ++ } ++ else if (bits->format == PIXMAN_r5g6b5) ++ { ++ image->common.get_scanline_32 = ++ bits_image_fetch_bilinear_no_repeat_0565; ++ } ++ else ++ { ++ image->common.get_scanline_32 = ++ bits_image_fetch_transformed; ++ } + } + else + { +-- +cgit v0.8.3-6-g21f6 diff --git a/recipes/xorg-lib/pixman_0.18.0.bb b/recipes/xorg-lib/pixman_0.18.0.bb index 07966f86a5..b4fba422ef 100644 --- a/recipes/xorg-lib/pixman_0.18.0.bb +++ b/recipes/xorg-lib/pixman_0.18.0.bb @@ -1,5 +1,5 @@ require pixman.inc -PR = "${INC_PR}.1" +PR = "${INC_PR}.2" DEFAULT_PREFERENCE = "-1" DEFAULT_PREFERENCE_shr = "2" @@ -13,6 +13,7 @@ SRC_URI += "\ file://0005-ARM-added-NEON-optimizations-for-fetch-store-r5g6b5-.patch;patch=1 \ file://calloc.patch;patch=1 \ file://tls.patch;patch=1 \ + file://565-scanline.patch;patch=1 \ " SRC_URI[archive.md5sum] = "a4fb870fc325be258089f1683642e976" -- cgit v1.2.3