[cairo-commit] 3 commits - src/cairo-xcb-private.h src/cairo-xcb-surface.c src/cairo-xcb-surface-private.h src/cairo-xlib-xcb-surface.c util/cairo-trace

Uli Schlachter psychon at kemper.freedesktop.org
Mon Jul 18 01:29:28 PDT 2011


 src/cairo-xcb-private.h         |    1 -
 src/cairo-xcb-surface-private.h |   37 -------------------------------------
 src/cairo-xcb-surface.c         |    2 --
 src/cairo-xlib-xcb-surface.c    |    9 +++++++++
 util/cairo-trace/trace.c        |   16 ++++++++++++----
 5 files changed, 21 insertions(+), 44 deletions(-)

New commits:
commit 43b57d59a1e48125ed41e2a356b698522704c023
Author: Uli Schlachter <psychon at znc.in>
Date:   Sun Jul 17 18:18:21 2011 +0200

    cairo-xcb: Drop some unused definitions/file
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-xcb-private.h b/src/cairo-xcb-private.h
index 6aca5b9..92898b8 100644
--- a/src/cairo-xcb-private.h
+++ b/src/cairo-xcb-private.h
@@ -237,7 +237,6 @@ enum {
     CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT	= 0x0100,
     CAIRO_XCB_RENDER_HAS_GRADIENTS		= 0x0200,
 
-    CAIRO_XCB_HAS_DRI2				= 0x40000000,
     CAIRO_XCB_HAS_SHM				= 0x80000000
 };
 
diff --git a/src/cairo-xcb-surface-private.h b/src/cairo-xcb-surface-private.h
deleted file mode 100644
index 88eee28..0000000
--- a/src/cairo-xcb-surface-private.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Cairo - a vector graphics library with display and print output
- *
- * Copyright © 2009 Intel Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * Contributors(s):
- *	Chris Wilson <chris at chris-wilson.co.uk>
- */
-
-#ifndef CAIRO_XCB_SURFACE_PRIVATE_H
-#define CAIRO_XCB_SURFACE_PRIVATE_H
-
-#include "cairo-xcb-private.h"
-
-#endif
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 92b596e..157c8fb 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -45,8 +45,6 @@
 
 #include "cairo-default-context-private.h"
 
-#define AllPlanes ((unsigned) -1)
-#define CAIRO_ASSUME_PIXMAP 20
 #define XLIB_COORD_MAX 32767
 
 #if CAIRO_HAS_XLIB_XCB_FUNCTIONS
commit 2e264e73df0b5a2f6d6a7f906f483d4a827a5375
Author: Uli Schlachter <psychon at znc.in>
Date:   Sun Jul 17 17:55:26 2011 +0200

    xlib-xcb: Fix an "extension leak"
    
    When the xlib-xcb backend created a new cairo_device_t for a Display*, it called
    XAddExtension to get a callback on XCloseDisplay(). However, when the last
    surface using this device is destroyed, this extension isn't unregistered
    because there is no API for this.
    
    I noticed that gvim was quite slow after a while with xlib-xcb. The reason is
    that xlib has a linked list of registered extensions that it has to walk through
    for various callbacks. Since xlib-xcb caused lots of "dead" extension, this got
    quite slow when there were about 20k entries in this list.
    
    The fix is to make sure that the cairo_device_t isn't finished/destroyed when
    the last surface using it is destroyed. For this, we keep an internal reference
    which is only dropped when the device is finished. This happens when someone
    explicitly calls cairo_device_finish or when our XCloseDisplay hook runs.
    
    The same thing is done by cairo-xlib. I didn't port this over to xlib-xcb
    because at that time I didn't understand why it was needed.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-xlib-xcb-surface.c b/src/cairo-xlib-xcb-surface.c
index 6381e05..335a33a 100644
--- a/src/cairo-xlib-xcb-surface.c
+++ b/src/cairo-xlib-xcb-surface.c
@@ -278,6 +278,8 @@ _cairo_xlib_xcb_display_finish (void *abstract_display)
     display->xcb_device = NULL;
 
     XESetCloseDisplay (display->dpy, display->codes->extension, NULL);
+    /* Drop the reference from _cairo_xlib_xcb_device_create */
+    cairo_device_destroy (&display->base);
 }
 
 static int
@@ -301,6 +303,7 @@ _cairo_xlib_xcb_close_display(Display *dpy, XExtCodes *codes)
 	    /* Make sure the xcb and xlib-xcb devices are finished */
 	    cairo_device_finish (display->xcb_device);
 	    cairo_device_finish (&display->base);
+
 	    cairo_device_destroy (&display->base);
 	    return 0;
 	}
@@ -370,6 +373,12 @@ _cairo_xlib_xcb_device_create (Display *dpy, cairo_device_t *xcb_device)
     _cairo_device_init (&display->base, &_cairo_xlib_xcb_device_backend);
 
     XESetCloseDisplay (dpy, display->codes->extension, _cairo_xlib_xcb_close_display);
+    /* Add a reference for _cairo_xlib_xcb_display_finish. This basically means
+     * that the device's reference count never drops to zero
+     * as long as our Display* is alive. We need this because there is no
+     * "XDelExtension" to undo XAddExtension and having lots of registered
+     * extensions slows down libX11. */
+    cairo_device_reference (&display->base);
 
     display->dpy = dpy;
     display->xcb_device = cairo_device_reference(xcb_device);
commit 0dc63f5bb409de0013bf845f96383cc9dca27980
Author: Uli Schlachter <psychon at znc.in>
Date:   Sat Jul 16 16:47:30 2011 +0200

    cairo-trace: Fix mark-dirty with xcb backend
    
    cairo-xcb's acquire_source_image implementation will attach the image it returns
    as a snapshot to the xcb surface. cairo_surface_mark_dirty_rectangle asserts
    that the surface doesn't have any snapshots attached. cairo-trace will emit the
    surface to the trace when it was marked dirty by drawing it to an image surface.
    
    The combination of these three things caused a failed assertion when cairo-trace
    was used on something which uses xcb/Xlib and which uses mark_dirty.
    I found this with firefox and xlib-xcb.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index b8fd04e..3470c88 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -3584,6 +3584,12 @@ cairo_surface_mark_dirty (cairo_surface_t *surface)
 {
     _enter_trace ();
     _emit_line_info ();
+
+    /* Call cairo before emitting the trace since _emit_surface() might cause
+     * snapshots to be creates while mark_dirty assert()s that there are none.
+     */
+    DLCALL (cairo_surface_mark_dirty, surface);
+
     if (surface != NULL && _write_lock ()) {
 	if (_mark_dirty) {
 	    _emit_surface (surface);
@@ -3593,8 +3599,6 @@ cairo_surface_mark_dirty (cairo_surface_t *surface)
 	    _trace_printf ("%% s%ld mark-dirty\n", _get_surface_id (surface));
 	_write_unlock ();
     }
-
-    DLCALL (cairo_surface_mark_dirty, surface);
     _exit_trace ();
 }
 
@@ -3603,6 +3607,12 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
 				    int x, int y, int width, int height)
 {
     _enter_trace ();
+
+    /* Call cairo before emitting the trace since _emit_surface() might cause
+     * snapshots to be creates while mark_dirty assert()s that there are none.
+     */
+    DLCALL (cairo_surface_mark_dirty_rectangle, surface, x, y, width, height);
+
     _emit_line_info ();
     if (surface != NULL && _write_lock ()) {
 	if (_mark_dirty) {
@@ -3615,8 +3625,6 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
 		           _get_surface_id (surface), x, y, width, height);
 	_write_unlock ();
     }
-
-    DLCALL (cairo_surface_mark_dirty_rectangle, surface, x, y, width, height);
     _exit_trace ();
 }
 


More information about the cairo-commit mailing list