pixman: Branch 'master' - 3 commits
Alexander Larsson
alexl at kemper.freedesktop.org
Fri Feb 19 12:00:34 PST 2010
pixman/pixman-edge-imp.h | 8 -
pixman/pixman-private.h | 8 +
pixman/pixman-region.c | 256 +++++++++++++++++++++++++++++++++++++++++++++++
pixman/pixman.h | 6 -
test/Makefile.am | 4
test/region-test.c | 49 ++++++++
6 files changed, 319 insertions(+), 12 deletions(-)
New commits:
commit f32d585069e77f09f84de42eda8ed8f6849aab57
Author: Alexander Larsson <alexl at redhat.com>
Date: Fri Feb 19 11:22:52 2010 +0100
Test pixman_region32_init_from_image in region-test
diff --git a/test/Makefile.am b/test/Makefile.am
index 5f6ba13..3229f96 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -13,12 +13,14 @@ TESTPROGRAMS = \
composite
fetch_test_LDADD = $(TEST_LDADD)
-region_test_LDADD = $(TEST_LDADD)
composite_LDADD = $(TEST_LDADD)
trap_crasher_LDADD = $(TEST_LDADD)
oob_test_LDADD = $(TEST_LDADD)
window_test_LDADD = $(TEST_LDADD)
+region_test_LDADD = $(TEST_LDADD)
+region_test_SOURCES = region-test.c utils.c utils.h
+
blitters_test_LDADD = $(TEST_LDADD)
blitters_test_SOURCES = blitters-test.c utils.c utils.h
diff --git a/test/region-test.c b/test/region-test.c
index 3568969..9d5a41e 100644
--- a/test/region-test.c
+++ b/test/region-test.c
@@ -1,7 +1,7 @@
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
-#include "pixman.h"
+#include "utils.h"
int
main ()
@@ -22,8 +22,15 @@ main ()
{ 2, 6, 7, 6 },
{ 4, 1, 6, 1 },
};
- int i;
+ int i, j;
pixman_box32_t *b;
+ pixman_image_t *image, *fill;
+ pixman_color_t white = {
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xffff
+ };
/* This used to go into an infinite loop before pixman-region.c
* was fixed to not use explict "short" variables
@@ -74,5 +81,43 @@ main ()
assert (i == 0);
+ fill = pixman_image_create_solid_fill (&white);
+ for (i = 0; i < 100; i++)
+ {
+ int image_size = 128;
+
+ pixman_region32_init (&r1);
+
+ /* Add some random rectangles */
+ for (j = 0; j < 64; j++)
+ pixman_region32_union_rect (&r1, &r1,
+ lcg_rand_n (image_size),
+ lcg_rand_n (image_size),
+ lcg_rand_n (25),
+ lcg_rand_n (25));
+
+ /* Clip to image size */
+ pixman_region32_init_rect (&r2, 0, 0, image_size, image_size);
+ pixman_region32_intersect (&r1, &r1, &r2);
+ pixman_region32_fini (&r2);
+
+ /* render region to a1 mask */
+ image = pixman_image_create_bits (PIXMAN_a1, image_size, image_size, NULL, 0);
+ pixman_image_set_clip_region32 (image, &r1);
+ pixman_image_composite32 (PIXMAN_OP_SRC,
+ fill, NULL, image,
+ 0, 0, 0, 0, 0, 0,
+ image_size, image_size);
+ pixman_region32_init_from_image (&r2, image);
+
+ pixman_image_unref (image);
+
+ assert (pixman_region32_equal (&r1, &r2));
+ pixman_region32_fini (&r1);
+ pixman_region32_fini (&r2);
+
+ }
+ pixman_image_unref (fill);
+
return 0;
}
commit 48ef4befd88e06e83a583a70f0172f1a08a65cda
Author: Alexander Larsson <alexl at redhat.com>
Date: Mon Feb 15 09:40:50 2010 +0100
Add pixman_region{32}_init_from_image
This creates a region from an image in PIXMAN_a1 format.
diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index 9f7515c..830b458 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -42,6 +42,25 @@
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
+ * Copyright © 1998 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
@@ -2539,3 +2558,240 @@ PREFIX (_init_rects) (region_type_t *region,
return validate (region, &i);
}
+
+#define READ(_ptr) (*(_ptr))
+
+static inline box_type_t *
+bitmap_addrect (region_type_t *reg,
+ box_type_t *r,
+ box_type_t **first_rect,
+ int rx1, int ry1,
+ int rx2, int ry2)
+{
+ if ((rx1 < rx2) && (ry1 < ry2) &&
+ (!(reg->data->numRects &&
+ ((r-1)->y1 == ry1) && ((r-1)->y2 == ry2) &&
+ ((r-1)->x1 <= rx1) && ((r-1)->x2 >= rx2))))
+ {
+ if (!reg->data ||
+ reg->data->numRects == reg->data->size)
+ {
+ if (!pixman_rect_alloc (reg, 1))
+ return NULL;
+ *first_rect = PIXREGION_BOXPTR(reg);
+ r = *first_rect + reg->data->numRects;
+ }
+ r->x1 = rx1;
+ r->y1 = ry1;
+ r->x2 = rx2;
+ r->y2 = ry2;
+ reg->data->numRects++;
+ if (r->x1 < reg->extents.x1)
+ reg->extents.x1 = r->x1;
+ if (r->x2 > reg->extents.x2)
+ reg->extents.x2 = r->x2;
+ r++;
+ }
+ return r;
+}
+
+/* Convert bitmap clip mask into clipping region.
+ * First, goes through each line and makes boxes by noting the transitions
+ * from 0 to 1 and 1 to 0.
+ * Then it coalesces the current line with the previous if they have boxes
+ * at the same X coordinates.
+ * Stride is in number of uint32_t per line.
+ */
+PIXMAN_EXPORT void
+PREFIX (_init_from_image) (region_type_t *region,
+ pixman_image_t *image)
+{
+ uint32_t mask0 = 0xffffffff & ~SCREEN_SHIFT_RIGHT(0xffffffff, 1);
+ box_type_t *first_rect, *rects, *prect_line_start;
+ box_type_t *old_rect, *new_rect;
+ uint32_t *pw, w, *pw_line, *pw_line_end;
+ int irect_prev_start, irect_line_start;
+ int h, base, rx1 = 0, crects;
+ int ib;
+ pixman_bool_t in_box, same;
+ int width, height, stride;
+
+ PREFIX(_init) (region);
+
+ return_if_fail (image->type == BITS);
+ return_if_fail (image->bits.format == PIXMAN_a1);
+
+ pw_line = pixman_image_get_data (image);
+ width = pixman_image_get_width (image);
+ height = pixman_image_get_height (image);
+ stride = pixman_image_get_stride (image) / 4;
+
+ first_rect = PIXREGION_BOXPTR(region);
+ rects = first_rect;
+
+ region->extents.x1 = width - 1;
+ region->extents.x2 = 0;
+ irect_prev_start = -1;
+ for (h = 0; h < height; h++)
+ {
+ pw = pw_line;
+ pw_line += stride;
+ irect_line_start = rects - first_rect;
+
+ /* If the Screen left most bit of the word is set, we're starting in
+ * a box */
+ if (READ(pw) & mask0)
+ {
+ in_box = TRUE;
+ rx1 = 0;
+ }
+ else
+ {
+ in_box = FALSE;
+ }
+
+ /* Process all words which are fully in the pixmap */
+ pw_line_end = pw + (width >> 5);
+ for (base = 0; pw < pw_line_end; base += 32)
+ {
+ w = READ(pw++);
+ if (in_box)
+ {
+ if (!~w)
+ continue;
+ }
+ else
+ {
+ if (!w)
+ continue;
+ }
+ for (ib = 0; ib < 32; ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if (w & mask0)
+ {
+ if (!in_box)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ in_box = TRUE;
+ }
+ }
+ else
+ {
+ if (in_box)
+ {
+ /* end box */
+ rects = bitmap_addrect (region, rects, &first_rect,
+ rx1, h, base + ib, h + 1);
+ if (rects == NULL)
+ goto error;
+ in_box = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = SCREEN_SHIFT_LEFT(w, 1);
+ }
+ }
+
+ if (width & 31)
+ {
+ /* Process final partial word on line */
+ w = READ(pw++);
+ for (ib = 0; ib < (width & 31); ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if (w & mask0)
+ {
+ if (!in_box)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ in_box = TRUE;
+ }
+ }
+ else
+ {
+ if (in_box)
+ {
+ /* end box */
+ rects = bitmap_addrect(region, rects, &first_rect,
+ rx1, h, base + ib, h + 1);
+ if (rects == NULL)
+ goto error;
+ in_box = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = SCREEN_SHIFT_LEFT(w, 1);
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if (in_box)
+ {
+ rects = bitmap_addrect(region, rects, &first_rect,
+ rx1, h, base + (width & 31), h + 1);
+ if (rects == NULL)
+ goto error;
+ }
+ /* if all rectangles on this line have the same x-coords as
+ * those on the previous line, then add 1 to all the previous y2s and
+ * throw away all the rectangles from this line
+ */
+ same = FALSE;
+ if (irect_prev_start != -1)
+ {
+ crects = irect_line_start - irect_prev_start;
+ if (crects != 0 &&
+ crects == ((rects - first_rect) - irect_line_start))
+ {
+ old_rect = first_rect + irect_prev_start;
+ new_rect = prect_line_start = first_rect + irect_line_start;
+ same = TRUE;
+ while (old_rect < prect_line_start)
+ {
+ if ((old_rect->x1 != new_rect->x1) ||
+ (old_rect->x2 != new_rect->x2))
+ {
+ same = FALSE;
+ break;
+ }
+ old_rect++;
+ new_rect++;
+ }
+ if (same)
+ {
+ old_rect = first_rect + irect_prev_start;
+ while (old_rect < prect_line_start)
+ {
+ old_rect->y2 += 1;
+ old_rect++;
+ }
+ rects -= crects;
+ region->data->numRects -= crects;
+ }
+ }
+ }
+ if(!same)
+ irect_prev_start = irect_line_start;
+ }
+ if (!region->data->numRects)
+ {
+ region->extents.x1 = region->extents.x2 = 0;
+ }
+ else
+ {
+ region->extents.y1 = PIXREGION_BOXPTR(region)->y1;
+ region->extents.y2 = PIXREGION_END(region)->y2;
+ if (region->data->numRects == 1)
+ {
+ free (region->data);
+ region->data = NULL;
+ }
+ }
+
+ error:
+ return;
+}
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 03a233e..5009c6d 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -170,6 +170,7 @@ struct pixman_transform
/* forward declaration (sorry) */
struct pixman_box16;
+typedef union pixman_image pixman_image_t;
void pixman_transform_init_identity (struct pixman_transform *matrix);
pixman_bool_t pixman_transform_point_3d (const struct pixman_transform *transform,
@@ -401,6 +402,8 @@ pixman_bool_t pixman_region_init_rects (pixman_region16_t *reg
int count);
void pixman_region_init_with_extents (pixman_region16_t *region,
pixman_box16_t *extents);
+void pixman_region_init_from_image (pixman_region16_t *region,
+ pixman_image_t *image);
void pixman_region_fini (pixman_region16_t *region);
@@ -488,6 +491,8 @@ pixman_bool_t pixman_region32_init_rects (pixman_region32_t *r
int count);
void pixman_region32_init_with_extents (pixman_region32_t *region,
pixman_box32_t *extents);
+void pixman_region32_init_from_image (pixman_region32_t *region,
+ pixman_image_t *image);
void pixman_region32_fini (pixman_region32_t *region);
@@ -561,7 +566,6 @@ const char* pixman_version_string (void);
/*
* Images
*/
-typedef union pixman_image pixman_image_t;
typedef struct pixman_indexed pixman_indexed_t;
typedef struct pixman_gradient_stop pixman_gradient_stop_t;
commit 5dee05fcab16dbd3e2c5e4d85b9edf26cf523e3f
Author: Alexander Larsson <alexl at redhat.com>
Date: Mon Feb 15 09:39:59 2010 +0100
Move SCREEN_SHIFT_LEFT/RIGHT to pixman-private.h
This is needed for later use in other code.
diff --git a/pixman/pixman-edge-imp.h b/pixman/pixman-edge-imp.h
index a30f821..74720d1 100644
--- a/pixman/pixman-edge-imp.h
+++ b/pixman/pixman-edge-imp.h
@@ -79,14 +79,6 @@ RASTERIZE_EDGES (pixman_image_t *image,
#if N_BITS == 1
{
-#ifdef WORDS_BIGENDIAN
-# define SCREEN_SHIFT_LEFT(x,n) ((x) << (n))
-# define SCREEN_SHIFT_RIGHT(x,n) ((x) >> (n))
-#else
-# define SCREEN_SHIFT_LEFT(x,n) ((x) >> (n))
-# define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n))
-#endif
-
#define LEFT_MASK(x) \
(((x) & 0x1f) ? \
SCREEN_SHIFT_RIGHT (0xffffffff, (x) & 0x1f) : 0)
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index c99b101..efc690d 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -749,6 +749,14 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
PIXMAN_FORMAT_G (f) > 8 || \
PIXMAN_FORMAT_B (f) > 8)
+#ifdef WORDS_BIGENDIAN
+# define SCREEN_SHIFT_LEFT(x,n) ((x) << (n))
+# define SCREEN_SHIFT_RIGHT(x,n) ((x) >> (n))
+#else
+# define SCREEN_SHIFT_LEFT(x,n) ((x) >> (n))
+# define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n))
+#endif
+
/*
* Various debugging code
*/
More information about the xorg-commit
mailing list