pixman: Branch 'master' - 2 commits
Søren Sandmann Pedersen
sandmann at kemper.freedesktop.org
Sun Jul 12 10:35:13 PDT 2009
pixman/pixman-bits-image.c | 58 +++++++++++++++++++++++++++++
pixman/pixman-image.c | 3 +
pixman/pixman-private.h | 1
pixman/pixman-utils.c | 89 ++++++++++-----------------------------------
4 files changed, 83 insertions(+), 68 deletions(-)
New commits:
commit 03c6b294a4517f5dfbc87504fceb3a88efef6a17
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date: Sun Jul 12 03:55:23 2009 -0400
Only destroy the regions when pixman_compute_composite_region() returns TRUE
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index fddfb85..e2abcc2 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -498,9 +498,9 @@ _pixman_walk_composite_region (pixman_implementation_t *imp,
width, height, FALSE, FALSE,
®ion,
composite_rect);
- }
- pixman_region32_fini (®ion);
+ pixman_region32_fini (®ion);
+ }
}
@@ -686,7 +686,8 @@ _pixman_run_fast_path (const pixman_fast_path_t *paths,
pixman_region32_init (®ion);
if (pixman_compute_composite_region32 (
- ®ion, src, mask, dest, src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
+ ®ion, src, mask, dest,
+ src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
{
pixman_box32_t *extents = pixman_region32_extents (®ion);
@@ -705,9 +706,9 @@ _pixman_run_fast_path (const pixman_fast_path_t *paths,
result = TRUE;
}
- }
- pixman_region32_fini (®ion);
+ pixman_region32_fini (®ion);
+ }
}
return result;
commit 2af5f64e938f0d3b81f3f014441cdff650fe5457
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date: Sat Jul 11 03:25:25 2009 -0400
Move workaround logic to pixman-bits-image.c.
Instead of computing whether a workaround is needed on every call to
_pixman_run_fast_path(), just cache this information in the image.
Also, when workarounds are needed, clip against the source geometry to
prevent out of bound reads.
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 8036705..977b172 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -727,6 +727,61 @@ bits_image_fetch_untransformed_64 (pixman_image_t * image, int x, int y,
}
}
+static pixman_bool_t out_of_bounds_workaround = TRUE;
+
+/* Old X servers rely on out-of-bounds accesses when they are asked
+ * to composite with a window as the source. They create a pixman image
+ * pointing to some bogus position in memory, but then they set a clip
+ * region to the position where the actual bits are.
+ *
+ * Due to a bug in old versions of pixman, where it would not clip
+ * against the image bounds when a clip region was set, this would
+ * actually work. So by default we allow certain out-of-bound access
+ * to happen unless explicitly disabled.
+ *
+ * Fixed X servers should call this function to disable the workaround.
+ */
+PIXMAN_EXPORT void
+pixman_disable_out_of_bounds_workaround (void)
+{
+ out_of_bounds_workaround = FALSE;
+}
+
+static pixman_bool_t
+source_image_needs_out_of_bounds_workaround (bits_image_t *image)
+{
+ if (image->common.clip_sources &&
+ image->common.repeat == PIXMAN_REPEAT_NONE &&
+ out_of_bounds_workaround)
+ {
+ const pixman_box32_t *boxes;
+ int n;
+
+ if (!image->common.client_clip)
+ {
+ /* There is no client clip, so the drawable in question
+ * is a window if the clip region is different from the
+ * full drawable
+ */
+ boxes = pixman_region32_rectangles (&image->common.clip_region, &n);
+ if (n == 1)
+ {
+ if (boxes[0].x1 == 0 && boxes[0].y1 == 0 &&
+ boxes[0].x2 == image->width &&
+ boxes[0].y2 == image->height)
+ {
+ /* pixmap */
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void
bits_image_property_changed (pixman_image_t *image)
{
@@ -766,6 +821,9 @@ bits_image_property_changed (pixman_image_t *image)
bits->store_scanline_64 = bits_image_store_scanline_64;
bits->store_scanline_32 = bits_image_store_scanline_32;
+
+ bits->common.need_workaround =
+ source_image_needs_out_of_bounds_workaround (bits);
}
static uint32_t *
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index f95bf3f..d7020f2 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -115,6 +115,7 @@ _pixman_image_allocate (void)
common->client_clip = FALSE;
common->destroy_func = NULL;
common->destroy_data = NULL;
+ common->need_workaround = FALSE;
}
return image;
@@ -381,6 +382,8 @@ pixman_image_set_source_clipping (pixman_image_t *image,
pixman_bool_t clip_sources)
{
image->common.clip_sources = clip_sources;
+
+ image_property_changed (image);
}
/* Unlike all the other property setters, this function does not
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index b0056c4..081d35c 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -71,6 +71,7 @@ struct image_common
pixman_bool_t clip_sources; /* Whether the clip applies when
* the image is used as a source
*/
+ pixman_bool_t need_workaround;
pixman_transform_t *transform;
pixman_repeat_t repeat;
pixman_filter_t filter;
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index c7b97ef..fddfb85 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -30,26 +30,6 @@
#include "pixman-private.h"
-static pixman_bool_t out_of_bounds_workaround = TRUE;
-
-/* Old X servers rely on out-of-bounds accesses when they are asked
- * to composite with a window as the source. They create a pixman image
- * pointing to some bogus position in memory, but then they set a clip
- * region to the position where the actual bits are.
- *
- * Due to a bug in old versions of pixman, where it would not clip
- * against the image bounds when a clip region was set, this would
- * actually work. So by default we allow certain out-of-bound access
- * to happen unless explicitly disabled.
- *
- * Fixed X servers should call this function to disable the workaround.
- */
-PIXMAN_EXPORT void
-pixman_disable_out_of_bounds_workaround (void)
-{
- out_of_bounds_workaround = FALSE;
-}
-
/*
* Computing composite region
*/
@@ -105,13 +85,20 @@ clip_source_image (pixman_region32_t * region,
int dx,
int dy)
{
- /* Source clips are ignored, unless they are explicitly turned on
- * and the clip in question was set by an X client. (Because if
- * the clip was not set by a client, then it is a hierarchy
- * clip and those should always be ignored for sources).
+ /* The workaround lets certain fast paths run even when they
+ * would normally be rejected because of out-of-bounds access.
+ * We need to clip against the source geometry in that case
*/
- if (!picture->common.clip_sources || !picture->common.client_clip)
- return TRUE;
+ if (!picture->common.need_workaround)
+ {
+ /* Source clips are ignored, unless they are explicitly turned on
+ * and the clip in question was set by an X client. (Because if
+ * the clip was not set by a client, then it is a hierarchy
+ * clip and those should always be ignored for sources).
+ */
+ if (!picture->common.clip_sources || !picture->common.client_clip)
+ return TRUE;
+ }
return clip_general_image (region,
&picture->common.clip_region,
@@ -157,7 +144,7 @@ pixman_compute_composite_region32 (pixman_region32_t * region,
* pixman_disable_out_of_bounds_workaround();
*
*/
- if (!(dst_image->common.clip_sources && out_of_bounds_workaround))
+ if (!(dst_image->common.need_workaround))
{
region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
@@ -610,41 +597,6 @@ image_covers (pixman_image_t *image, pixman_box32_t *extents, int x, int y)
return TRUE;
}
-static pixman_bool_t
-source_image_needs_out_of_bounds_workaround (pixman_image_t *image)
-{
- if (!out_of_bounds_workaround)
- return FALSE;
-
- if (image->common.clip_sources &&
- !image->common.client_clip &&
- image->common.have_clip_region)
- {
- const pixman_box32_t *boxes;
- int n;
-
- /* There is no client clip, so the drawable in question
- * is a window if the clip region is different from the
- * full drawable
- */
- boxes = pixman_region32_rectangles (&image->common.clip_region, &n);
- if (n == 1)
- {
- if (boxes[0].x1 == 0 && boxes[0].y1 == 0 &&
- boxes[0].x2 == image->bits.width &&
- boxes[0].y2 == image->bits.height)
- {
- /* pixmap */
- return FALSE;
- }
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
pixman_bool_t
_pixman_run_fast_path (const pixman_fast_path_t *paths,
pixman_implementation_t *imp,
@@ -740,7 +692,7 @@ _pixman_run_fast_path (const pixman_fast_path_t *paths,
if ((image_covers (src, extents, dest_x - src_x, dest_y - src_y) &&
(!mask || image_covers (mask, extents, dest_x - mask_x, dest_y - mask_y))) ||
- source_image_needs_out_of_bounds_workaround (src))
+ src->common.need_workaround)
{
walk_region_internal (imp, op,
src, mask, dest,
More information about the xorg-commit
mailing list