Re: Performance issues of GDK deprecation in favour of Cairo



On Tue, 17 Aug 2010 12:26:04 +0100
James Morris <james jwm-art net> wrote:
On 17 August 2010 11:23, Chris Vine <chris cvine freeserve co uk>
wrote:
Can you avoid redrawing the entire list of rectangles on each expose
event?

Yes this is what I'm hoping. Though I've been a bit mixed up with how
Cairo and GTK work together.

When drawing in an expose event callback, you would normally clip to
the rectangle representing the "dirty" area (the area enclosed by
event->area.x, event->area.y, event->area.width,
event->area.height). You could then only call
gdk_window_invalidate_rect() or gdk_window_invalidate_region() on
the particular parts of the particular GdkWindow object(s) which
need redrawing.

Right. I think I'm starting to see where I went wrong. Though say it
is a real expose event (ie not due to the timeout) which has erased
some rectangles. Do I need to redraw the dirty area with calls to
cairo, that is, I will still need to maintain a list of rectangles
that currently exist?

Yes.  You can just clip (mask) the area to be drawn to with something
like:

  cairo_rectangle (cr, event->area.x, event->area.y,
                   event->area.width, event->area.height);
  cairo_clip (cr);

After that you can draw to the cairo surface as normal but areas
outside the clipped area will be masked out and ignored.  I imagine it
would still be more efficient even so to ignore note rectangles which
you know have not been changed if you can (that would I imagine depend
on how complex they are) but I don't think there is any easy means of
determining, in the callback, what has generated the expose event.  In
other words, I don't think you can assume that any particular expose
event is not one generated artificially rather than one called up by
the window manager.  So you may need to examine the co-ordinates of any
one note rectangle with those of the "dirty" area of the event if you
wanted to make the implementation more efficient still.

What about drawing via cairo to a pixbuf and using that for the (real)
expose events?

You can convert pixels in pixbuf format to cairo image format, but I
don't see why that would be advantageous in your case. They use
different formats (RGB/RGBA, alpha not pre-multipled, for pixbuf, and
BGR/BGRA, with pre-multiplied alpha, for image surfaces). You would
also need to allow for endianness in converting, because image
surfaces are in 32-bit native endian format.

Draw to the surface directly, if you can, because it saves conversion,
and futzing around with endianness.  That is why gdk provides you with
a cairo context, incorporating a destination surface, for any
GdkDrawable.

I am not an expert on cairo drawing functions.  Others in the list
probably know considerably more.  I just know what I need to know for
the things I write.

Chris





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]