[cairo-commit] 2 commits - src/cairo-freelist.c src/cairo-freelist-private.h src/cairo-xlib-display.c src/cairo-xlib-private.h src/cairo-xlib-screen.c src/cairo-xlib-surface.c src/cairo-xlib-surface-private.h

Chris Wilson ickle at kemper.freedesktop.org
Tue Sep 1 15:18:00 PDT 2009


 src/cairo-freelist-private.h     |   29 ------
 src/cairo-freelist.c             |   29 ++++++
 src/cairo-xlib-display.c         |  126 +++++++++++++++++++++++++++-
 src/cairo-xlib-private.h         |   88 +++++++++++--------
 src/cairo-xlib-screen.c          |  155 +++++++++++++++-------------------
 src/cairo-xlib-surface-private.h |    3 
 src/cairo-xlib-surface.c         |  173 +++++++++++++++++++++------------------
 7 files changed, 370 insertions(+), 233 deletions(-)

New commits:
commit 7d1eb259f93d3f2f2e754b2b8b90cb88359b477d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Sep 1 23:12:43 2009 +0100

    [xlib] Make xlib_display_t private and rename xlib_screen_info_t
    
    The issue Joonas was trying to solve was the unwanted inclusion of
    the inlines via cairo-freelist-private.h. Unwittingly he included
    cairoint.h from cairo-xlib-private.h instead, a far more heinous crime as
    that causes the boilerplate to try to use the hidden, private symbols.
    Instead we resolve this issue by making the cairo_xlib_display_t structure
    private to cairo-xlib-display.c and provide functions to manipulate the
    abstract data type. Whilst in the vicinity, we rename
    cairo_xlib_screen_info_t to cairo_xlib_screen_t for consistency and
    cleanliness.

diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index d05bfed..0c0ce61 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -38,8 +38,32 @@
 #include "cairo-xlib-private.h"
 #include "cairo-xlib-xrender-private.h"
 
+#include "cairo-freelist-private.h"
+
 #include <X11/Xlibint.h>	/* For XESetCloseDisplay */
 
+struct _cairo_xlib_display {
+    cairo_xlib_display_t *next;
+    cairo_reference_count_t ref_count;
+    cairo_mutex_t mutex;
+
+    Display *display;
+    cairo_xlib_screen_t *screens;
+
+    int render_major;
+    int render_minor;
+    XRenderPictFormat *cached_xrender_formats[CAIRO_FORMAT_A1 + 1];
+
+    cairo_xlib_job_t *workqueue;
+    cairo_freelist_t wq_freelist;
+
+    cairo_xlib_hook_t *close_display_hooks;
+    unsigned int buggy_gradients :1;
+    unsigned int buggy_pad_reflect :1;
+    unsigned int buggy_repeat :1;
+    unsigned int closed :1;
+};
+
 typedef int (*cairo_xlib_error_func_t) (Display     *display,
 					XErrorEvent *event);
 
@@ -71,14 +95,14 @@ _cairo_xlib_remove_close_display_hook_internal (cairo_xlib_display_t *display,
 static void
 _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
 {
-    cairo_xlib_screen_info_t	    *screen;
+    cairo_xlib_screen_t	    *screen;
     cairo_xlib_hook_t		    *hook;
 
     /* call all registered shutdown routines */
     CAIRO_MUTEX_LOCK (display->mutex);
 
     for (screen = display->screens; screen != NULL; screen = screen->next)
-	_cairo_xlib_screen_info_close_display (screen);
+	_cairo_xlib_screen_close_display (screen);
 
     while (TRUE) {
 	hook = display->close_display_hooks;
@@ -99,7 +123,7 @@ _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
 static void
 _cairo_xlib_display_discard_screens (cairo_xlib_display_t *display)
 {
-    cairo_xlib_screen_info_t *screens;
+    cairo_xlib_screen_t *screens;
 
     CAIRO_MUTEX_LOCK (display->mutex);
     screens = display->screens;
@@ -107,10 +131,10 @@ _cairo_xlib_display_discard_screens (cairo_xlib_display_t *display)
     CAIRO_MUTEX_UNLOCK (display->mutex);
 
     while (screens != NULL) {
-	cairo_xlib_screen_info_t *screen = screens;
+	cairo_xlib_screen_t *screen = screens;
 	screens = screen->next;
 
-	_cairo_xlib_screen_info_destroy (screen);
+	_cairo_xlib_screen_destroy (screen);
     }
 }
 
@@ -559,3 +583,95 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t	*display,
 
     return xrender_format;
 }
+
+Display *
+_cairo_xlib_display_get_dpy (cairo_xlib_display_t *display)
+{
+    return display->display;
+}
+
+void
+_cairo_xlib_display_remove_screen (cairo_xlib_display_t *display,
+				   cairo_xlib_screen_t *screen)
+{
+    cairo_xlib_screen_t **prev;
+    cairo_xlib_screen_t *list;
+
+    CAIRO_MUTEX_LOCK (display->mutex);
+    for (prev = &display->screens; (list = *prev); prev = &list->next) {
+	if (list == screen) {
+	    *prev = screen->next;
+	    break;
+	}
+    }
+    CAIRO_MUTEX_UNLOCK (display->mutex);
+}
+
+cairo_status_t
+_cairo_xlib_display_get_screen (cairo_xlib_display_t *display,
+				Screen *screen,
+				cairo_xlib_screen_t **out)
+{
+    cairo_xlib_screen_t *info = NULL, **prev;
+
+    CAIRO_MUTEX_LOCK (display->mutex);
+    if (display->closed) {
+	CAIRO_MUTEX_UNLOCK (display->mutex);
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+    }
+
+    for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) {
+	if (info->screen == screen) {
+	    /*
+	     * MRU the list
+	     */
+	    if (prev != &display->screens) {
+		*prev = info->next;
+		info->next = display->screens;
+		display->screens = info;
+	    }
+	    break;
+	}
+    }
+    CAIRO_MUTEX_UNLOCK (display->mutex);
+
+    *out = info;
+    return CAIRO_STATUS_SUCCESS;
+}
+
+
+void
+_cairo_xlib_display_add_screen (cairo_xlib_display_t *display,
+				cairo_xlib_screen_t *screen)
+{
+    CAIRO_MUTEX_LOCK (display->mutex);
+    screen->next = display->screens;
+    display->screens = screen;
+    CAIRO_MUTEX_UNLOCK (display->mutex);
+}
+
+void
+_cairo_xlib_display_get_xrender_version (cairo_xlib_display_t *display,
+					 int *major, int *minor)
+{
+    *major = display->render_major;
+    *minor = display->render_minor;
+}
+
+cairo_bool_t
+_cairo_xlib_display_has_repeat (cairo_xlib_display_t *display)
+{
+    return ! display->buggy_repeat;
+}
+
+cairo_bool_t
+_cairo_xlib_display_has_reflect (cairo_xlib_display_t *display)
+{
+    return ! display->buggy_pad_reflect;
+}
+
+cairo_bool_t
+_cairo_xlib_display_has_gradients (cairo_xlib_display_t *display)
+{
+    return ! display->buggy_gradients;
+}
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index b980b07..e92bb94 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -41,11 +41,13 @@
 #include "cairo-xlib-xrender-private.h"
 
 #include "cairo-compiler-private.h"
-#include "cairo-freelist-private.h"
 #include "cairo-mutex-private.h"
 #include "cairo-reference-count-private.h"
+#include "cairo-types-private.h"
 
 typedef struct _cairo_xlib_display cairo_xlib_display_t;
+typedef struct _cairo_xlib_screen cairo_xlib_screen_t;
+
 typedef struct _cairo_xlib_hook cairo_xlib_hook_t;
 typedef struct _cairo_xlib_job cairo_xlib_job_t;
 typedef void (*cairo_xlib_notify_func) (Display *, void *);
@@ -56,28 +58,6 @@ struct _cairo_xlib_hook {
     void (*func) (cairo_xlib_display_t *display, void *data);
 };
 
-struct _cairo_xlib_display {
-    cairo_xlib_display_t *next;
-    cairo_reference_count_t ref_count;
-    cairo_mutex_t mutex;
-
-    Display *display;
-    cairo_xlib_screen_info_t *screens;
-
-    int render_major;
-    int render_minor;
-    XRenderPictFormat *cached_xrender_formats[CAIRO_FORMAT_A1 + 1];
-
-    cairo_xlib_job_t *workqueue;
-    cairo_freelist_t wq_freelist;
-
-    cairo_xlib_hook_t *close_display_hooks;
-    unsigned int buggy_gradients :1;
-    unsigned int buggy_pad_reflect :1;
-    unsigned int buggy_repeat :1;
-    unsigned int closed :1;
-};
-
 /* size of color cube */
 #define CUBE_SIZE 6
 /* size of gray ramp */
@@ -92,8 +72,8 @@ typedef struct _cairo_xlib_visual_info {
     uint8_t gray8_to_pseudocolor[256];
 } cairo_xlib_visual_info_t;
 
-struct _cairo_xlib_screen_info {
-    cairo_xlib_screen_info_t *next;
+struct _cairo_xlib_screen {
+    cairo_xlib_screen_t *next;
     cairo_reference_count_t ref_count;
     cairo_mutex_t mutex;
 
@@ -115,10 +95,33 @@ _cairo_xlib_display_get (Display *display, cairo_xlib_display_t **out);
 
 cairo_private cairo_xlib_display_t *
 _cairo_xlib_display_reference (cairo_xlib_display_t *info);
+
 cairo_private void
 _cairo_xlib_display_destroy (cairo_xlib_display_t *info);
 
 cairo_private void
+_cairo_xlib_display_lock (cairo_xlib_display_t *display);
+
+cairo_private void
+_cairo_xlib_display_unlock (cairo_xlib_display_t *display);
+
+cairo_private Display *
+_cairo_xlib_display_get_dpy (cairo_xlib_display_t *info);
+
+cairo_private void
+_cairo_xlib_display_add_screen (cairo_xlib_display_t *display,
+				cairo_xlib_screen_t *screen);
+
+cairo_private cairo_status_t
+_cairo_xlib_display_get_screen (cairo_xlib_display_t *display,
+				Screen *screen,
+				cairo_xlib_screen_t **out);
+
+cairo_private void
+_cairo_xlib_display_remove_screen (cairo_xlib_display_t *display,
+				   cairo_xlib_screen_t *screen);
+
+cairo_private void
 _cairo_xlib_add_close_display_hook (cairo_xlib_display_t *display, cairo_xlib_hook_t *hook);
 
 cairo_private void
@@ -136,40 +139,53 @@ _cairo_xlib_display_queue_resource (cairo_xlib_display_t *display,
 cairo_private void
 _cairo_xlib_display_notify (cairo_xlib_display_t *display);
 
+cairo_private void
+_cairo_xlib_display_get_xrender_version (cairo_xlib_display_t *display,
+					 int *major, int *minor);
+
+cairo_private cairo_bool_t
+_cairo_xlib_display_has_repeat (cairo_xlib_display_t *display);
+
+cairo_private cairo_bool_t
+_cairo_xlib_display_has_reflect (cairo_xlib_display_t *display);
+
+cairo_private cairo_bool_t
+_cairo_xlib_display_has_gradients (cairo_xlib_display_t *display);
+
 cairo_private XRenderPictFormat *
 _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t	*display,
 	                                cairo_format_t		 format);
 
 cairo_private cairo_status_t
-_cairo_xlib_screen_info_get (cairo_xlib_display_t *display,
-			     Screen *screen,
-			     cairo_xlib_screen_info_t **out);
+_cairo_xlib_screen_get (Display *dpy,
+			Screen *screen,
+			cairo_xlib_screen_t **out);
 
-cairo_private cairo_xlib_screen_info_t *
-_cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info);
+cairo_private cairo_xlib_screen_t *
+_cairo_xlib_screen_reference (cairo_xlib_screen_t *info);
 cairo_private void
-_cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info);
+_cairo_xlib_screen_destroy (cairo_xlib_screen_t *info);
 
 cairo_private void
-_cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info);
+_cairo_xlib_screen_close_display (cairo_xlib_screen_t *info);
 
 cairo_private GC
-_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_get_gc (cairo_xlib_screen_t *info,
 			   unsigned int depth,
 			   Drawable drawable,
 			   unsigned int *need_reset);
 
 cairo_private void
-_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_put_gc (cairo_xlib_screen_t *info,
 			   unsigned int depth,
 			   GC gc,
 			   cairo_bool_t reset_clip);
 
 cairo_private cairo_font_options_t *
-_cairo_xlib_screen_get_font_options (cairo_xlib_screen_info_t *info);
+_cairo_xlib_screen_get_font_options (cairo_xlib_screen_t *info);
 
 cairo_private cairo_status_t
-_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_t *info,
 				    Visual *visual,
 				    cairo_xlib_visual_info_t **out);
 
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index e491a33..38e64af 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -144,7 +144,7 @@ get_integer_default (Display    *dpy,
 
 static void
 _cairo_xlib_init_screen_font_options (Display *dpy,
-				      cairo_xlib_screen_info_t *info)
+				      cairo_xlib_screen_t *info)
 {
     cairo_bool_t xft_hinting;
     cairo_bool_t xft_antialias;
@@ -254,8 +254,8 @@ _cairo_xlib_init_screen_font_options (Display *dpy,
     cairo_font_options_set_hint_metrics (&info->font_options, CAIRO_HINT_METRICS_ON);
 }
 
-cairo_xlib_screen_info_t *
-_cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info)
+cairo_xlib_screen_t *
+_cairo_xlib_screen_reference (cairo_xlib_screen_t *info)
 {
     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
 
@@ -265,7 +265,7 @@ _cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info)
 }
 
 void
-_cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info)
+_cairo_xlib_screen_close_display (cairo_xlib_screen_t *info)
 {
     cairo_xlib_visual_info_t **visuals;
     Display *dpy;
@@ -273,7 +273,7 @@ _cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info)
 
     CAIRO_MUTEX_LOCK (info->mutex);
 
-    dpy = info->display->display;
+    dpy = _cairo_xlib_display_get_dpy (info->display);
 
 #if HAS_ATOMIC_OPS
     do {
@@ -297,26 +297,16 @@ _cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info)
 }
 
 void
-_cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
+_cairo_xlib_screen_destroy (cairo_xlib_screen_t *info)
 {
-    cairo_xlib_screen_info_t **prev;
-    cairo_xlib_screen_info_t *list;
-
     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
 
     if (! _cairo_reference_count_dec_and_test (&info->ref_count))
 	return;
 
-    CAIRO_MUTEX_LOCK (info->display->mutex);
-    for (prev = &info->display->screens; (list = *prev); prev = &list->next) {
-	if (list == info) {
-	    *prev = info->next;
-	    break;
-	}
-    }
-    CAIRO_MUTEX_UNLOCK (info->display->mutex);
+    _cairo_xlib_display_remove_screen (info->display, info);
 
-    _cairo_xlib_screen_info_close_display (info);
+    _cairo_xlib_screen_close_display (info);
 
     _cairo_xlib_display_destroy (info->display);
 
@@ -328,77 +318,68 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
 }
 
 cairo_status_t
-_cairo_xlib_screen_info_get (cairo_xlib_display_t *display,
-			     Screen *screen,
-			     cairo_xlib_screen_info_t **out)
+_cairo_xlib_screen_get (Display *dpy,
+			Screen *screen,
+			cairo_xlib_screen_t **out)
 {
-    cairo_xlib_screen_info_t *info = NULL, **prev;
+    cairo_xlib_display_t *display;
+    cairo_xlib_screen_t *info;
+    cairo_status_t status;
 
-    CAIRO_MUTEX_LOCK (display->mutex);
-    if (display->closed) {
-	CAIRO_MUTEX_UNLOCK (display->mutex);
-	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+    status = _cairo_xlib_display_get (dpy, &display);
+    if (likely (status == CAIRO_STATUS_SUCCESS))
+	status = _cairo_xlib_display_get_screen (display, screen, &info);
+    if (unlikely (status))
+	goto CLEANUP_DISPLAY;
+
+    if (info != NULL) {
+	*out = _cairo_xlib_screen_reference (info);
+	goto CLEANUP_DISPLAY;
     }
 
-    for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) {
-	if (info->screen == screen) {
-	    /*
-	     * MRU the list
-	     */
-	    if (prev != &display->screens) {
-		*prev = info->next;
-		info->next = display->screens;
-		display->screens = info;
-	    }
-	    break;
-	}
+    info = malloc (sizeof (cairo_xlib_screen_t));
+    if (unlikely (info == NULL)) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto CLEANUP_DISPLAY;
     }
-    CAIRO_MUTEX_UNLOCK (display->mutex);
 
-    if (info != NULL) {
-	info = _cairo_xlib_screen_info_reference (info);
-    } else {
-	info = malloc (sizeof (cairo_xlib_screen_info_t));
-	if (unlikely (info == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-	CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
-	CAIRO_MUTEX_INIT (info->mutex);
-	info->display = _cairo_xlib_display_reference (display);
-	info->screen = screen;
-	info->has_render = FALSE;
-	info->has_font_options = FALSE;
-	info->gc_depths = 0;
-	memset (info->gc, 0, sizeof (info->gc));
-
-	_cairo_array_init (&info->visuals,
-			   sizeof (cairo_xlib_visual_info_t*));
-
-	if (screen) {
-	    Display *dpy = display->display;
-	    int event_base, error_base;
-
-	    info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
-		    (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
-	}
+    CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
+    CAIRO_MUTEX_INIT (info->mutex);
+    info->display = display;
+    info->screen = screen;
+    info->has_render = FALSE;
+    info->has_font_options = FALSE;
+    info->gc_depths = 0;
+    memset (info->gc, 0, sizeof (info->gc));
+
+    _cairo_array_init (&info->visuals,
+		       sizeof (cairo_xlib_visual_info_t*));
 
-	/* Small window of opportunity for two screen infos for the same
-	 * Screen - just wastes a little bit of memory but should not cause
-	 * any corruption.
-	 */
-	CAIRO_MUTEX_LOCK (display->mutex);
-	info->next = display->screens;
-	display->screens = info;
-	CAIRO_MUTEX_UNLOCK (display->mutex);
+    if (screen) {
+	int event_base, error_base;
+
+	info->has_render =
+	    XRenderQueryExtension (dpy, &event_base, &error_base) &&
+	    (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0);
     }
 
+    /* Small window of opportunity for two screen infos for the same
+     * Screen - just wastes a little bit of memory but should not cause
+     * any corruption.
+     */
+    _cairo_xlib_display_add_screen (display, info);
+
     *out = info;
     return CAIRO_STATUS_SUCCESS;
+
+  CLEANUP_DISPLAY:
+    _cairo_xlib_display_destroy (display);
+    return status;
 }
 
 #if HAS_ATOMIC_OPS
 GC
-_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_get_gc (cairo_xlib_screen_t *info,
 			   unsigned int depth,
 			   Drawable drawable,
 			   unsigned int *dirty)
@@ -438,12 +419,13 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
     }
 
     gcv.graphics_exposures = False;
-    return XCreateGC (info->display->display, drawable,
+    return XCreateGC (_cairo_xlib_display_get_dpy (info->display),
+		      drawable,
 		      GCGraphicsExposures, &gcv);
 }
 
 void
-_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_put_gc (cairo_xlib_screen_t *info,
 			   unsigned int depth,
 			   GC gc,
 			   cairo_bool_t reset_clip)
@@ -485,7 +467,7 @@ out:
 }
 #else
 GC
-_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_get_gc (cairo_xlib_screen_t *info,
 			   unsigned int depth,
 			   Drawable drawable,
 			   unsigned int *dirty)
@@ -510,7 +492,8 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
 	XGCValues gcv;
 
 	gcv.graphics_exposures = False;
-	gc = XCreateGC (info->display->display, drawable,
+	gc = XCreateGC (_cairo_xlib_display_get_dpy (info->display),
+			drawable,
 			GCGraphicsExposures, &gcv);
     }
 
@@ -518,7 +501,7 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
 }
 
 void
-_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_put_gc (cairo_xlib_screen_t *info,
 			   unsigned int depth,
 			   GC gc,
 			   cairo_bool_t reset_clip)
@@ -557,11 +540,11 @@ _cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
 #endif
 
 cairo_status_t
-_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_t *info,
 				    Visual *visual,
 				    cairo_xlib_visual_info_t **out)
 {
-    Display *dpy = info->display->display;
+    Display *dpy = _cairo_xlib_display_get_dpy (info->display);
     cairo_xlib_visual_info_t **visuals, *ret = NULL;
     cairo_status_t status;
     int i, n_visuals;
@@ -617,19 +600,19 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
 }
 
 cairo_font_options_t *
-_cairo_xlib_screen_get_font_options (cairo_xlib_screen_info_t *info)
+_cairo_xlib_screen_get_font_options (cairo_xlib_screen_t *info)
 {
     if (info->has_font_options)
 	return &info->font_options;
 
     CAIRO_MUTEX_LOCK (info->mutex);
     if (! info->has_font_options) {
-	Display *dpy = info->display->display;
-
 	_cairo_font_options_init_default (&info->font_options);
 
-	if (info->screen != NULL)
-	    _cairo_xlib_init_screen_font_options (dpy, info);
+	if (info->screen != NULL) {
+	    _cairo_xlib_init_screen_font_options (_cairo_xlib_display_get_dpy (info->display),
+						  info);
+	}
 
 	info->has_font_options = TRUE;
     }
diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h
index cb97650..b3cbe04 100644
--- a/src/cairo-xlib-surface-private.h
+++ b/src/cairo-xlib-surface-private.h
@@ -46,12 +46,11 @@ struct _cairo_xlib_surface {
 
     Display *dpy;
     cairo_xlib_display_t *display;
-    cairo_xlib_screen_info_t *screen_info;
+    cairo_xlib_screen_t *screen;
     cairo_xlib_hook_t close_display_hook;
 
     GC gc;
     Drawable drawable;
-    Screen *screen;
     cairo_bool_t owns_pixmap;
     Visual *visual;
 
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 65b8a69..b53f4de 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -74,9 +74,8 @@ typedef int (*cairo_xlib_error_func_t) (Display     *display,
 					XErrorEvent *event);
 
 static cairo_surface_t *
-_cairo_xlib_surface_create_internal (Display		       *dpy,
+_cairo_xlib_surface_create_internal (cairo_xlib_screen_t	*screen,
 				     Drawable		        drawable,
-				     Screen		       *screen,
 				     Visual		       *visual,
 				     XRenderPictFormat	       *xrender_format,
 				     int			width,
@@ -249,8 +248,8 @@ _cairo_xlib_surface_create_similar_with_format (void	       *abstract_src,
 			 xrender_format->depth);
 
     surface = (cairo_xlib_surface_t *)
-	      _cairo_xlib_surface_create_internal (dpy, pix,
-		                                   src->screen, NULL,
+	      _cairo_xlib_surface_create_internal (src->screen, pix,
+						   NULL,
 						   xrender_format,
 						   width, height,
 						   xrender_format->depth);
@@ -327,8 +326,8 @@ _cairo_xlib_surface_create_similar (void	       *abstract_src,
 			 xrender_format->depth);
 
     surface = (cairo_xlib_surface_t *)
-	      _cairo_xlib_surface_create_internal (src->dpy, pix,
-		                                   src->screen, src->visual,
+	      _cairo_xlib_surface_create_internal (src->screen, pix,
+		                                   src->visual,
 						   xrender_format,
 						   width, height,
 						   xrender_format->depth);
@@ -382,7 +381,7 @@ _cairo_xlib_surface_finish (void *abstract_surface)
     }
 
     if (surface->gc != NULL) {
-	_cairo_xlib_screen_put_gc (surface->screen_info,
+	_cairo_xlib_screen_put_gc (surface->screen,
 				   surface->depth,
 				   surface->gc,
 				   surface->gc_has_clip_rects);
@@ -392,17 +391,15 @@ _cairo_xlib_surface_finish (void *abstract_surface)
     if (surface->clip_rects != surface->embedded_clip_rects)
 	free (surface->clip_rects);
 
-    if (surface->screen_info != NULL)
-	_cairo_xlib_screen_info_destroy (surface->screen_info);
-
-    if (surface->display != NULL) {
+    if (surface->dpy != NULL) {
 	_cairo_xlib_remove_close_display_hook (surface->display,
 					       &surface->close_display_hook);
-	_cairo_xlib_display_destroy (surface->display);
+	surface->dpy = NULL;
     }
 
+    _cairo_xlib_screen_destroy (surface->screen);
+
     cairo_region_destroy (surface->clip_region);
-    surface->dpy = NULL;
 
     return status;
 }
@@ -857,7 +854,7 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
 	} else {
 	    format = CAIRO_FORMAT_RGB24;
 
-	    status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
+	    status = _cairo_xlib_screen_get_visual_info (surface->screen,
 							 surface->visual,
 							 &visual_info);
 	    if (unlikely (status))
@@ -984,7 +981,7 @@ _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface,
 {
 
     if (surface->gc == NULL) {
-	surface->gc = _cairo_xlib_screen_get_gc (surface->screen_info,
+	surface->gc = _cairo_xlib_screen_get_gc (surface->screen,
 						 surface->depth,
 						 surface->drawable,
 						 &surface->clip_dirty);
@@ -1017,7 +1014,7 @@ _cairo_xlib_surface_maybe_put_gc (cairo_xlib_surface_t *surface)
     if (surface->gc_has_clip_rects)
 	return;
 
-    _cairo_xlib_screen_put_gc (surface->screen_info,
+    _cairo_xlib_screen_put_gc (surface->screen,
 			       surface->depth,
 			       surface->gc,
 			       FALSE);
@@ -1117,7 +1114,7 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
 	    _characterize_field (surface->g_mask, &o_g_width, &o_g_shift);
 	    _characterize_field (surface->b_mask, &o_b_width, &o_b_shift);
 	} else {
-	    status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
+	    status = _cairo_xlib_screen_get_visual_info (surface->screen,
 							 surface->visual,
 							 &visual_info);
 	    if (unlikely (status))
@@ -1289,7 +1286,7 @@ static inline cairo_bool_t
 _cairo_xlib_surface_same_screen (cairo_xlib_surface_t *dst,
 				 cairo_xlib_surface_t *src)
 {
-    return dst->screen_info == src->screen_info;
+    return dst->screen == src->screen;
 }
 
 static cairo_status_t
@@ -1400,9 +1397,9 @@ _cairo_xlib_surface_create_solid_pattern_surface (void                  *abstrac
 			    other->depth);
 
     surface = (cairo_xlib_surface_t *)
-	      _cairo_xlib_surface_create_internal (other->dpy,
+	      _cairo_xlib_surface_create_internal (other->screen,
 						   pixmap,
-						   other->screen, other->visual,
+						   other->visual,
 						   other->xrender_format,
 						   width, height,
 						   other->depth);
@@ -2010,9 +2007,9 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_surface_t *dst,
 							     CAIRO_FORMAT_ARGB32);
 
 	    surface = (cairo_xlib_surface_t *)
-		_cairo_xlib_surface_create_internal (dst->dpy, None,
-						     dst->screen, NULL,
-						     format, 0, 0, 32);
+		_cairo_xlib_surface_create_internal (dst->screen, None,
+						     NULL, format,
+						     0, 0, 32);
 	    if (unlikely (surface->base.status)) {
 		XRenderFreePicture (dst->dpy, picture);
 		return surface->base.status;
@@ -2744,7 +2741,7 @@ _cairo_xlib_surface_get_font_options (void                  *abstract_surface,
 {
     cairo_xlib_surface_t *surface = abstract_surface;
 
-    *options = *_cairo_xlib_screen_get_font_options (surface->screen_info);
+    *options = *_cairo_xlib_screen_get_font_options (surface->screen);
 }
 
 static void
@@ -2870,19 +2867,15 @@ _cairo_xlib_surface_detach_display (cairo_xlib_display_t *display, void *data)
 }
 
 static cairo_surface_t *
-_cairo_xlib_surface_create_internal (Display		       *dpy,
-				     Drawable		        drawable,
-				     Screen		       *screen,
-				     Visual		       *visual,
-				     XRenderPictFormat	       *xrender_format,
-				     int			width,
-				     int			height,
-				     int			depth)
+_cairo_xlib_surface_create_internal (cairo_xlib_screen_t	*screen,
+				     Drawable			 drawable,
+				     Visual			*visual,
+				     XRenderPictFormat		*xrender_format,
+				     int			 width,
+				     int			 height,
+				     int			 depth)
 {
     cairo_xlib_surface_t *surface;
-    cairo_xlib_display_t *display;
-    cairo_xlib_screen_info_t *screen_info;
-    cairo_status_t status;
 
     CAIRO_MUTEX_INITIALIZE ();
 
@@ -2891,14 +2884,15 @@ _cairo_xlib_surface_create_internal (Display		       *dpy,
 
 	/* XXX find matching visual for core/dithering fallbacks? */
     } else if (visual) {
+	Screen *scr = screen->screen;
 	int j, k;
 
 	/* This is ugly, but we have to walk over all visuals
 	 * for the display to find the correct depth.
 	 */
 	depth = 0;
-	for (j = 0; j < screen->ndepths; j++) {
-	    Depth *d = &screen->depths[j];
+	for (j = 0; j < scr->ndepths; j++) {
+	    Depth *d = &scr->depths[j];
 	    for (k = 0; k < d->nvisuals; k++) {
 		if (&d->visuals[k] == visual) {
 		    depth = d->depth;
@@ -2913,36 +2907,27 @@ _cairo_xlib_surface_create_internal (Display		       *dpy,
     if (depth == 0)
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
 
-    status = _cairo_xlib_display_get (dpy, &display);
-    if (unlikely (status))
-	return _cairo_surface_create_in_error (status);
-
-    status = _cairo_xlib_screen_info_get (display, screen, &screen_info);
-    if (unlikely (status)) {
-	_cairo_xlib_display_destroy (display);
-	return _cairo_surface_create_in_error (status);
-    }
-
     surface = malloc (sizeof (cairo_xlib_surface_t));
-    if (unlikely (surface == NULL)) {
-	_cairo_xlib_screen_info_destroy (screen_info);
-	_cairo_xlib_display_destroy (display);
+    if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-    }
+
+    surface->dpy = _cairo_xlib_display_get_dpy (screen->display);
 
     /* initialize and hook into the CloseDisplay callback */
     surface->close_display_hook.func = _cairo_xlib_surface_detach_display;
-    _cairo_xlib_add_close_display_hook (display, &surface->close_display_hook);
+    _cairo_xlib_add_close_display_hook (screen->display,
+					&surface->close_display_hook);
 
-    surface->render_major = display->render_major;
-    surface->render_minor = display->render_minor;
+    _cairo_xlib_display_get_xrender_version (screen->display,
+					     &surface->render_major,
+					     &surface->render_minor);
     if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface)) {
 	if (!xrender_format) {
 	    if (visual) {
-		xrender_format = XRenderFindVisualFormat (dpy, visual);
+		xrender_format = XRenderFindVisualFormat (surface->dpy, visual);
 	    } else if (depth == 1) {
 		xrender_format =
-		    _cairo_xlib_display_get_xrender_format (display,
+		    _cairo_xlib_display_get_xrender_format (screen->display,
 							    CAIRO_FORMAT_A1);
 	    }
 	}
@@ -2959,29 +2944,27 @@ _cairo_xlib_surface_create_internal (Display		       *dpy,
     _cairo_surface_init (&surface->base, &cairo_xlib_surface_backend,
 			 _xrender_format_to_content (xrender_format));
 
-    surface->dpy = dpy;
-    surface->display = display;
-    surface->screen_info = screen_info;
+    surface->screen = _cairo_xlib_screen_reference (screen);
+    surface->display = screen->display;
 
     surface->gc = NULL;
     surface->drawable = drawable;
-    surface->screen = screen;
     surface->owns_pixmap = FALSE;
     surface->use_pixmap = 0;
     surface->width = width;
     surface->height = height;
 
-    surface->buggy_repeat = screen_info->display->buggy_repeat;
+    surface->buggy_repeat = ! _cairo_xlib_display_has_repeat (surface->display);
     if (! CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLES (surface)) {
 	/* so we can use the XTile fallback */
 	surface->buggy_repeat = TRUE;
     }
 
-    surface->buggy_pad_reflect = screen_info->display->buggy_pad_reflect;
+    surface->buggy_pad_reflect = ! _cairo_xlib_display_has_reflect (surface->display);
     if (! CAIRO_SURFACE_RENDER_HAS_EXTENDED_REPEAT (surface))
 	surface->buggy_pad_reflect = TRUE;
 
-    surface->buggy_gradients = screen_info->display->buggy_gradients;
+    surface->buggy_gradients = ! _cairo_xlib_display_has_gradients (surface->display);
     if (! CAIRO_SURFACE_RENDER_HAS_GRADIENTS (surface))
 	surface->buggy_gradients = TRUE;
 
@@ -3095,13 +3078,25 @@ cairo_xlib_surface_create (Display     *dpy,
 			   int		width,
 			   int		height)
 {
-    Screen *screen = _cairo_xlib_screen_from_visual (dpy, visual);
+    Screen *scr;
+    cairo_xlib_screen_t *screen;
+    cairo_surface_t *surface;
+    cairo_status_t status;
 
-    if (screen == NULL)
+    scr = _cairo_xlib_screen_from_visual (dpy, visual);
+    if (scr == NULL)
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
 
-    return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
-						visual, NULL, width, height, 0);
+    status = _cairo_xlib_screen_get (dpy, scr, &screen);
+    if (unlikely (status))
+	return _cairo_surface_create_in_error (status);
+
+    surface = _cairo_xlib_surface_create_internal (screen, drawable,
+						   visual, NULL,
+						   width, height, 0);
+    _cairo_xlib_screen_destroy (screen);
+
+    return surface;
 }
 slim_hidden_def (cairo_xlib_surface_create);
 
@@ -3121,12 +3116,24 @@ slim_hidden_def (cairo_xlib_surface_create);
 cairo_surface_t *
 cairo_xlib_surface_create_for_bitmap (Display  *dpy,
 				      Pixmap	bitmap,
-				      Screen   *screen,
+				      Screen   *scr,
 				      int	width,
 				      int	height)
 {
-    return _cairo_xlib_surface_create_internal (dpy, bitmap, screen,
-						NULL, NULL, width, height, 1);
+    cairo_xlib_screen_t *screen;
+    cairo_surface_t *surface;
+    cairo_status_t status;
+
+    status = _cairo_xlib_screen_get (dpy, scr, &screen);
+    if (unlikely (status))
+	return _cairo_surface_create_in_error (status);
+
+    surface = _cairo_xlib_surface_create_internal (screen, bitmap,
+						   NULL, NULL,
+						   width, height, 1);
+    _cairo_xlib_screen_destroy (screen);
+
+    return surface;
 }
 
 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
@@ -3153,13 +3160,25 @@ cairo_xlib_surface_create_for_bitmap (Display  *dpy,
 cairo_surface_t *
 cairo_xlib_surface_create_with_xrender_format (Display		    *dpy,
 					       Drawable		    drawable,
-					       Screen		    *screen,
+					       Screen		    *scr,
 					       XRenderPictFormat    *format,
 					       int		    width,
 					       int		    height)
 {
-    return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
-						NULL, format, width, height, 0);
+    cairo_xlib_screen_t *screen;
+    cairo_surface_t *surface;
+    cairo_status_t status;
+
+    status = _cairo_xlib_screen_get (dpy, scr, &screen);
+    if (unlikely (status))
+	return _cairo_surface_create_in_error (status);
+
+    surface = _cairo_xlib_surface_create_internal (screen, drawable,
+						   NULL, format,
+						   width, height, 0);
+    _cairo_xlib_screen_destroy (screen);
+
+    return surface;
 }
 slim_hidden_def (cairo_xlib_surface_create_with_xrender_format);
 
@@ -3358,7 +3377,7 @@ cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface)
 	return NULL;
     }
 
-    return surface->screen;
+    return surface->screen->screen;
 }
 
 /**
@@ -3504,7 +3523,7 @@ _cairo_xlib_surface_remove_scaled_font (cairo_xlib_display_t	*display,
 	Display *dpy;
 	int i;
 
-	dpy = display->display;
+	dpy = _cairo_xlib_display_get_dpy (display);
 	for (i = 0; i < NUM_GLYPHSETS; i++) {
 	    cairo_xlib_font_glyphset_info_t *glyphset_info;
 
@@ -3706,8 +3725,8 @@ _cairo_xlib_scaled_font_get_glyphset_info_for_format (cairo_scaled_font_t *scale
 	glyphset_info->xrender_format =
 	    _cairo_xlib_display_get_xrender_format (display,
 		                                    glyphset_info->format);
-	glyphset_info->glyphset = XRenderCreateGlyphSet (display->display,
-		                                 glyphset_info->xrender_format);
+	glyphset_info->glyphset = XRenderCreateGlyphSet (_cairo_xlib_display_get_dpy (display),
+							 glyphset_info->xrender_format);
     }
 
     return glyphset_info;
commit b8ddd66cf6e0d16383580c3c3398343f577b89fd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Sep 1 21:49:01 2009 +0100

    Revert "[freelist] Make _cairo_freepool_alloc_from_new_pool static inline."
    
    This reverts commit 5a3fa29b370816acb3a08d60e4031ed82c1e4c73 as it breaks
    the boilerplate when linking with gcc.

diff --git a/src/cairo-freelist-private.h b/src/cairo-freelist-private.h
index 420fa33..d48a720 100644
--- a/src/cairo-freelist-private.h
+++ b/src/cairo-freelist-private.h
@@ -22,7 +22,6 @@
 #ifndef CAIRO_FREELIST_H
 #define CAIRO_FREELIST_H
 
-#include "cairoint.h"
 #include "cairo-types-private.h"
 #include "cairo-compiler-private.h"
 
@@ -97,32 +96,8 @@ _cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize);
 cairo_private void
 _cairo_freepool_fini (cairo_freepool_t *freepool);
 
-static inline void *
-_cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool)
-{
-    cairo_freelist_pool_t *pool;
-    int poolsize;
-
-    if (freepool->pools != &freepool->embedded_pool)
-	poolsize = 2 * freepool->pools->size;
-    else
-	poolsize = (128 * freepool->nodesize + 8191) & -8192;
-    pool = malloc (sizeof (cairo_freelist_pool_t) + poolsize);
-    if (unlikely (pool == NULL))
-	return pool;
-
-    pool->next = freepool->pools;
-    freepool->pools = pool;
-
-    pool->size = poolsize;
-    pool->rem = poolsize - freepool->nodesize;
-    pool->data = (uint8_t *) (pool + 1) + freepool->nodesize;
-
-    VG (VALGRIND_MAKE_MEM_NOACCESS (pool->data, poolsize));
-    VG (VALGRIND_MAKE_MEM_UNDEFINED (pool->data, freepool->nodesize));
-
-    return pool + 1;
-}
+cairo_private void *
+_cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool);
 
 static inline void *
 _cairo_freepool_alloc_from_pool (cairo_freepool_t *freepool)
diff --git a/src/cairo-freelist.c b/src/cairo-freelist.c
index e7f3ac2..6277f90 100644
--- a/src/cairo-freelist.c
+++ b/src/cairo-freelist.c
@@ -20,6 +20,8 @@
  * OF THIS SOFTWARE.
  */
 
+#include "cairoint.h"
+
 #include "cairo-freelist-private.h"
 
 void
@@ -109,3 +111,30 @@ _cairo_freepool_fini (cairo_freepool_t *freepool)
     }
     VG (VALGRIND_MAKE_MEM_NOACCESS (freepool, sizeof (freepool)));
 }
+
+void *
+_cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool)
+{
+    cairo_freelist_pool_t *pool;
+    int poolsize;
+
+    if (freepool->pools != &freepool->embedded_pool)
+	poolsize = 2 * freepool->pools->size;
+    else
+	poolsize = (128 * freepool->nodesize + 8191) & -8192;
+    pool = malloc (sizeof (cairo_freelist_pool_t) + poolsize);
+    if (unlikely (pool == NULL))
+	return pool;
+
+    pool->next = freepool->pools;
+    freepool->pools = pool;
+
+    pool->size = poolsize;
+    pool->rem = poolsize - freepool->nodesize;
+    pool->data = (uint8_t *) (pool + 1) + freepool->nodesize;
+
+    VG (VALGRIND_MAKE_MEM_NOACCESS (pool->data, poolsize));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (pool->data, freepool->nodesize));
+
+    return pool + 1;
+}


More information about the cairo-commit mailing list