[PATCH 2/2] cairo-xlib-surface: Avoid slow RGB24 -> RGB16 color conversion in cairo

Holger Hans Peter Freyther zecke at selfish.org
Sat Nov 6 08:45:55 PDT 2010


This is restoring the cairo 1.8 behavior and will use a 24bit
depth xlib-surface when trying to draw a CAIRO_FORMAT_RGB24
surface.
---
 src/cairo-xlib-surface.c |   39 +++++++++++++++++++++++++++------------
 1 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index c74f656..7165977 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -353,12 +353,12 @@ _xrender_format_to_content (XRenderPictFormat *xrender_format)
 }
 
 static cairo_surface_t *
-_cairo_xlib_surface_create_similar (void	       *abstract_src,
-				    cairo_content_t	content,
-				    int			width,
-				    int			height)
+_cairo_xlib_surface_create_similar_clever (cairo_xlib_surface_t		*src,
+					   cairo_content_t		content,
+					   int				width,
+					   int				height,
+					   cairo_image_surface_t 	*image)
 {
-    cairo_xlib_surface_t *src = abstract_src;
     XRenderPictFormat *xrender_format;
     cairo_xlib_surface_t *surface;
     cairo_xlib_display_t *display;
@@ -379,11 +379,16 @@ _cairo_xlib_surface_create_similar (void	       *abstract_src,
      * arbitrarily pick a visual/depth for the similar surface.
      */
     xrender_format = src->xrender_format;
-    if ((xrender_format != NULL &&
-	_xrender_format_to_content (xrender_format) == content) ||
-	(xrender_format =
-	 _cairo_xlib_display_get_xrender_format (display,
-						 _cairo_format_from_content (content))))
+    if (xrender_format) {
+	cairo_content_t src_content = _xrender_format_to_content(xrender_format);
+	if ((image && src_content == content && xrender_format->depth != image->depth) ||
+             src_content != content) {
+		xrender_format = _cairo_xlib_display_get_xrender_format (display,
+						_cairo_format_from_content(content));
+	}
+    }
+
+    if (xrender_format)
     {
 	Visual *visual;
 
@@ -451,6 +456,16 @@ _cairo_xlib_surface_create_similar (void	       *abstract_src,
     return &surface->base;
 }
 
+static cairo_surface_t *
+_cairo_xlib_surface_create_similar (void	       *abstract_src,
+				    cairo_content_t	content,
+				    int			width,
+				    int			height)
+{
+    cairo_xlib_surface_t *src = abstract_src;
+    return _cairo_xlib_surface_create_similar_clever(src, content, width, height, NULL);
+}
+
 static cairo_status_t
 _cairo_xlib_surface_finish (void *abstract_surface)
 {
@@ -1496,9 +1511,9 @@ _cairo_xlib_surface_clone_similar (void			*abstract_surface,
 	    return UNSUPPORTED ("roi too large for xlib");
 
 	clone = (cairo_xlib_surface_t *)
-	    _cairo_xlib_surface_create_similar (surface,
+	    _cairo_xlib_surface_create_similar_clever (surface,
 						image_src->base.content,
-						width, height);
+						width, height, image_src);
 	if (clone == NULL)
 	    return UNSUPPORTED ("unhandled image format, no similar surface");
 
-- 
1.7.3.1


--------------030105070307010302020709--


More information about the cairo mailing list