[PATCH] Proposed fix to add detection of pixman supporting GOOD/BEST filters

Bill Spitzak <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
This adds the necessary flags/symbols/macros, but they are never set.

Note there are some odd differences between xlib and xcb, such as
whether filters and extents matter for gradients. I did not change
this but it may be something to look into.
---
 src/cairo-xcb-connection.c     |   10 ++++++++++
 src/cairo-xcb-private.h        |    6 +++++-
 src/cairo-xcb-surface-render.c |   29 +++++++++++++++--------------
 src/cairo-xlib-private.h       |    3 +++
 src/cairo-xlib-source.c        |   25 +++++++++++--------------
 5 files changed, 44 insertions(+), 29 deletions(-)

diff --git a/src/cairo-xcb-connection.c b/src/cairo-xcb-connection.c
index b48add1..2d51e14 100644
--- a/src/cairo-xcb-connection.c
+++ b/src/cairo-xcb-connection.c
@@ -77,6 +77,8 @@ typedef struct _cairo_xcb_xid {
 
 #define XCB_RENDER_HAS_PICTURE_TRANSFORM(surface)	XCB_RENDER_AT_LEAST((surface), 0, 6)
 #define XCB_RENDER_HAS_FILTERS(surface)			XCB_RENDER_AT_LEAST((surface), 0, 6)
+#define XCB_RENDER_HAS_FILTER_GOOD(surface) FALSE
+#define XCB_RENDER_HAS_FILTER_BEST(surface) FALSE
 
 #define XCB_RENDER_HAS_EXTENDED_REPEAT(surface)	XCB_RENDER_AT_LEAST((surface), 0, 10)
 #define XCB_RENDER_HAS_GRADIENTS(surface)	XCB_RENDER_AT_LEAST((surface), 0, 10)
@@ -390,6 +392,12 @@ _cairo_xcb_connection_query_render (cairo_xcb_connection_t *connection)
     if (XCB_RENDER_HAS_FILTERS (version))
 	connection->flags |= CAIRO_XCB_RENDER_HAS_FILTERS;
 
+    if (XCB_RENDER_HAS_FILTER_GOOD (version))
+	connection->flags |= CAIRO_XCB_RENDER_HAS_FILTER_GOOD;
+
+    if (XCB_RENDER_HAS_FILTER_BEST (version))
+	connection->flags |= CAIRO_XCB_RENDER_HAS_FILTER_BEST;
+
     if (XCB_RENDER_HAS_PDF_OPERATORS (version))
 	connection->flags |= CAIRO_XCB_RENDER_HAS_PDF_OPERATORS;
 
@@ -882,6 +890,8 @@ cairo_xcb_device_debug_cap_xrender_version (cairo_device_t *device,
 			       CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS |
 			       CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM |
 			       CAIRO_XCB_RENDER_HAS_FILTERS |
+			       CAIRO_XCB_RENDER_HAS_FILTER_GOOD |
+			       CAIRO_XCB_RENDER_HAS_FILTER_BEST |
 			       CAIRO_XCB_RENDER_HAS_PDF_OPERATORS |
 			       CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT |
 			       CAIRO_XCB_RENDER_HAS_GRADIENTS);
diff --git a/src/cairo-xcb-private.h b/src/cairo-xcb-private.h
index 134100a..0880cc7 100644
--- a/src/cairo-xcb-private.h
+++ b/src/cairo-xcb-private.h
@@ -247,6 +247,8 @@ enum {
     CAIRO_XCB_RENDER_HAS_PDF_OPERATORS		= 0x0080,
     CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT	= 0x0100,
     CAIRO_XCB_RENDER_HAS_GRADIENTS		= 0x0200,
+    CAIRO_XCB_RENDER_HAS_FILTER_GOOD		= 0x0400,
+    CAIRO_XCB_RENDER_HAS_FILTER_BEST		= 0x0800,
 
     CAIRO_XCB_HAS_SHM				= 0x80000000,
 
@@ -259,7 +261,9 @@ enum {
 			    CAIRO_XCB_RENDER_HAS_FILTERS |
 			    CAIRO_XCB_RENDER_HAS_PDF_OPERATORS |
 			    CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT |
-			    CAIRO_XCB_RENDER_HAS_GRADIENTS,
+			    CAIRO_XCB_RENDER_HAS_GRADIENTS |
+			    CAIRO_XCB_RENDER_HAS_FILTER_GOOD |
+			    CAIRO_XCB_RENDER_HAS_FILTER_BEST,
     CAIRO_XCB_SHM_MASK    = CAIRO_XCB_HAS_SHM
 };
 
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 64bd1c5..abe8a13 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -393,11 +393,6 @@ _pattern_is_supported (uint32_t flags,
     if (pattern->type == CAIRO_PATTERN_TYPE_SOLID)
 	return TRUE;
 
-    if (! _cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL)) {
-	if ((flags & CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM) == 0)
-	    return FALSE;
-    }
-
     switch (pattern->extend) {
     default:
 	ASSERT_NOT_REACHED;
@@ -411,14 +406,21 @@ _pattern_is_supported (uint32_t flags,
     }
 
     if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
-	cairo_filter_t filter = pattern->filter;
-	if (! (filter == CAIRO_FILTER_NEAREST || filter == CAIRO_FILTER_FAST)) {
-	    if ((flags & CAIRO_XCB_RENDER_HAS_FILTERS) == 0)
-		return FALSE;
-            /* Filter matrix is not supported in XRender */
-	    if (filter == CAIRO_FILTER_GOOD || filter == CAIRO_FILTER_BEST)
-		return FALSE;
+	switch (pattern->filter) {
+	case CAIRO_FILTER_FAST:
+	case CAIRO_FILTER_NEAREST:
+	case CAIRO_FILTER_GAUSSIAN:
+	    return (flags & CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM) ||
+		_cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL);
+	case CAIRO_FILTER_GOOD:
+	    return flags & CAIRO_XCB_RENDER_HAS_FILTER_GOOD;
+	case CAIRO_FILTER_BEST:
+	    return flags & CAIRO_XCB_RENDER_HAS_FILTER_BEST;
+	case CAIRO_FILTER_BILINEAR:
+	    return flags & CAIRO_XCB_RENDER_HAS_FILTERS;
 	}
+    } else if (pattern->type == CAIRO_PATTERN_TYPE_MESH) {
+	return FALSE;
     } else { /* gradient */
 	if ((flags & CAIRO_XCB_RENDER_HAS_GRADIENTS) == 0)
 	    return FALSE;
@@ -430,9 +432,8 @@ _pattern_is_supported (uint32_t flags,
 	{
 	    return FALSE;
 	}
+	return TRUE;
     }
-
-    return pattern->type != CAIRO_PATTERN_TYPE_MESH;
 }
 
 static void
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index 822c85b..40f4473 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -372,7 +372,10 @@ _cairo_xlib_font_close (cairo_xlib_font_t *font);
 #define CAIRO_RENDER_HAS_TRIFAN(surface)			CAIRO_RENDER_AT_LEAST((surface), 0, 4)
 
 #define CAIRO_RENDER_HAS_PICTURE_TRANSFORM(surface)	CAIRO_RENDER_AT_LEAST((surface), 0, 6)
+/* This is actually a test for BILINEAR filter support: */
 #define CAIRO_RENDER_HAS_FILTERS(surface)	CAIRO_RENDER_AT_LEAST((surface), 0, 6)
+#define CAIRO_RENDER_HAS_FILTER_GOOD(surface) FALSE
+#define CAIRO_RENDER_HAS_FILTER_BEST(surface) FALSE
 
 #define CAIRO_RENDER_HAS_EXTENDED_REPEAT(surface)	CAIRO_RENDER_AT_LEAST((surface), 0, 10)
 #define CAIRO_RENDER_HAS_GRADIENTS(surface)	CAIRO_RENDER_AT_LEAST((surface), 0, 10)
diff --git a/src/cairo-xlib-source.c b/src/cairo-xlib-source.c
index 4326a6f..08683bc 100644
--- a/src/cairo-xlib-source.c
+++ b/src/cairo-xlib-source.c
@@ -1093,22 +1093,19 @@ pattern_is_supported (cairo_xlib_display_t *display,
 	    return FALSE;
     }
 
-    if (! CAIRO_RENDER_HAS_PICTURE_TRANSFORM (display)) {
-	if (!_cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL))
-	    return FALSE;
-    }
-
-    if (! CAIRO_RENDER_HAS_FILTERS (display)) {
-	    /* No filters implies no transforms, so we optimise away BILINEAR */
+    switch (pattern->filter) {
+    case CAIRO_FILTER_GOOD:
+	return CAIRO_RENDER_HAS_FILTER_GOOD (display);
+    case CAIRO_FILTER_BEST:
+	return CAIRO_RENDER_HAS_FILTER_BEST (display);
+    case CAIRO_FILTER_BILINEAR:
+	return CAIRO_RENDER_HAS_FILTERS (display);
+    default: /* FAST, NEAREST, GAUSSIAN */
+	return CAIRO_RENDER_HAS_PICTURE_TRANSFORM (display) ||
+	    _cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL);
     }
-
-    /* Filter matrix is not supported in XRender */
-    if (pattern->filter == CAIRO_FILTER_GOOD ||
-	pattern->filter == CAIRO_FILTER_BEST)
-	return FALSE;
-
-    return TRUE;
 }
+
 cairo_surface_t *
 _cairo_xlib_source_create_for_pattern (cairo_surface_t *_dst,
 				       const cairo_pattern_t *pattern,
-- 
1.7.9.5

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.