diff options
author | marha <marha@users.sourceforge.net> | 2013-08-19 09:03:18 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2013-08-19 09:03:18 +0200 |
commit | 854ec4da20ddff9b830be0a7d5b81d8cb4774132 (patch) | |
tree | 223425d84b5ea3727f74546c92dee8b03c074158 /pixman | |
parent | 0659c77949b38440a2a9ba67e1ee9cacef1f3a7f (diff) | |
download | vcxsrv-854ec4da20ddff9b830be0a7d5b81d8cb4774132.tar.gz vcxsrv-854ec4da20ddff9b830be0a7d5b81d8cb4774132.tar.bz2 vcxsrv-854ec4da20ddff9b830be0a7d5b81d8cb4774132.zip |
fontconfig libX11 libXdmcp libxcb xkeyboard-config mesa pixman xserver git update 19 aug 2013
xserver commit fe7463b8ce0de301c2f82b108c93963424f77219
libxcb commit 5648ddd2b97068f549268284129a438a6845e14c
libxcb/xcb-proto commit 56a82005ac388fcb7a4d1c82e07c7e72eaf69a32
xkeyboard-config commit 87c865aee1844b2cc6b1a5a208116dd095f4d76a
libX11 commit 9b291044a240e5b9b031ed814e0c84e53a1c3084
libXdmcp commit 66514a4af7eaa47e8718434356d7efce95e570cf
libXext commit 7378d4bdbd33ed49ed6cfa5c4f73d7527982aab4
libfontenc commit 3acba630d8b57084f7e92c15732408711ed5137a
libXinerama commit 6e1d1dc328ba8162bba2f4694e7f3c706a1491ff
libXau commit 899790011304c4029e15abf410e49ce7cec17e0a
xkbcomp commit 0ebdf47fd4bc434ac3d2339544c022a869510738
pixman commit 3518a0dafa63098d41e466f73d105b7e3e4b12de
xextproto commit f27fcc99d1cf935cc289933326f7d3baacd5107a
randrproto commit ca7cc541c2e43e6c784df19b4583ac35829d2f72
glproto commit 8e3407e02980d088e20041e79bdcdd3737e7827e
mkfontscale commit f48de13423c7300f4da9f61993b624426b38ddc0
xwininfo commit ba0d1b0da21d2dbdd81098ed5778f3792b472e13
libXft commit c5e760a239afc62a1c75e0509868e35957c8df52
libXmu commit d5dac08d65c4865f311cb62c161dbb1300eecd11
libxtrans commit f6a161f2a003f4da0a2e414b4faa0ee0de0c01f0
fontconfig commit 084cf7c44e985dd48c088d921ad0d9a43b0b00b4
mesa commit d13003f544417db6de44c65a0c118bd2b189458a
Diffstat (limited to 'pixman')
-rw-r--r-- | pixman/RELEASING | 2 | ||||
-rw-r--r-- | pixman/pixman/pixman-fast-path.c | 241 | ||||
-rw-r--r-- | pixman/pixman/pixman-general.c | 7 | ||||
-rw-r--r-- | pixman/pixman/pixman-image.c | 3 | ||||
-rw-r--r-- | pixman/pixman/pixman-implementation.c | 1 | ||||
-rw-r--r-- | pixman/pixman/pixman-private.h | 2 | ||||
-rw-r--r-- | pixman/test/Makefile.sources | 1 | ||||
-rw-r--r-- | pixman/test/alpha-loop.c | 7 | ||||
-rw-r--r-- | pixman/test/matrix-test.c | 53 | ||||
-rw-r--r-- | pixman/test/scaling-bench.c | 69 |
10 files changed, 381 insertions, 5 deletions
diff --git a/pixman/RELEASING b/pixman/RELEASING index fbe15813d..657857de2 100644 --- a/pixman/RELEASING +++ b/pixman/RELEASING @@ -55,3 +55,5 @@ Here are the steps to follow to create a new pixman release: You must use "--tags" here; otherwise the new tag will not be pushed out. +8) Change the topic of the #cairo IRC channel on freenode to advertise + the new version. diff --git a/pixman/pixman/pixman-fast-path.c b/pixman/pixman/pixman-fast-path.c index 3982dce8b..2608268d9 100644 --- a/pixman/pixman/pixman-fast-path.c +++ b/pixman/pixman/pixman-fast-path.c @@ -2261,6 +2261,237 @@ fast_write_back_r5g6b5 (pixman_iter_t *iter) } } +typedef struct +{ + int y; + uint64_t * buffer; +} line_t; + +typedef struct +{ + line_t line0; + line_t line1; + pixman_fixed_t y; + pixman_fixed_t x; + uint64_t data[1]; +} bilinear_info_t; + +static void +fetch_horizontal (bits_image_t *image, line_t *line, + int y, pixman_fixed_t x, pixman_fixed_t ux, int n) +{ + uint32_t *bits = image->bits + y * image->rowstride; + int i; + + for (i = 0; i < n; ++i) + { + int x0 = pixman_fixed_to_int (x); + int x1 = x0 + 1; + int32_t dist_x; + + uint32_t left = *(bits + x0); + uint32_t right = *(bits + x1); + + dist_x = pixman_fixed_to_bilinear_weight (x); + dist_x <<= (8 - BILINEAR_INTERPOLATION_BITS); + +#if SIZEOF_LONG <= 4 + { + uint32_t lag, rag, ag; + uint32_t lrb, rrb, rb; + + lag = (left & 0xff00ff00) >> 8; + rag = (right & 0xff00ff00) >> 8; + ag = (lag << 8) + dist_x * (rag - lag); + + lrb = (left & 0x00ff00ff); + rrb = (right & 0x00ff00ff); + rb = (lrb << 8) + dist_x * (rrb - lrb); + + *((uint32_t *)(line->buffer + i)) = ag; + *((uint32_t *)(line->buffer + i) + 1) = rb; + } +#else + { + uint64_t lagrb, ragrb; + uint32_t lag, rag; + uint32_t lrb, rrb; + + lag = (left & 0xff00ff00); + lrb = (left & 0x00ff00ff); + rag = (right & 0xff00ff00); + rrb = (right & 0x00ff00ff); + lagrb = (((uint64_t)lag) << 24) | lrb; + ragrb = (((uint64_t)rag) << 24) | rrb; + + line->buffer[i] = (lagrb << 8) + dist_x * (ragrb - lagrb); + } +#endif + + x += ux; + } + + line->y = y; +} + +static uint32_t * +fast_fetch_bilinear_cover (pixman_iter_t *iter, const uint32_t *mask) +{ + pixman_fixed_t fx, ux; + bilinear_info_t *info = iter->data; + line_t *line0, *line1; + int y0, y1; + int32_t dist_y; + int i; + + fx = info->x; + ux = iter->image->common.transform->matrix[0][0]; + + y0 = pixman_fixed_to_int (info->y); + y1 = y0 + 1; + dist_y = pixman_fixed_to_bilinear_weight (info->y); + dist_y <<= (8 - BILINEAR_INTERPOLATION_BITS); + + line0 = &info->line0; + line1 = &info->line1; + + if (line0->y != y0 || line1->y != y1) + { + if (line0->y == y1 || line1->y == y0) + { + line_t tmp = *line0; + *line0 = *line1; + *line1 = tmp; + } + + if (line0->y != y0) + { + fetch_horizontal ( + &iter->image->bits, line0, y0, fx, ux, iter->width); + } + + if (line1->y != y1) + { + fetch_horizontal ( + &iter->image->bits, line1, y1, fx, ux, iter->width); + } + } + + for (i = 0; i < iter->width; ++i) + { +#if SIZEOF_LONG <= 4 + uint32_t ta, tr, tg, tb; + uint32_t ba, br, bg, bb; + uint32_t tag, trb; + uint32_t bag, brb; + uint32_t a, r, g, b; + + tag = *((uint32_t *)(line0->buffer + i)); + trb = *((uint32_t *)(line0->buffer + i) + 1); + bag = *((uint32_t *)(line1->buffer + i)); + brb = *((uint32_t *)(line1->buffer + i) + 1); + + ta = tag >> 16; + ba = bag >> 16; + a = (ta << 8) + dist_y * (ba - ta); + + tr = trb >> 16; + br = brb >> 16; + r = (tr << 8) + dist_y * (br - tr); + + tg = tag & 0xffff; + bg = bag & 0xffff; + g = (tg << 8) + dist_y * (bg - tg); + + tb = trb & 0xffff; + bb = brb & 0xffff; + b = (tb << 8) + dist_y * (bb - tb); + + a = (a << 8) & 0xff000000; + r = (r << 0) & 0x00ff0000; + g = (g >> 8) & 0x0000ff00; + b = (b >> 16) & 0x000000ff; +#else + uint64_t top = line0->buffer[i]; + uint64_t bot = line1->buffer[i]; + uint64_t tar = (top & 0xffff0000ffff0000ULL) >> 16; + uint64_t bar = (bot & 0xffff0000ffff0000ULL) >> 16; + uint64_t tgb = (top & 0x0000ffff0000ffffULL); + uint64_t bgb = (bot & 0x0000ffff0000ffffULL); + uint64_t ar, gb; + uint32_t a, r, g, b; + + ar = (tar << 8) + dist_y * (bar - tar); + gb = (tgb << 8) + dist_y * (bgb - tgb); + + a = ((ar >> 24) & 0xff000000); + r = ((ar >> 0) & 0x00ff0000); + g = ((gb >> 40) & 0x0000ff00); + b = ((gb >> 16) & 0x000000ff); +#endif + + iter->buffer[i] = a | r | g | b; + } + + info->y += iter->image->common.transform->matrix[1][1]; + + return iter->buffer; +} + +static void +bilinear_cover_iter_fini (pixman_iter_t *iter) +{ + free (iter->data); +} + +static void +fast_bilinear_cover_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *iter_info) +{ + int width = iter->width; + bilinear_info_t *info; + pixman_vector_t v; + + /* Reference point is the center of the pixel */ + v.vector[0] = pixman_int_to_fixed (iter->x) + pixman_fixed_1 / 2; + v.vector[1] = pixman_int_to_fixed (iter->y) + pixman_fixed_1 / 2; + v.vector[2] = pixman_fixed_1; + + if (!pixman_transform_point_3d (iter->image->common.transform, &v)) + goto fail; + + info = malloc (sizeof (*info) + (2 * width - 1) * sizeof (uint64_t)); + if (!info) + goto fail; + + info->x = v.vector[0] - pixman_fixed_1 / 2; + info->y = v.vector[1] - pixman_fixed_1 / 2; + + /* It is safe to set the y coordinates to -1 initially + * because COVER_CLIP_BILINEAR ensures that we will only + * be asked to fetch lines in the [0, height) interval + */ + info->line0.y = -1; + info->line0.buffer = &(info->data[0]); + info->line1.y = -1; + info->line1.buffer = &(info->data[width]); + + iter->get_scanline = fast_fetch_bilinear_cover; + iter->fini = bilinear_cover_iter_fini; + + iter->data = info; + return; + +fail: + /* Something went wrong, either a bad matrix or OOM; in such cases, + * we don't guarantee any particular rendering. + */ + _pixman_log_error ( + FUNC, "Allocation failure or bad matrix, skipping rendering\n"); + + iter->get_scanline = _pixman_iter_get_scanline_noop; + iter->fini = bilinear_cover_iter_fini; +} + #define IMAGE_FLAGS \ (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | \ FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST) @@ -2280,6 +2511,16 @@ static const pixman_iter_info_t fast_iters[] = _pixman_iter_init_bits_stride, fast_dest_fetch_noop, fast_write_back_r5g6b5 }, + { PIXMAN_a8r8g8b8, + (FAST_PATH_STANDARD_FLAGS | + FAST_PATH_SCALE_TRANSFORM | + FAST_PATH_BILINEAR_FILTER | + FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR), + ITER_NARROW | ITER_SRC, + fast_bilinear_cover_iter_init, + NULL, NULL + }, + { PIXMAN_null }, }; diff --git a/pixman/pixman/pixman-general.c b/pixman/pixman/pixman-general.c index 4da5da5e2..6310bff9d 100644 --- a/pixman/pixman/pixman-general.c +++ b/pixman/pixman/pixman-general.c @@ -208,6 +208,13 @@ general_composite_rect (pixman_implementation_t *imp, dest_iter.write_back (&dest_iter); } + if (src_iter.fini) + src_iter.fini (&src_iter); + if (mask_iter.fini) + mask_iter.fini (&mask_iter); + if (dest_iter.fini) + dest_iter.fini (&dest_iter); + if (scanline_buffer != (uint8_t *) stack_scanline_buffer) free (scanline_buffer); } diff --git a/pixman/pixman/pixman-image.c b/pixman/pixman/pixman-image.c index 4f9c2f966..1ff1a4974 100644 --- a/pixman/pixman/pixman-image.c +++ b/pixman/pixman/pixman-image.c @@ -926,6 +926,9 @@ _pixman_image_get_solid (pixman_implementation_t *imp, ITER_NARROW | ITER_SRC, image->common.flags); result = *iter.get_scanline (&iter, NULL); + + if (iter.fini) + iter.fini (&iter); } /* If necessary, convert RGB <--> BGR. */ diff --git a/pixman/pixman/pixman-implementation.c b/pixman/pixman/pixman-implementation.c index 160847ad0..588405451 100644 --- a/pixman/pixman/pixman-implementation.c +++ b/pixman/pixman/pixman-implementation.c @@ -313,6 +313,7 @@ _pixman_implementation_iter_init (pixman_implementation_t *imp, iter->height = height; iter->iter_flags = iter_flags; iter->image_flags = image_flags; + iter->fini = NULL; if (!iter->image) { diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h index af4a0b6e0..964660508 100644 --- a/pixman/pixman/pixman-private.h +++ b/pixman/pixman/pixman-private.h @@ -209,6 +209,7 @@ union pixman_image typedef struct pixman_iter_t pixman_iter_t; typedef uint32_t *(* pixman_iter_get_scanline_t) (pixman_iter_t *iter, const uint32_t *mask); typedef void (* pixman_iter_write_back_t) (pixman_iter_t *iter); +typedef void (* pixman_iter_fini_t) (pixman_iter_t *iter); typedef enum { @@ -255,6 +256,7 @@ struct pixman_iter_t /* These function pointers are initialized by the implementation */ pixman_iter_get_scanline_t get_scanline; pixman_iter_write_back_t write_back; + pixman_iter_fini_t fini; /* These fields are scratch data that implementations can use */ void * data; diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources index b5fc740f3..2fabdb574 100644 --- a/pixman/test/Makefile.sources +++ b/pixman/test/Makefile.sources @@ -33,6 +33,7 @@ OTHERPROGRAMS = \ lowlevel-blt-bench \ radial-perf-test \ check-formats \ + scaling-bench \ $(NULL) # Utility functions diff --git a/pixman/test/alpha-loop.c b/pixman/test/alpha-loop.c index eca761537..4d4384d00 100644 --- a/pixman/test/alpha-loop.c +++ b/pixman/test/alpha-loop.c @@ -8,6 +8,7 @@ int main (int argc, char **argv) { + pixman_image_t *a, *d, *s; uint8_t *alpha; uint32_t *src, *dest; @@ -17,9 +18,9 @@ main (int argc, char **argv) src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4); dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4); - pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH); - pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4); - pixman_image_t *s = pixman_image_create_bits (PIXMAN_a2r10g10b10, WIDTH, HEIGHT, src, WIDTH * 4); + a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH); + d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4); + s = pixman_image_create_bits (PIXMAN_a2r10g10b10, WIDTH, HEIGHT, src, WIDTH * 4); fail_after (5, "Infinite loop detected: 5 seconds without progress\n"); diff --git a/pixman/test/matrix-test.c b/pixman/test/matrix-test.c index 8437dd291..0a5f203f5 100644 --- a/pixman/test/matrix-test.c +++ b/pixman/test/matrix-test.c @@ -70,6 +70,53 @@ pixman_bool_t does_it_fit_fixed_48_16 (__float128 x) #endif +static inline uint32_t +byteswap32 (uint32_t x) +{ + return ((x & ((uint32_t)0xFF << 24)) >> 24) | + ((x & ((uint32_t)0xFF << 16)) >> 8) | + ((x & ((uint32_t)0xFF << 8)) << 8) | + ((x & ((uint32_t)0xFF << 0)) << 24); +} + +static inline uint64_t +byteswap64 (uint64_t x) +{ + return ((x & ((uint64_t)0xFF << 56)) >> 56) | + ((x & ((uint64_t)0xFF << 48)) >> 40) | + ((x & ((uint64_t)0xFF << 40)) >> 24) | + ((x & ((uint64_t)0xFF << 32)) >> 8) | + ((x & ((uint64_t)0xFF << 24)) << 8) | + ((x & ((uint64_t)0xFF << 16)) << 24) | + ((x & ((uint64_t)0xFF << 8)) << 40) | + ((x & ((uint64_t)0xFF << 0)) << 56); +} + +static void +byteswap_transform (pixman_transform_t *t) +{ + int i, j; + + if (is_little_endian ()) + return; + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + t->matrix[i][j] = byteswap32 (t->matrix[i][j]); +} + +static void +byteswap_vector_48_16 (pixman_vector_48_16_t *v) +{ + int i; + + if (is_little_endian ()) + return; + + for (i = 0; i < 3; i++) + v->v[i] = byteswap64 (v->v[i]); +} + uint32_t test_matrix (int testnum, int verbose) { @@ -90,6 +137,8 @@ test_matrix (int testnum, int verbose) #endif prng_randmemset (&ti, sizeof(ti), 0); prng_randmemset (&vi, sizeof(vi), 0); + byteswap_transform (&ti); + byteswap_vector_48_16 (&vi); for (j = 0; j < 3; j++) { @@ -132,8 +181,6 @@ test_matrix (int testnum, int verbose) else transform_ok = pixman_transform_point_31_16 (&ti, &vi, &result_i); - crc32 = compute_crc32 (crc32, &result_i, sizeof(result_i)); - #ifdef HAVE_FLOAT128 /* compare with a reference 128-bit floating point implementation */ for (j = 0; j < 3; j++) @@ -173,6 +220,8 @@ test_matrix (int testnum, int verbose) } } #endif + byteswap_vector_48_16 (&result_i); + crc32 = compute_crc32 (crc32, &result_i, sizeof (result_i)); } return crc32; } diff --git a/pixman/test/scaling-bench.c b/pixman/test/scaling-bench.c new file mode 100644 index 000000000..b39adeff5 --- /dev/null +++ b/pixman/test/scaling-bench.c @@ -0,0 +1,69 @@ +#include <stdlib.h> +#include "utils.h" + +#define SOURCE_WIDTH 320 +#define SOURCE_HEIGHT 240 + +static pixman_image_t * +make_source (void) +{ + size_t n_bytes = (SOURCE_WIDTH + 2) * (SOURCE_HEIGHT + 2) * 4; + uint32_t *data = malloc (n_bytes); + pixman_image_t *source; + + prng_randmemset (data, n_bytes, 0); + + source = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, SOURCE_WIDTH + 2, SOURCE_HEIGHT + 2, + data, + (SOURCE_WIDTH + 2) * 4); + + pixman_image_set_filter (source, PIXMAN_FILTER_BILINEAR, NULL, 0); + + return source; +} + +int +main () +{ + double scale; + pixman_image_t *src; + + prng_srand (23874); + + src = make_source (); + printf ("# %-6s %-22s %-14s %-12s\n", + "ratio", + "resolutions", + "time / ms", + "time per pixel / ns"); + for (scale = 0.1; scale < 10.005; scale += 0.01) + { + int dest_width = SOURCE_WIDTH * scale + 0.5; + int dest_height = SOURCE_HEIGHT * scale + 0.5; + pixman_fixed_t s = (1 / scale) * 65536.0 + 0.5; + pixman_transform_t transform; + pixman_image_t *dest; + double t1, t2; + + pixman_transform_init_scale (&transform, s, s); + pixman_image_set_transform (src, &transform); + + dest = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, dest_width, dest_height, NULL, -1); + + t1 = gettime(); + pixman_image_composite ( + PIXMAN_OP_OVER, src, NULL, dest, + scale, scale, 0, 0, 0, 0, dest_width, dest_height); + t2 = gettime(); + + printf ("%6.2f : %4dx%-4d => %4dx%-4d : %12.4f : %12.4f\n", + scale, SOURCE_WIDTH, SOURCE_HEIGHT, dest_width, dest_height, + (t2 - t1) * 1000, ((t2 - t1) / (dest_width * dest_height)) * 1000000000); + + pixman_image_unref (dest); + } + + return 0; +} |