[cairo] cairo / xlib not updating window content

Theo Veenker theo.veenker at beexy.nl
Mon Jul 30 20:47:34 UTC 2018

On 29/07/18 14:22, Pavel Petrovic wrote:
> Hi Theo,
> Many thanks for the hints!
> I forgot to attach a link to a new version in my second e-mail
> with those three findings, it's here:
>     https://kempelen.dai.fmph.uniba.sk/test_cairo/test_cairo2.c
> ( I have saved the version from Cedrix here:
>     https://kempelen.dai.fmph.uniba.sk/test_cairo/test_cairo_Cedric_Roux.c )
> Also now modified my second version according to your hints
> - i.e. dropping the windows[] array and always created a new
> cairo_t when drawing something
>     https://kempelen.dai.fmph.uniba.sk/test_cairo/test_cairo3.c
> Is there, please, any reason for doing so?
> Why is it better to always create a new context?
> Just because of the possibility something could have changed
> with the surface meanwhile, so a fresh context will be up-to-date,
> or are there any other reasons? How about efficiency?
> Is creating a new context a cheap operation?

Context creation is cheap I think. Just check out the sources. I 
wouldn't use push/pop groups unless you really need to. It involves 
creating intermediate surfaces. If your drawing flickers try using a 
compositing WM. Or use double buffering: use create_similar() for the 
back buffer and that paint it onto the window each time your drawing is 
ready or (if you want to do it right) only update at vblank.

If possible, clipping may also help to speed up things.

> I am also responding to resizing of the window now
> with resizing back to this fixed size, although I did not go
> into preventing maximizing, which seems more tricky.

You are catching ResizeRequest. You should catch ConfigureNotify instead.

> Pavel
> On Sat, Jul 28, 2018 at 7:31 PM, Theo Veenker <theo.veenker at beexy.nl> wrote:
>> Hi Pavel,
>> I think you should just each time when you want to draw something:
>> - create cairo context
>> - draw stuff
>> - destroy context
>> So basically get rid of your windows[] array. You shouldn't need flush in
>> your case.
>> Since you keep a surface for each window, make sure to update its size when
>> the target window has changed size.
>> Have fun,
>> Theo
>> On 28/07/18 12:34, Pavel Petrovic wrote:
>>> Hello,
>>> I tried to investigate in more depth, here are some findings:
>>> 1. Filled rectangles not showing up:
>>>     - changing them for circles solves it, so it really is about the
>>> rectangles
>>>     - workaround: not only fill, but draw again and then stroke, this
>>> solves the issue
>>>     pending question: why drawing filled rectangles without borders is
>>> not possible/flushed?
>>> 2. cairo_paint() effect lost due to window not shown yet:
>>>     - adding ExposureMask to XSelectInput() and then painting only after
>>>       the Expose event arrives, solves the problem
>>>     pending question: why drawing to a window that has been properly
>>> constructed is lost if it was not exposed yet?
>>> 3. the red line drawn from keyboard events not being updated:
>>>      - adding extra cairo_surface_flush() after each piece of line helps
>>> somewhat,
>>>        it seems that all parts of line are drawn eventually, but
>>> sometimes it takes
>>>        even several seconds, while the machine cpu/memory is pretty idle
>>>     follow-up question:
>>>       Does cairo keep all the shapes that have been drawn in some kind of
>>> list
>>>       which slows it down so much when there are so many shapes?
>>>       (sorry for such a beginner/disturbing question)
>>> Thanks.
>>> Pavel
>>> On Sat, Jul 28, 2018 at 9:50 AM, Pavel Petrovic
>>> <pavel.petrovic.level2 at gmail.com> wrote:
>>>> I am trying to learn how to use Cairo 2D drawing library with xlib
>>>> surfaces.
>>>> I wrote a little test program that allows creating multiple windows.
>>>> Each function may have a custom paint() function that is called
>>>> regularly to add some graphics content to the window, or redraw it
>>>> completely if desired. There is also an option to define mouse and key
>>>> listener. The main routine checks for X events (to delegate them to
>>>> mouse and key listener) and for timeout for periodic call of those
>>>> paint() functions.
>>>> I tried with the 1.14.6 version of Cairo (that is currently available
>>>> as package in Ubuntu 16.04), and the latest 1.15.12, but the results
>>>> are the same.
>>>> The expected behavior of this demo is to open 3 windows. One will have
>>>> random rectangles being added, another one random texts, and the third
>>>> random circles.
>>>> In addition, clicking into windows should produce lines (connecting to
>>>> mouse click, or randomly), and using arrow keys should draw a red line
>>>> in the window with circles.
>>>> The circles and text seem to show up regularly as expected. All three
>>>> windows should have white background, but two of them are black. And
>>>> the worst, the window with rectangles does not get updated much (and
>>>> it does not matter if it is the first window created or not, it is
>>>> always the rectangles that do not show up properly).
>>>> They are only shown when the focus changes to or from that window -
>>>> then the remaining rectangles that should have been drawn meanwhile
>>>> suddenly appear.
>>>> I am calling cairo_surface_flush() on the surface of each window after
>>>> adding any content, but that does not help. I also tried posting
>>>> XEvents to that window of various kind (such as focus), they arrive,
>>>> but rectangles do not show up.
>>>> Furthermore, even though drawing lines with mouse works fine, drawing
>>>> line with key arrows suffers from the same problem - it is drawn, but
>>>> not shown properly.
>>>> I am obviously wrong in some of my assumptions about what this library
>>>> can do, but I am not sure where.
>>>> It seems that there are some two competing versions of drawing being
>>>> shown, since it happens sometimes that one or two rectangles, or
>>>> pieces of the red line are flashing. Some kind of strange buffering,
>>>> caching? It may just be some bug in my program, I do not know.
>>>> Another observation - the black background is because drawing white
>>>> background happens before the window is shown, and thus those
>>>> cairo_paint calls are somehow discarded. I do not know how to make the
>>>> window appear earlier, it seems it appears only after some later
>>>> changes on the screen.
>>>> I am stuck on this after a couple of desperate days, could you help me
>>>> out at least in part, please?
>>>> The program is here:
>>>> https://kempelen.dai.fmph.uniba.sk/test_cairo/test_cairo.c
>>>> An example screenshot (with a broken red line drawn by keys, and
>>>> rectangles not showing up properly):
>>>> https://kempelen.dai.fmph.uniba.sk/test_cairo/test_cairo.png
>>>> To compile (on Ubuntu 16.04 or similar system):
>>>> gcc -o test_cairo test_cairo.c -I/usr/include/cairo -lX11 -lcairo
>> --
>> Theo Veenker  |  Beexy - Behavioral Experiment Software
>> +31(0)524-541531  |  +31(0)6-42525777 mobile
>> theo.veenker at beexy.nl  |  www.beexy.nl
>> --
>> cairo mailing list
>> cairo at cairographics.org
>> https://lists.cairographics.org/mailman/listinfo/cairo

Theo Veenker  |  Beexy - Behavioral Experiment Software
+31(0)524-541531  |  +31(0)6-42525777 mobile
theo.veenker at beexy.nl  |  www.beexy.nl

More information about the cairo mailing list