[cairo] GTK+, Cairo, XLib integration for fast 2D graphics drawing

Chris Wilson chris at chris-wilson.co.uk
Wed Oct 10 02:08:15 PDT 2012

On Wed, 10 Oct 2012 09:20:40 +0300, Christos Sotiriou <csotiriou at gmail.com> wrote:
> Dear Chris, Dear Cairo Developers/Users,
> I had a few more questions regarding my older post, *i.e.* being able to
> draw millions of small rectangles on a Cairo surface provided by GTK/GDK.
> Chris Wilson was kind enough to explain that my Cairo drawing is slow as I
> use a non-integer, non-uniform scaling factor, and has improved the Cairo
> code for new releases; however, I am stuck with the older Cairo version
> which I mention in my older email (for O/S compatibility), so I am back to
> probing this issue further, as I really need to speed up zoom-in/zoom-out
> for my rectangles.
> My two questions are the following:
>    1. Does Cairo *always use or not use* 2D Hardware Rendering? How can
>    this be enabled or verified using Cairo code? If not, where can I find a
>    Cairo code snippet which enables X acceleration?

If you pass cairo an X Drawable, it will use XRender to draw to it.
If you pass cairo an image buffer, it will render directly to it using
the CPU.

>    2. As I mention in a prior message I used two methods for
>    "double-buffering", drawing to an image surface OR drawing to a similar
>    surface (cairo_surface_create_similar). Funnily enough, the latter was
>    faster. Is there a reason for this? It seems mysterious...

Using image requires doing all the rasterisation locally and transferring
the final result using PutImage. Using the similar surface, and you will
offload the rasterisation to the X server, which may in turn use the GPU
to accelerate the operations.
>    3. Related to my first question, I tried to use Cairo/X interaction to
>    verify if this would improve drawing, *i.e.* if I used an Xlib surface.
>    I used the following code:
>     xdisplay = gdk_x11_drawable_get_xdisplay(maincanvas_drawable);
>     xid = gdk_x11_drawable_get_xid(maincanvas_drawable);
>     visual =
>    gdk_x11_visual_get_xvisual(gtk_widget_get_visual(GTK_WIDGET(maincanvas)));
>     maincanvas_sf = cairo_xlib_surface_create(xdisplay, xid, visual,
>    maincanvasWidth, maincanvasHeight);
>     maincanvas_cs = cairo_create(maincanvas_sf);
>    However, drawing to the Xlib surface did not help either (actually made
>    matters worse, as GDK/GTK interaction with scrollbars stopped working). So,
>    coming back to my first question, how can I guarantee 2D acceleration and
>    why is an Xlib surface not helping? How can an Xlib surface be used
>    properly?

In your expose event, you want to call
  cr = gdk_cairo_create(gtk_widget_get_window(widget))
to integrate your drawing into the GTK+ model.

Chris Wilson, Intel Open Source Technology Centre

More information about the cairo mailing list