[cairo-commit] 2 commits - src/cairo-xcb-connection.c src/cairo-xcb-private.h src/cairo-xcb-resources.c src/cairo-xcb-screen.c src/cairo-xlib-xcb-surface.c

Uli Schlachter psychon at kemper.freedesktop.org
Sat Jan 17 11:14:21 PST 2015


 src/cairo-xcb-connection.c   |   19 +++++++++++++++++++
 src/cairo-xcb-private.h      |    4 +++-
 src/cairo-xcb-resources.c    |   33 +++++----------------------------
 src/cairo-xcb-screen.c       |   16 ++++++++++++++++
 src/cairo-xlib-xcb-surface.c |   33 ++++++++++++++++++---------------
 5 files changed, 61 insertions(+), 44 deletions(-)

New commits:
commit ebd23accc8722db838f6db12f7489f16fe6016ce
Author: Uli Schlachter <psychon at znc.in>
Date:   Sat Dec 6 17:04:07 2014 +0100

    xlib-xcb: Don't be lazy and use the real xcb_screen_t
    
    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 9c0d4b4..af3e155 100644
--- a/src/cairo-xlib-xcb-surface.c
+++ b/src/cairo-xlib-xcb-surface.c
@@ -519,21 +519,6 @@ cairo_xlib_surface_create (Display     *dpy,
 								     width, height));
 }
 
-cairo_surface_t *
-cairo_xlib_surface_create_for_bitmap (Display  *dpy,
-				      Pixmap	bitmap,
-				      Screen   *scr,
-				      int	width,
-				      int	height)
-{
-    return _cairo_xlib_xcb_surface_create (dpy, scr, NULL, NULL,
-					   cairo_xcb_surface_create_for_bitmap (XGetXCBConnection (dpy),
-										(xcb_screen_t *) scr,
-										bitmap,
-										width, height));
-}
-
-#if CAIRO_HAS_XLIB_XRENDER_SURFACE
 static xcb_screen_t *
 _cairo_xcb_screen_from_root (xcb_connection_t *connection,
 			     xcb_window_t id)
@@ -548,6 +533,24 @@ _cairo_xcb_screen_from_root (xcb_connection_t *connection,
 
     return NULL;
 }
+
+cairo_surface_t *
+cairo_xlib_surface_create_for_bitmap (Display  *dpy,
+				      Pixmap	bitmap,
+				      Screen   *scr,
+				      int	width,
+				      int	height)
+{
+    xcb_connection_t *connection = XGetXCBConnection (dpy);
+    xcb_screen_t *screen = _cairo_xcb_screen_from_root (connection, (xcb_window_t) scr->root);
+    return _cairo_xlib_xcb_surface_create (dpy, scr, NULL, NULL,
+					   cairo_xcb_surface_create_for_bitmap (connection,
+										screen,
+										bitmap,
+										width, height));
+}
+
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
 cairo_surface_t *
 cairo_xlib_surface_create_with_xrender_format (Display		    *dpy,
 					       Drawable		    drawable,
commit b47209a03feeed2172f35a6d79ba1176fedd5e17
Author: Uli Schlachter <psychon at znc.in>
Date:   Sat Dec 6 16:04:46 2014 +0100

    xcb: Query the display's subpixel order via RENDER
    
    With commit e691d242, the xcb backend started parsing the resources, just like
    cairo-xlib does. One behavior from cairo-xlib was missing: If no Xft.rgba
    property was specified, cairo-xlib defaults to the screen's subpixel order.
    This commit brings that last bit of functionality to cairo-xcb (but currently
    disabled due to commit e0c0a673).
    
    This commits adds a new array to cairo_xcb_connection_t that contains the
    subpixel order for each screen. There is also a new member in cairo_xcb_screen_t
    which contains the subpixel order of that screen and which is initialized from
    the array when the screen is constructed. With this in place, the
    resource-parsing code can just pick the subpixel order from the screen if
    needed.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-xcb-connection.c b/src/cairo-xcb-connection.c
index 2d51e14..67897fa 100644
--- a/src/cairo-xcb-connection.c
+++ b/src/cairo-xcb-connection.c
@@ -79,6 +79,7 @@ typedef struct _cairo_xcb_xid {
 #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_SUBPIXEL_ORDER(surface)		XCB_RENDER_AT_LEAST((surface), 0, 6)
 
 #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)
@@ -407,6 +408,15 @@ _cairo_xcb_connection_query_render (cairo_xcb_connection_t *connection)
     if (XCB_RENDER_HAS_GRADIENTS (version))
 	connection->flags |= CAIRO_XCB_RENDER_HAS_GRADIENTS;
 
+    if (XCB_RENDER_HAS_SUBPIXEL_ORDER (version)) {
+	uint32_t screen;
+	uint32_t *subpixel = xcb_render_query_pict_formats_subpixels(formats);
+
+	/* The spec explicitly allows to have too few entries in the reply... */
+	for (screen = 0; screen < formats->num_subpixel && screen < connection->root->roots_len; screen++)
+	    connection->subpixel_orders[screen] = subpixel[screen];
+    }
+
     free (version);
 
     status = _cairo_xcb_connection_parse_xrender_formats (connection, formats);
@@ -581,6 +591,7 @@ _device_destroy (void *device)
     CAIRO_MUTEX_FINI (connection->shm_mutex);
     CAIRO_MUTEX_FINI (connection->screens_mutex);
 
+    free (connection->subpixel_orders);
     free (connection);
 }
 
@@ -684,6 +695,14 @@ _cairo_xcb_connection_get (xcb_connection_t *xcb_connection)
 
     connection->root = xcb_get_setup (xcb_connection);
     connection->render = NULL;
+    connection->subpixel_orders = calloc (connection->root->roots_len, sizeof(*connection->subpixel_orders));
+    if (unlikely (connection->subpixel_orders == NULL)) {
+	CAIRO_MUTEX_UNLOCK (connection->device.mutex);
+	_cairo_xcb_connection_destroy (connection);
+	connection = NULL;
+	goto unlock;
+    }
+
     ext = xcb_get_extension_data (xcb_connection, &xcb_render_id);
     if (ext != NULL && ext->present) {
 	status = _cairo_xcb_connection_query_render (connection);
diff --git a/src/cairo-xcb-private.h b/src/cairo-xcb-private.h
index 1e1d1ee..214fa45 100644
--- a/src/cairo-xcb-private.h
+++ b/src/cairo-xcb-private.h
@@ -181,7 +181,8 @@ struct _cairo_xcb_font {
 struct _cairo_xcb_screen {
     cairo_xcb_connection_t *connection;
 
-    xcb_screen_t	    *xcb_screen;
+    xcb_screen_t	   *xcb_screen;
+    xcb_render_sub_pixel_t  subpixel_order;
 
     xcb_gcontext_t gc[GC_CACHE_SIZE];
     uint8_t gc_depths[GC_CACHE_SIZE];
@@ -223,6 +224,7 @@ struct _cairo_xcb_connection {
     const xcb_setup_t *root;
     const xcb_query_extension_reply_t *render;
     const xcb_query_extension_reply_t *shm;
+    xcb_render_sub_pixel_t *subpixel_orders;
 
     cairo_list_t free_xids;
     cairo_freepool_t xid_pool;
diff --git a/src/cairo-xcb-resources.c b/src/cairo-xcb-resources.c
index 62c27ef..1877758 100644
--- a/src/cairo-xcb-resources.c
+++ b/src/cairo-xcb-resources.c
@@ -251,21 +251,13 @@ get_resources(xcb_connection_t *connection, xcb_screen_t *screen, cairo_xcb_reso
     resource_parser_done (&parser);
 }
 
-#if 0 && XCB_RENDER_MAJOR_VERSION > 99 && XCB_RENDER_MINOR_VERSION > 99
-static void
-get_rgba_from_render (xcb_connection_t *connection, xcb_screen_t *screen, cairo_xcb_resources_t *resources)
+void
+_cairo_xcb_resources_get (cairo_xcb_screen_t *screen, cairo_xcb_resources_t *resources)
 {
-    /* this is a mock-up of what the function might look like,
-       xcb_render_query_sub_pixel is not actually implemented in XCB (yet) */
-
-    xcb_render_query_sub_pixel_order_cookie_t cookie;
-    xcb_render_query_sub_pixel_order_reply_t *reply;
-
-    cookie = xcb_render_query_sub_pixel (connection, screen);
-    reply = xcb_render_query_sub_pixel_reply (connection, cookie, NULL);
+    get_resources (screen->connection->xcb_connection, screen->xcb_screen, resources);
 
-    if (reply) {
-	switch (reply->sub_pixel_order) {
+    if (resources->xft_rgba == FC_RGBA_UNKNOWN) {
+	switch (screen->subpixel_order) {
 	case XCB_RENDER_SUB_PIXEL_UNKNOWN:
 	    resources->xft_rgba = FC_RGBA_UNKNOWN;
 	    break;
@@ -285,20 +277,5 @@ get_rgba_from_render (xcb_connection_t *connection, xcb_screen_t *screen, cairo_
 	    resources->xft_rgba = FC_RGBA_NONE;
 	    break;
 	}
-
-	free(reply);
     }
 }
-#endif
-
-void
-_cairo_xcb_resources_get (cairo_xcb_screen_t *screen, cairo_xcb_resources_t *resources)
-{
-    get_resources (screen->connection->xcb_connection, screen->xcb_screen, resources);
-
-#if 0 && XCB_RENDER_MAJOR_VERSION > 99 && XCB_RENDER_MINOR_VERSION > 99
-    if (resources->xft_rgba == FC_RGBA_UNKNOWN) {
-	get_rgba_from_render (screen->connection->xcb_connection, screen->xcb_screen, resources);
-    }
-#endif
-}
diff --git a/src/cairo-xcb-screen.c b/src/cairo-xcb-screen.c
index 69ea459..d0019f9 100644
--- a/src/cairo-xcb-screen.c
+++ b/src/cairo-xcb-screen.c
@@ -207,6 +207,18 @@ _pattern_cache_entry_destroy (void *closure)
     _cairo_freelist_free (&entry->screen->pattern_cache_entry_freelist, entry);
 }
 
+static int _get_screen_index(cairo_xcb_connection_t *xcb_connection,
+			     xcb_screen_t *xcb_screen)
+{
+    int idx = 0;
+    xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_connection->root);
+    for (; iter.rem; xcb_screen_next(&iter), idx++)
+	if (iter.data->root == xcb_screen->root)
+	    return idx;
+
+    ASSERT_NOT_REACHED;
+}
+
 cairo_xcb_screen_t *
 _cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
 		       xcb_screen_t *xcb_screen)
@@ -214,6 +226,7 @@ _cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
     cairo_xcb_connection_t *connection;
     cairo_xcb_screen_t *screen;
     cairo_status_t status;
+    int screen_idx;
     int i;
 
     connection = _cairo_xcb_connection_get (xcb_connection);
@@ -240,9 +253,12 @@ _cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
     if (unlikely (screen == NULL))
 	goto unlock;
 
+    screen_idx = _get_screen_index(connection, xcb_screen);
+
     screen->connection = connection;
     screen->xcb_screen = xcb_screen;
     screen->has_font_options = FALSE;
+    screen->subpixel_order = connection->subpixel_orders[screen_idx];
 
     _cairo_freelist_init (&screen->pattern_cache_entry_freelist,
 			  sizeof (struct pattern_cache_entry));


More information about the cairo-commit mailing list