$NetBSD: patch-ba,v 1.1 2011/10/27 16:52:51 drochner Exp $ --- pixman/pixman-image.c.orig 2011-06-09 19:19:44.000000000 +0000 +++ pixman/pixman-image.c @@ -160,27 +160,54 @@ _pixman_image_reset_clip_region (pixman_ image->common.have_clip_region = FALSE; } -/* Executive Summary: This function is a no-op that only exists - * for historical reasons. - * - * There used to be a bug in the X server where it would rely on - * out-of-bounds accesses when it was asked to composite with a - * window as the source. It would create a pixman image pointing - * to some bogus position in memory, but then set a clip region - * to the position where the actual bits were. +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 when the pixman bug was fixed, a workaround was - * added to allow certain out-of-bound accesses. This function disabled - * those workarounds. + * actually work. So by default we allow certain out-of-bound access + * to happen unless explicitly disabled. * - * Since 0.21.2, pixman doesn't do these workarounds anymore, so now - * this function is a no-op. + * 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 && + image->common.have_clip_region && + out_of_bounds_workaround) + { + if (!image->common.client_clip) + { + /* There is no client clip, so if the clip region extends beyond the + * drawable geometry, it must be because the X server generated the + * bogus clip region. + */ + const pixman_box32_t *extents = + pixman_region32_extents (&image->common.clip_region); + + if (extents->x1 >= 0 && extents->x2 <= image->width && + extents->y1 >= 0 && extents->y2 <= image->height) + { + return FALSE; + } + } + + return TRUE; + } + + return FALSE; } static void @@ -332,6 +359,9 @@ compute_image_info (pixman_image_t *imag flags |= FAST_PATH_IS_OPAQUE; } + if (source_image_needs_out_of_bounds_workaround (&image->bits)) + flags |= FAST_PATH_NEEDS_WORKAROUND; + if (image->bits.read_func || image->bits.write_func) flags &= ~FAST_PATH_NO_ACCESSORS;