Add patch to test new clip rules

This commit is contained in:
Soren Sandmann Pedersen 2009-05-12 04:13:54 +00:00
parent 33c786ceea
commit 78474d616c
2 changed files with 422 additions and 1 deletions

416
new-clip-rules.patch Normal file
View File

@ -0,0 +1,416 @@
commit f7724a23170413f4d33e635e4b156a3bc07067c7
Author: Søren Sandmann Pedersen <sandmann@redhat.com>
Date: Mon May 11 00:36:17 2009 -0400
Simplify clipping rule.
The new rule is:
- Output is clipped to the destination clip region.
- If a source image has the clip_sources property set, then there
is an additional step, after repeating and transforming, but before
compositing, where pixels that are not in the source clip are
rejected. Rejected means no compositing takes place (not that the
pixel is treated as 0). By default no source clipping is taking
place.
The old rules were unclear and inconsistently implemented.
diff --git a/pixman/pixman-compute-region.c b/pixman/pixman-compute-region.c
index a93cee0..077bb7d 100644
--- a/pixman/pixman-compute-region.c
+++ b/pixman/pixman-compute-region.c
@@ -79,43 +79,12 @@ miClipPictureSrc (pixman_region32_t * pRegion,
int dx,
int dy)
{
- /* XXX what to do with clipping from transformed pictures? */
- if (pPicture->common.transform || pPicture->type != BITS)
+ if (!pPicture->common.clip_sources)
return TRUE;
- if (pPicture->common.repeat)
- {
- /* If the clip region was set by a client, then it should be intersected
- * with the composite region since it's interpreted as happening
- * after the repeat algorithm.
- *
- * If the clip region was not set by a client, then it was imposed by
- * boundaries of the pixmap, or by sibling or child windows, which means
- * it should in theory be repeated along. FIXME: we ignore that case.
- * It is only relevant for windows that are (a) clipped by siblings/children
- * and (b) used as source. However this case is not useful anyway due
- * to lack of GraphicsExpose events.
- */
- if (pPicture->common.has_client_clip)
- {
- pixman_region32_translate ( pRegion, dx, dy);
-
- if (!pixman_region32_intersect (pRegion, pRegion,
- pPicture->common.src_clip))
- return FALSE;
-
- pixman_region32_translate ( pRegion, -dx, -dy);
- }
-
- return TRUE;
- }
- else
- {
- return miClipPictureReg (pRegion,
- pPicture->common.src_clip,
- dx,
- dy);
- }
+ return miClipPictureReg (pRegion,
+ &pPicture->common.clip_region,
+ dx, dy);
}
/*
@@ -154,12 +123,16 @@ pixman_compute_composite_region32 (pixman_region32_t * pRegion,
return FALSE;
}
/* clip against dst */
- if (!miClipPictureReg (pRegion, &pDst->common.clip_region, 0, 0))
+ if (pDst->common.have_clip_region)
{
- pixman_region32_fini (pRegion);
- return FALSE;
+ if (!miClipPictureReg (pRegion, &pDst->common.clip_region, 0, 0))
+ {
+ pixman_region32_fini (pRegion);
+ return FALSE;
+ }
}
- if (pDst->common.alpha_map)
+
+ if (pDst->common.alpha_map && pDst->common.alpha_map->common.have_clip_region)
{
if (!miClipPictureReg (pRegion, &pDst->common.alpha_map->common.clip_region,
-pDst->common.alpha_origin.x,
@@ -170,12 +143,15 @@ pixman_compute_composite_region32 (pixman_region32_t * pRegion,
}
}
/* clip against src */
- if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc))
+ if (pSrc->common.have_clip_region)
{
- pixman_region32_fini (pRegion);
- return FALSE;
+ if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc))
+ {
+ pixman_region32_fini (pRegion);
+ return FALSE;
+ }
}
- if (pSrc->common.alpha_map)
+ if (pSrc->common.alpha_map && pSrc->common.alpha_map->common.have_clip_region)
{
if (!miClipPictureSrc (pRegion, (pixman_image_t *)pSrc->common.alpha_map,
xDst - (xSrc + pSrc->common.alpha_origin.x),
@@ -186,14 +162,14 @@ pixman_compute_composite_region32 (pixman_region32_t * pRegion,
}
}
/* clip against mask */
- if (pMask)
+ if (pMask && pMask->common.have_clip_region)
{
if (!miClipPictureSrc (pRegion, pMask, xDst - xMask, yDst - yMask))
{
pixman_region32_fini (pRegion);
return FALSE;
}
- if (pMask->common.alpha_map)
+ if (pMask->common.alpha_map && pMask->common.alpha_map->common.have_clip_region)
{
if (!miClipPictureSrc (pRegion, (pixman_image_t *)pMask->common.alpha_map,
xDst - (xMask + pMask->common.alpha_origin.x),
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index bd52f25..5ae55dd 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -81,10 +81,8 @@ allocate_image (void)
{
image_common_t *common = &image->common;
- pixman_region32_init (&common->full_region);
pixman_region32_init (&common->clip_region);
- common->src_clip = &common->full_region;
- common->has_client_clip = FALSE;
+ common->clip_sources = FALSE;
common->transform = NULL;
common->repeat = PIXMAN_REPEAT_NONE;
common->filter = PIXMAN_FILTER_NEAREST;
@@ -120,7 +118,6 @@ pixman_image_unref (pixman_image_t *image)
if (common->ref_count == 0)
{
pixman_region32_fini (&common->clip_region);
- pixman_region32_fini (&common->full_region);
if (common->transform)
free (common->transform);
@@ -323,17 +320,7 @@ create_bits (pixman_format_code_t format,
static void
reset_clip_region (pixman_image_t *image)
{
- pixman_region32_fini (&image->common.clip_region);
-
- if (image->type == BITS)
- {
- pixman_region32_init_rect (&image->common.clip_region, 0, 0,
- image->bits.width, image->bits.height);
- }
- else
- {
- pixman_region32_init (&image->common.clip_region);
- }
+ image->common.have_clip_region = FALSE;
}
PIXMAN_EXPORT pixman_image_t *
@@ -374,14 +361,10 @@ pixman_image_create_bits (pixman_format_code_t format,
image->bits.free_me = free_me;
image->bits.rowstride = rowstride_bytes / (int) sizeof (uint32_t); /* we store it in number
- * of uint32_t's
- */
+ * of uint32_t's
+ */
image->bits.indexed = NULL;
- pixman_region32_fini (&image->common.full_region);
- pixman_region32_init_rect (&image->common.full_region, 0, 0,
- image->bits.width, image->bits.height);
-
reset_clip_region (image);
return image;
}
@@ -394,6 +377,8 @@ pixman_image_set_clip_region32 (pixman_image_t *image,
if (region)
{
+ image->common.have_clip_region = TRUE;
+
return pixman_region32_copy (&common->clip_region, region);
}
else
@@ -429,7 +414,7 @@ PIXMAN_EXPORT void
pixman_image_set_has_client_clip (pixman_image_t *image,
pixman_bool_t client_clip)
{
- image->common.has_client_clip = client_clip;
+ /* This function is obsolete - it had to do with source and hierarchy clipping */
}
PIXMAN_EXPORT pixman_bool_t
@@ -506,16 +491,14 @@ pixman_image_set_filter (pixman_image_t *image,
return TRUE;
}
+/* Whether there is an extra step in the pipeline where clips are applied
+ * to source images. Don't use it unless you are X.
+ */
PIXMAN_EXPORT void
pixman_image_set_source_clipping (pixman_image_t *image,
- pixman_bool_t source_clipping)
+ pixman_bool_t clip_sources)
{
- image_common_t *common = &image->common;
-
- if (source_clipping)
- common->src_clip = &common->clip_region;
- else
- common->src_clip = &common->full_region;
+ image->common.clip_sources = clip_sources;
}
/* Unlike all the other property setters, this function does not
@@ -712,11 +695,14 @@ pixman_image_fill_rectangles (pixman_op_t op,
pixman_box32_t *boxes;
pixman_region32_init_rect (&fill_region, rects[i].x, rects[i].y, rects[i].width, rects[i].height);
- if (!pixman_region32_intersect (&fill_region,
- &fill_region,
- &dest->common.clip_region))
- return FALSE;
+ if (dest->common.have_clip_region)
+ {
+ if (!pixman_region32_intersect (&fill_region,
+ &fill_region,
+ &dest->common.clip_region))
+ return FALSE;
+ }
boxes = pixman_region32_rectangles (&fill_region, &n_boxes);
for (j = 0; j < n_boxes; ++j)
diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index 548d38d..4f6ef91 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -1989,7 +1989,6 @@ pixman_image_composite (pixman_op_t op,
&& (pSrc->common.filter == PIXMAN_FILTER_NEAREST)
&& PIXMAN_FORMAT_BPP(pDst->bits.format) == 32
&& pSrc->bits.format == pDst->bits.format
- && pSrc->common.src_clip == &(pSrc->common.full_region)
&& !pSrc->common.read_func && !pSrc->common.write_func
&& !pDst->common.read_func && !pDst->common.write_func)
{
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index debd723..ee0bb0b 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -292,10 +292,9 @@ struct image_common
{
image_type_t type;
int32_t ref_count;
- pixman_region32_t full_region;
- pixman_region32_t clip_region;
- pixman_region32_t *src_clip;
- pixman_bool_t has_client_clip;
+ pixman_region32_t clip_region;
+ pixman_bool_t have_clip_region; /* if FALSE, there is no clip */
+ pixman_bool_t clip_sources; /* Whether clips apply to source images */
pixman_transform_t *transform;
pixman_repeat_t repeat;
pixman_filter_t filter;
diff --git a/pixman/pixman-transformed.c b/pixman/pixman-transformed.c
index 6d695c5..ba45cc6 100644
--- a/pixman/pixman-transformed.c
+++ b/pixman/pixman-transformed.c
@@ -61,17 +61,9 @@ typedef FASTCALL uint32_t (*fetchFromRegionProc)(bits_image_t *pict, int x, int
*/
static force_inline uint32_t
do_fetch (bits_image_t *pict, int x, int y, fetchPixelProc32 fetch,
- pixman_bool_t src_clip,
pixman_bool_t inside_bounds)
{
- if (src_clip)
- {
- if (pixman_region32_contains_point (pict->common.src_clip, x, y,NULL))
- return fetch (pict, x, y);
- else
- return 0;
- }
- else if (inside_bounds)
+ if (inside_bounds)
{
return fetch (pict, x, y);
}
@@ -92,7 +84,6 @@ fetch_nearest (bits_image_t *pict,
fetchPixelProc32 fetch,
pixman_bool_t affine,
pixman_repeat_t repeat,
- pixman_bool_t has_src_clip,
const pixman_vector_t *v)
{
if (!v->vector[2])
@@ -147,7 +138,7 @@ fetch_nearest (bits_image_t *pict,
return 0;
}
- return do_fetch (pict, x, y, fetch, has_src_clip, inside_bounds);
+ return do_fetch (pict, x, y, fetch, inside_bounds);
}
}
@@ -156,7 +147,6 @@ fetch_bilinear (bits_image_t *pict,
fetchPixelProc32 fetch,
pixman_bool_t affine,
pixman_repeat_t repeat,
- pixman_bool_t has_src_clip,
const pixman_vector_t *v)
{
if (!v->vector[2])
@@ -235,10 +225,10 @@ fetch_bilinear (bits_image_t *pict,
return 0;
}
- tl = do_fetch(pict, x1, y1, fetch, has_src_clip, inside_bounds);
- tr = do_fetch(pict, x2, y1, fetch, has_src_clip, inside_bounds);
- bl = do_fetch(pict, x1, y2, fetch, has_src_clip, inside_bounds);
- br = do_fetch(pict, x2, y2, fetch, has_src_clip, inside_bounds);
+ tl = do_fetch(pict, x1, y1, fetch, inside_bounds);
+ tr = do_fetch(pict, x2, y1, fetch, inside_bounds);
+ bl = do_fetch(pict, x1, y2, fetch, inside_bounds);
+ br = do_fetch(pict, x2, y2, fetch, inside_bounds);
ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
@@ -317,6 +307,8 @@ fbFetchTransformed_Convolution(bits_image_t * pict, int width, uint32_t *buffer,
for (x = x1; x < x2; x++) {
if (*p) {
int tx;
+ uint32_t c;
+
switch (pict->common.repeat) {
case PIXMAN_REPEAT_NORMAL:
tx = MOD (x, pict->width);
@@ -332,14 +324,13 @@ fbFetchTransformed_Convolution(bits_image_t * pict, int width, uint32_t *buffer,
default:
tx = x;
}
- if (pixman_region32_contains_point (pict->common.src_clip, tx, ty, NULL)) {
- uint32_t c = fetch(pict, tx, ty);
-
- srtot += Red(c) * *p;
- sgtot += Green(c) * *p;
- sbtot += Blue(c) * *p;
- satot += Alpha(c) * *p;
- }
+
+ c = fetch(pict, tx, ty);
+
+ srtot += Red(c) * *p;
+ sgtot += Green(c) * *p;
+ sbtot += Blue(c) * *p;
+ satot += Alpha(c) * *p;
}
p++;
}
@@ -419,7 +410,6 @@ ACCESS(fbFetchTransformed)(bits_image_t * pict, int x, int y, int width,
if (pict->common.filter == PIXMAN_FILTER_NEAREST || pict->common.filter == PIXMAN_FILTER_FAST)
{
fetchPixelProc32 fetch;
- pixman_bool_t src_clip;
int i;
/* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */
@@ -427,12 +417,10 @@ ACCESS(fbFetchTransformed)(bits_image_t * pict, int x, int y, int width,
fetch = ACCESS(pixman_fetchPixelProcForPicture32)(pict);
- src_clip = pict->common.src_clip != &(pict->common.full_region);
-
for ( i = 0; i < width; ++i)
{
if (!mask || mask[i] & maskBits)
- *(buffer + i) = fetch_nearest (pict, fetch, affine, pict->common.repeat, src_clip, &v);
+ *(buffer + i) = fetch_nearest (pict, fetch, affine, pict->common.repeat, &v);
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
@@ -443,7 +431,6 @@ ACCESS(fbFetchTransformed)(bits_image_t * pict, int x, int y, int width,
pict->common.filter == PIXMAN_FILTER_GOOD ||
pict->common.filter == PIXMAN_FILTER_BEST)
{
- pixman_bool_t src_clip;
fetchPixelProc32 fetch;
int i;
@@ -451,12 +438,11 @@ ACCESS(fbFetchTransformed)(bits_image_t * pict, int x, int y, int width,
adjust (&v, &unit, -(pixman_fixed_1 / 2));
fetch = ACCESS(pixman_fetchPixelProcForPicture32)(pict);
- src_clip = pict->common.src_clip != &(pict->common.full_region);
for (i = 0; i < width; ++i)
{
if (!mask || mask[i] & maskBits)
- *(buffer + i) = fetch_bilinear (pict, fetch, affine, pict->common.repeat, src_clip, &v);
+ *(buffer + i) = fetch_bilinear (pict, fetch, affine, pict->common.repeat, &v);
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];

View File

@ -3,7 +3,7 @@
Name: pixman Name: pixman
Version: 0.15.2 Version: 0.15.2
Release: 1%{?dist} Release: 2%{?dist}
Summary: Pixel manipulation library Summary: Pixel manipulation library
Group: System Environment/Libraries Group: System Environment/Libraries
@ -15,6 +15,7 @@ URL: http://xorg.freedesktop.org/archive/individual/lib/%{name}-%{ver
Source0: http://www.cairographics.org/releases/pixman-%{version}.tar.gz Source0: http://www.cairographics.org/releases/pixman-%{version}.tar.gz
Source1: make-pixman-snapshot.sh Source1: make-pixman-snapshot.sh
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Patch0: new-clip-rules.patch
# BuildRequires: automake autoconf libtool pkgconfig # BuildRequires: automake autoconf libtool pkgconfig
@ -32,6 +33,7 @@ Development library for pixman.
%prep %prep
%setup -q %setup -q
%patch0 -p1 -b .new-clip-rules
%build %build
%configure --disable-static %configure --disable-static
@ -61,6 +63,9 @@ rm -rf $RPM_BUILD_ROOT
%{_libdir}/pkgconfig/pixman-1.pc %{_libdir}/pkgconfig/pixman-1.pc
%changelog %changelog
* Tue May 12 2009 Soren Sandmann <ssp@redhat.com> 0.15.2-2
- Add patch to implement new clipping rules.
* Thu Apr 16 2009 Soren Sandmann <ssp@redhat.com> 0.15.2-1 * Thu Apr 16 2009 Soren Sandmann <ssp@redhat.com> 0.15.2-1
- pixman 0.15.2 - pixman 0.15.2