[cairo] memory problem with the X11 - SHM backend

Cedric Roux sed at free.fr
Sun Dec 1 02:30:06 PST 2013


On 12/01/2013 10:55 AM, Uli Schlachter wrote:
> Hi,
>
> On 01.12.2013 01:06, Cedric Roux wrote:
>> I have a problem running you with X11/Xshm. This is a debian host here.
>> The following program reports an always increasing "evs" thing.
>>
>> The first line it outputs is "1 evs" and the last one is
>> "7409 evs".
>
> It doesn't do so here:
>
>   $ gcc t.c -lcairo -lX11&&  ./a.out | uniq -c
>     7500 1 evs

I have 1.12.16 here, you are with the git one?
Still no problem if you do the following instead of the translate(0,0) ?

          static int z = 2;  cairo_matrix_init_translate(&m, z, z);
          z = 2 - z;

>
> (Looks like the first paint() causes a SHM fallback and all the following
> paint()s don't cause any Xlib calls, but just draw to the already existing SHM
> image surface)
>
> If I do make the change mentioned below, I do get an increasing size of the
> event queue. Why don't you run any event loop that gets events from Xlib?

There is the XCheckMaskEvent thing, but it never prints "events".
even with XFlush before.

To figure things out (there are events in the queue, why doesn't
XCheckMaskEvent return them?) I looked at the first_event field when
calling XInitExtension and it is 65. I didn't check in the source of
X11 but I suspect XCheckMaskEvent(-1L) won't look at this number
because (1<<65) is out of range. Calling XNextEvent indeed removes the
event from the queue.

Well, I'm left with a problem here. I cannot use XNextEvent because
my program uses select and XCheckMaskEvent leaves the event in
the queue... So I guess I'll have to go with the XEventsQueued thing
to check if there is something waiting and then use XNextEvent to
really get it out. Or something...

Thanks for your help, Uli, and taking time to test things.
I guess it was me misunderstanding something in there, probably
the semantics of XCheckMaskEvent. Or something.

Regards.

>
>> That means the X event queue is not emptied. (Please don't
>> look at the style, it's a quick and dirty hack to let the problem pop
>> up.)
>>
>> Oh yes, you need to create a 128x128 mini.png file to run it. Content
>> does not seem to matter, I have a white image here.
>>
>> Am I doing something wrong with you or is the problem on your side?
>
> Uhm, so what exactly is the problem here? So far we are just at the symptom
> "always increasing 'evs' thing". This might cause many actual problems, so which
> one are you looking at?
>
>> If I call XSync(d, True) the queue is emptied and the original program
>> that exhibited the problem and from which I wrote that little proof of
>> concept still works pretty reasonably well. (What a terrific sentence
>> I just wrote...)
>> Except it smokes my CPU like hell, but that's none of your concern I
>> suspect.
>>
>> In the hope that you can help me here...
>> Regards cairo, have a nice sunday.
>>
>> #include<stdio.h>
>> #include<cairo/cairo.h>
>> #include<cairo/cairo-xlib.h>
>> #include<X11/Xlib.h>
>> #include<stdlib.h>
>>
>> int main(void)
>> {
>>     cairo_surface_t *image;
>>     cairo_pattern_t *pletters;
>>     cairo_surface_t *cs;
>>     Display *d;
>>     Pixmap p;
>>
>>     d = XOpenDisplay(0); if (!d) abort();
>>     p = XCreatePixmap(d, DefaultRootWindow(d), 256, 256,
>>                       DefaultDepth(d, DefaultScreen(d)));
>>     cs = cairo_xlib_surface_create(d, p, DefaultVisual(d, DefaultScreen(d)),
>>                                    256, 256);
>>
>>     //image = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 512, 512);
>>     image = cairo_image_surface_create_from_png("mini.png");
>>     pletters = cairo_pattern_create_for_surface(image);
>>
>>     int y;
>>     for (y=0; y<  500; y++) {
>>       int i;
>>       cairo_matrix_t m;
>>       cairo_t *c = cairo_create(cs);
>>
>>       //cairo_scale(c, 0.5, 0.5);
>>       //cairo_translate(c, 1, 1);
>>       for (i = 0; i<  15; i++) {
>>         //static int z = 2;  cairo_matrix_init_translate(&m, 0, 0); //z =
>> 2 - z;
>>         cairo_matrix_init_translate(&m, 0, 0); //z = 2 - z;
>>         cairo_pattern_set_matrix(pletters,&m);
>>         cairo_set_source(c, pletters);
>>         cairo_paint(c);
>>
>>         //XSync(d, True);
>>         printf("%d evs\n", XEventsQueued(d, QueuedAfterReading));
>>         //XFlush(d);
>>
>>         XEvent ev; while (XCheckMaskEvent(d, -1L,&ev)) {
>> printf("event!\n"); }
>
> Add here: cairo_surface_flush(cs); and the event queue gets filled with
> MIT-SHM-Completion events (and the program of course runs a lot slower).
>
>>       }
>>
>>       cairo_destroy(c);
>>     }
>>
>>     return 0;
>> }
>>
>
> Cheers,
> Uli



More information about the cairo mailing list