[cairo] Concerns regarding cairo-xcb backend

Uli Schlachter psychon at znc.in
Sat Dec 16 09:46:06 UTC 2017


Hi,

On 12.12.2017 14:47, Alexandre Bique wrote:
> I'm improving the Linux port of the u-he plugins (www.u-he.com) and I was
> using Xlib before but I've switched to xcb now, and I'm using cairo-xcb
> instead of cairo-xlib for the painting.
> 
> While using the cairo-xcb backend I've come across the following assertion:
> 
> cairo-xcb-screen.c:219: _get_screen_index: Assertion `!"reached"' failed.
> 
> I've looked at the source code and I was surprised to see that the
> cairo-xcb backend has global variables (mutex, list of
> cairo_xcb_connection, ...), and I wonder if this is the issue in my case.

cairo-xlib has such global data as well. When you create two cairo
surfaces for the same XCB connection, you want cairo to initialise
"everything" just once.

> The application I'm working on is a software synthesizer plugin (VST2/VST3)
> which a Digital Audio Workstation like Bitwig Studio (www.bitwig.com) can
> use and display.
> 
> The DAW loads the plugins, can show the plugin window (using XEmbed), hide
> or close the plugin window. In case the plugin window is closed I close my
> xcb connection, free my FT library handle and destroy my cairo xcb surface.
> 
> So if the window is shown/closed/shown/closed/... it will initialize and
> destroy xcb+FT+cairo_xcb_surface for each of them.
> 
> And I wonder if this is the issue: cairo_xcb seems to not work properly in
> such scenario.
> 
> Do you have any experience or ideas to share?

When you have a cairo surface using your xcb_connection*, do the following:

 cairo_device_t *device = cairo_device_reference(
        cairo_surface_get_device(surface));

Then, *before* you do xcb_disconnect(connection), do:

 cairo_device_finish(device);
 cairo_device_destroy(device);

The above should happen automatically when the last cairo-xcb surface is
finished. Thus, it might be that you have a leak somewhere? (Not
necessarily, there are non-leak cases where the above can happen)

cairo-xlib does some (IMO) bad hacks so that the above is not necessary:
It registers itself as an X11 extension with libX11. That way it gets a
callback when you do XCloseDisplay(), but since unregistering an X11
extension is not possible, this has some other downsides (e.g. the above
"dance" is still necessary if cairo ends up being unloaded before the
X11 connection is closed).

Cheers,
Uli
-- 
- Captain, I think I should tell you I've never
  actually landed a starship before.
- That's all right, Lieutenant, neither have I.


More information about the cairo mailing list