[cairo] [PATCH] V2 Proposed fix to add detection of pixman supporting GOOD/BEST filters
Bill Spitzak
spitzak at gmail.com
Thu Aug 14 19:17:39 PDT 2014
(Ignore previous one, I managed to send an old patch again. This one
avoids compiler warnings)
This adds the necessary symbols/flags/macros but does not set them.
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 | 30 ++++++++++++++++--------------
src/cairo-xlib-private.h | 3 +++
src/cairo-xlib-source.c | 28 ++++++++++++++--------------
5 files changed, 48 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..31fb267 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,22 @@ _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:
+ 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:
+ case CAIRO_FILTER_GAUSSIAN:
+ default:
+ 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 +433,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..81cc028 100644
--- a/src/cairo-xlib-source.c
+++ b/src/cairo-xlib-source.c
@@ -1093,22 +1093,22 @@ 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_FAST:
+ case CAIRO_FILTER_NEAREST:
+ return CAIRO_RENDER_HAS_PICTURE_TRANSFORM (display) ||
+ _cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL);
+ 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:
+ case CAIRO_FILTER_GAUSSIAN:
+ default:
+ return CAIRO_RENDER_HAS_FILTERS (display);
}
-
- /* 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