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

List:       cairo
Subject:    [cairo] Filling rectangles on non-RENDER X servers
From:       Billy Biggs <vektor () dumbterm ! net>
Date:       2005-11-02 4:36:23
Message-ID: 20051102043623.GG25276 () dumbterm ! net
[Download RAW message or body]

Attached is a patch which seems to greatly improve the performance of
GTK+ 2.8 applications targeting X servers which do not support RENDER.

  This patch has two problems:

    - It always allocates a new colour, which is expensive.  For
      TrueColor and DirectColor visuals this should be easier to do.
      I'm not sure how best to do this code.
    - It only handles fully opaque colours, while the optimization
      should apply in more (and maybe less) cases depending on the
      operator.

  I think this optimization is pretty important, and would appreciate
advice or help for solving the above issues.

  -Billy


["cairo-no-render-fill-rectangles.diff" (text/plain)]

Index: src/cairo-xlib-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib-surface.c,v
retrieving revision 1.126
diff -p -u -r1.126 cairo-xlib-surface.c
--- src/cairo-xlib-surface.c	2 Nov 2005 00:40:37 -0000	1.126
+++ src/cairo-xlib-surface.c	2 Nov 2005 04:19:50 -0000
@@ -1332,8 +1332,32 @@ _cairo_xlib_surface_fill_rectangles (voi
     cairo_xlib_surface_t *surface = abstract_surface;
     XRenderColor render_color;
 
-    if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface)) {
+	Colormap colormap;
+	XColor xcolor;
+	int i;
+
+	if (color->alpha_short != 0xffff /* && operator != CAIRO_SOURCE*/)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+
+	_cairo_xlib_surface_ensure_gc (surface);
+
+	memset (&xcolor, 0, sizeof (XColor));
+	xcolor.red = color->red_short;
+	xcolor.green = color->green_short;
+	xcolor.blue = color->blue_short;
+	colormap = DefaultColormap (surface->dpy, XScreenNumberOfScreen (surface->screen));
+	XAllocColor (surface->dpy, colormap, &xcolor);
+
+	XSetForeground (surface->dpy, surface->gc, xcolor.pixel);
+
+	for (i = 0; i < num_rects; i++)
+	    XFillRectangle (surface->dpy, surface->drawable, surface->gc,
+			    rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+
+	XFreeColors (surface->dpy, colormap, &xcolor.pixel, 1, 0);
+	return CAIRO_STATUS_SUCCESS;
+    }
 
     render_color.red   = color->red_short;
     render_color.green = color->green_short;


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

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