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

Bill Spitzak spitzak at gmail.com
Thu Aug 14 19:12:38 PDT 2014


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



More information about the cairo mailing list