[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cairo
Subject:    Re: [cairo] bumping pixmap dependency
From:       Thomas Jaeger <thjaeger () gmail ! com>
Date:       2009-06-05 16:06:35
Message-ID: 4A29428B.9050600 () gmail ! com
[Download RAW message or body]

Chris Wilson wrote:
> How ready are your set of patches to enable passing the extended Repeat
> modes to Xorg? Given that 1.10 is now so delayed, I'm inclined to apply
> them if we can have a dependable method of only enabling them for fixed
> drivers.

I don't think there's really a reliable way to tell whether the drivers
are fixed, so in my current version of the patch (attached), I just
assume that xserver-1.7 is good enough.  The artifact that you get if
the driver thinks that EXTEND_PAD means EXTEND_REPEAT are not too bad
anyway when the clipping region is only slightly bigger than the
rendered rectangle.

As for the gradient patches, I'm not so sure anymore that David
Reveman's approach was the right one:  Wouldn't it make more sense to
handle gradients like solid fills and add a new function to
cairo_surface_backend_t for backends that want to accelerate gradient fills.

Tom

["0001-xlib-xcb-Hand-off-EXTEND_PAD-EXTEND_REFLECT-to-Rende.patch" (text/x-patch)]

From e1b17f0ffd66c1fe1c93b627a4d6efc87b924ad2 Mon Sep 17 00:00:00 2001
From: Thomas Jaeger <ThJaeger@gmail.com>
Date: Thu, 19 Feb 2009 12:02:41 -0500
Subject: [PATCH 1/5] xlib, xcb: Hand off EXTEND_PAD/EXTEND_REFLECT to Render

Most drivers and the X server used to have incorrect RepeatPad/RepeatReflect
implementations, forcing cairo to fall back to client-side software rendering,
which is painfully slow due to pixmaps being transfered over the wire.  These
issues are mostly fixed in the drivers (with the exception of radeonhd, whose
developers didn't respond) and the RepeatPad software fallback is implemented
correctly as of pixman-0.15.0, so this patch will hand off composite operations
with EXTEND_PAD/EXTEND_REFLECT source patterns to XRender.

There is no way to detect whether the X server or the drivers use a
broken Render implementation, we make a guess based on the server
version:  It's probably safe to assume that 1.7 X servers will use
fixed drivers and a recent enough version of pixman.
---
 src/cairo-xcb-surface.c          |   15 +++++++++++++--
 src/cairo-xlib-display.c         |   15 +++++++++++----
 src/cairo-xlib-private.h         |    1 +
 src/cairo-xlib-surface-private.h |    1 +
 src/cairo-xlib-surface.c         |   21 ++++++++++++++++++---
 5 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 30a5c6b..78d9a00 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -101,6 +101,8 @@ typedef struct cairo_xcb_surface {
 
 #define CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM(surface)	CAIRO_SURFACE_RENDER_AT_LEAST((surface), \
0, 6)  #define CAIRO_SURFACE_RENDER_HAS_FILTERS(surface)	CAIRO_SURFACE_RENDER_AT_LEAST((surface), \
0, 6) +#define CAIRO_SURFACE_RENDER_HAS_REPEAT_PAD(surface)	CAIRO_SURFACE_RENDER_AT_LEAST((surface), \
0, 10) +#define CAIRO_SURFACE_RENDER_HAS_REPEAT_REFLECT(surface)	CAIRO_SURFACE_RENDER_AT_LEAST((surface), \
0, 10)  
 static void
 _cairo_xcb_surface_ensure_gc (cairo_xcb_surface_t *surface);
@@ -854,13 +856,22 @@ _cairo_xcb_surface_set_attributes (cairo_xcb_surface_t	      \
*surface,  
     switch (attributes->extend) {
     case CAIRO_EXTEND_NONE:
-	_cairo_xcb_surface_set_repeat (surface, 0);
+	_cairo_xcb_surface_set_repeat (surface, XCB_RENDER_REPEAT_NONE);
 	break;
     case CAIRO_EXTEND_REPEAT:
-	_cairo_xcb_surface_set_repeat (surface, 1);
+	_cairo_xcb_surface_set_repeat (surface, XCB_RENDER_REPEAT_NORMAL);
 	break;
     case CAIRO_EXTEND_REFLECT:
+	if (!CAIRO_SURFACE_RENDER_HAS_REPEAT_REFLECT(surface))
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	_cairo_xcb_surface_set_repeat (surface, XCB_RENDER_REPEAT_REFLECT);
+	break;
     case CAIRO_EXTEND_PAD:
+	if (!CAIRO_SURFACE_RENDER_HAS_REPEAT_PAD(surface))
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	_cairo_xcb_surface_set_repeat (surface, XCB_RENDER_REPEAT_PAD);
+	break;
+    default:
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index af244ab..65df2b7 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -285,6 +285,7 @@ _cairo_xlib_display_get (Display *dpy,
 	    sizeof (display->cached_xrender_formats));
 
     display->buggy_repeat = FALSE;
+    display->buggy_pad_reflect = TRUE;
 
     /* This buggy_repeat condition is very complicated because there
      * are multiple X server code bases (with multiple versioning
@@ -331,13 +332,19 @@ _cairo_xlib_display_get (Display *dpy,
      *    (just using VendorRelase < 70000000), as buggy_repeat=TRUE.
      */
     if (strstr (ServerVendor (dpy), "X.Org") != NULL) {
-	if (VendorRelease (dpy) >= 60700000 && VendorRelease (dpy) < 70000000)
-	    display->buggy_repeat = TRUE;
-	if (VendorRelease (dpy) < 10400000)
-	    display->buggy_repeat = TRUE;
+	if (VendorRelease (dpy) >= 60700000) {
+	    if (VendorRelease (dpy) < 70000000)
+		display->buggy_repeat = TRUE;
+	} else {
+	    if (VendorRelease (dpy) < 10400000)
+		display->buggy_repeat = TRUE;
+	    if (VendorRelease (dpy) >= 10699000)
+		display->buggy_pad_reflect = FALSE;
+	}
     } else if (strstr (ServerVendor (dpy), "XFree86") != NULL) {
 	if (VendorRelease (dpy) <= 40500000)
 	    display->buggy_repeat = TRUE;
+
     }
 
     display->next = _cairo_xlib_display_list;
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index b9c84b8..4995bc6 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -73,6 +73,7 @@ struct _cairo_xlib_display {
 
     cairo_xlib_hook_t *close_display_hooks;
     unsigned int buggy_repeat :1;
+    unsigned int buggy_pad_reflect :1;
     unsigned int closed :1;
 };
 
diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h
index fe37e5f..164fe15 100644
--- a/src/cairo-xlib-surface-private.h
+++ b/src/cairo-xlib-surface-private.h
@@ -76,6 +76,7 @@ struct _cairo_xlib_surface {
      * we can reuse the test for now.
      */
     cairo_bool_t buggy_repeat;
+    cairo_bool_t buggy_pad_reflect;
 
     int width;
     int height;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index aa6b3d1..67b4ca6 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1466,7 +1466,15 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t	    \
*surface,  _cairo_xlib_surface_set_repeat (surface, RepeatNormal);
 	break;
     case CAIRO_EXTEND_REFLECT:
+	if (surface->buggy_pad_reflect)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	_cairo_xlib_surface_set_repeat (surface, RepeatReflect);
+	break;
     case CAIRO_EXTEND_PAD:
+	if (surface->buggy_pad_reflect)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	_cairo_xlib_surface_set_repeat (surface, RepeatPad);
+	break;
     default:
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
@@ -1768,7 +1776,9 @@ _cairo_xlib_surface_composite (cairo_operator_t		op,
 					      src_x, src_y,
 					      mask_x, mask_y,
 					      width, height,
-					      CAIRO_PATTERN_ACQUIRE_NO_REFLECT,
+					      dst->buggy_pad_reflect ?
+						      CAIRO_PATTERN_ACQUIRE_NO_REFLECT :
+						      CAIRO_PATTERN_ACQUIRE_NONE,
 					      (cairo_surface_t **) &src,
 					      (cairo_surface_t **) &mask,
 					      &src_attr, &mask_attr);
@@ -2181,7 +2191,9 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	op,
     status = _cairo_pattern_acquire_surface (pattern, &dst->base,
 					     CAIRO_CONTENT_COLOR_ALPHA,
 					     src_x, src_y, width, height,
-					     CAIRO_PATTERN_ACQUIRE_NO_REFLECT,
+					     dst->buggy_pad_reflect ?
+						     CAIRO_PATTERN_ACQUIRE_NO_REFLECT :
+						     CAIRO_PATTERN_ACQUIRE_NONE,
 					     (cairo_surface_t **) &src,
 					     &attributes);
     if (unlikely (status))
@@ -2686,6 +2698,7 @@ _cairo_xlib_surface_create_internal (Display		       *dpy,
 	/* so we can use the XTile fallback */
 	surface->buggy_repeat = TRUE;
     }
+    surface->buggy_pad_reflect = screen_info->display->buggy_pad_reflect;
 
     surface->dst_picture = None;
     surface->src_picture = None;
@@ -4125,7 +4138,9 @@ _cairo_xlib_surface_show_glyphs (void                \
*abstract_dst,  CAIRO_CONTENT_COLOR_ALPHA,
                                                  glyph_extents.x, glyph_extents.y,
                                                  glyph_extents.width, \
                glyph_extents.height,
-						 CAIRO_PATTERN_ACQUIRE_NO_REFLECT,
+						 dst->buggy_pad_reflect ?
+							 CAIRO_PATTERN_ACQUIRE_NO_REFLECT :
+							 CAIRO_PATTERN_ACQUIRE_NONE,
                                                  (cairo_surface_t **) &src,
                                                  &attributes);
         if (unlikely (status))
-- 
1.6.3.1



_______________________________________________
cairo mailing list
cairo@cairographics.org
http://lists.cairographics.org/mailman/listinfo/cairo

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic