Skip to content

Commit

Permalink
xcb: Query the display's subpixel order via RENDER
Browse files Browse the repository at this point in the history
With commit e691d24, 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 e0c0a67).

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@znc.in>
  • Loading branch information
Uli Schlachter committed Jan 17, 2015
1 parent 02e4efc commit b47209a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 29 deletions.
19 changes: 19 additions & 0 deletions src/cairo-xcb-connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion src/cairo-xcb-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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;
Expand Down
33 changes: 5 additions & 28 deletions src/cairo-xcb-resources.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
}
16 changes: 16 additions & 0 deletions src/cairo-xcb-screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,13 +207,26 @@ _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)
{
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);
Expand All @@ -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));
Expand Down

0 comments on commit b47209a

Please sign in to comment.