Re: Performance issues of GDK deprecation in favour of Cairo

2010-08-18 Thread Stefan Kost
hi,

On 17.08.2010 12:01, James Morris wrote:
 Hi,

 I see that some GDK drawing functions and graphics contexts have been
 deprecated in favour of using Cairo.

 Yesterday I spent a few hours *removing* Cairo code from my fledgling
 GTK application and replacing it with gdk_draw_rectangle,
 gdk_gc_set_rgb_fg_color, and gdk_gc_set_function. I did this for
 performance reasons[1]

 I am wondering if my approach to drawing is wrong however and if a
 better approach might yield less CPU usage?

 It begins with a 33ms timeout. The timeout callback calls
 gtk_widget_queue_draw on the window and the drawing area.
   

Would it be possible to isolate this into a standalone demo. Or could
you point us to the actual code?

Stefan

 (Imagine rectangles appearing each time a note is played in a piece of
 music and disappearing when that note ends.)

 In the expose event callback a linked-list of rectangles is
 maintained. Rectangles are added to the list and removed from the list
 as notes start and end (The application is an experimental MIDI
 sequencer/arpeggiator operating in real time).

 Each and every time the expose event callback is called (every 33ms)
 the background and the entire list of rectangles is drawn as well as
 various maintenance functions performed on the list.

 The documentation of gdk_cairo_create seems to suggest this is the
 only way of doing it when it says:

 Note that due to double-buffering, Cairo contexts created in a GTK+
 expose event handler cannot be cached and reused between different
 expose events.

 Is it possible to do this any other way?
 Cheers,
 James.

 [1]My machine is a 64bit 3.0ghz dual core desktop. Using GDK for
 drawing, the CPU usage is at worst 5% on both cores. Using Cairo on
 the other hand, the CPU usage can reach as much as 20% on both cores.

 The project is here:http://github.com/jwm-art-net/BoxySeq
 Cairo routines is here:
 http://github.com/jwm-art-net/BoxySeq/tree/97f6d674a2a182a143ef82b03bde11689fedcf18
 GDK routines is here:
 http://github.com/jwm-art-net/BoxySeq/tree/29f412b41b2371ec136aa86da50d858f5892bfa0
 ___
 gtk-app-devel-list mailing list
 gtk-app-devel-list@gnome.org
 http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
   

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Performance issues of GDK deprecation in favour of Cairo

2010-08-18 Thread James Morris
On 18 August 2010 15:57, Stefan Kost enso...@hora-obscura.de wrote:
 hi,

 On 17.08.2010 12:01, James Morris wrote:
 Hi,

 I see that some GDK drawing functions and graphics contexts have been
 deprecated in favour of using Cairo.

 Yesterday I spent a few hours *removing* Cairo code from my fledgling
 GTK application and replacing it with gdk_draw_rectangle,
 gdk_gc_set_rgb_fg_color, and gdk_gc_set_function. I did this for
 performance reasons[1]

 I am wondering if my approach to drawing is wrong however and if a
 better approach might yield less CPU usage?

 It begins with a 33ms timeout. The timeout callback calls
 gtk_widget_queue_draw on the window and the drawing area.


 Would it be possible to isolate this into a standalone demo. Or could
 you point us to the actual code?

Hi Stefan,

The actual code is here:
http://github.com/jwm-art-net/BoxySeq/blob/97f6d674a2a182a143ef82b03bde11689fedcf18/gui_grid.c

I'm probably not going to work on it for a while. Probably going to
make the back-end into a library first and then investigate the
possibility of using FLTK.

Cheers,
James.


 Stefan

 (Imagine rectangles appearing each time a note is played in a piece of
 music and disappearing when that note ends.)

 In the expose event callback a linked-list of rectangles is
 maintained. Rectangles are added to the list and removed from the list
 as notes start and end (The application is an experimental MIDI
 sequencer/arpeggiator operating in real time).

 Each and every time the expose event callback is called (every 33ms)
 the background and the entire list of rectangles is drawn as well as
 various maintenance functions performed on the list.

 The documentation of gdk_cairo_create seems to suggest this is the
 only way of doing it when it says:

 Note that due to double-buffering, Cairo contexts created in a GTK+
 expose event handler cannot be cached and reused between different
 expose events.

 Is it possible to do this any other way?
 Cheers,
 James.

 [1]My machine is a 64bit 3.0ghz dual core desktop. Using GDK for
 drawing, the CPU usage is at worst 5% on both cores. Using Cairo on
 the other hand, the CPU usage can reach as much as 20% on both cores.

 The project is here:    http://github.com/jwm-art-net/BoxySeq
 Cairo routines is here:
 http://github.com/jwm-art-net/BoxySeq/tree/97f6d674a2a182a143ef82b03bde11689fedcf18
 GDK routines is here:
 http://github.com/jwm-art-net/BoxySeq/tree/29f412b41b2371ec136aa86da50d858f5892bfa0
 ___
 gtk-app-devel-list mailing list
 gtk-app-devel-list@gnome.org
 http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list



___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Performance issues of GDK deprecation in favour of Cairo

2010-08-17 Thread Chris Vine
On Tue, 17 Aug 2010 10:01:43 +0100
James Morris ja...@jwm-art.net wrote:

 I see that some GDK drawing functions and graphics contexts have been
 deprecated in favour of using Cairo.
 
 Yesterday I spent a few hours *removing* Cairo code from my fledgling
 GTK application and replacing it with gdk_draw_rectangle,
 gdk_gc_set_rgb_fg_color, and gdk_gc_set_function. I did this for
 performance reasons[1]
 
 I am wondering if my approach to drawing is wrong however and if a
 better approach might yield less CPU usage?
 
 It begins with a 33ms timeout. The timeout callback calls
 gtk_widget_queue_draw on the window and the drawing area.
 
 (Imagine rectangles appearing each time a note is played in a piece of
 music and disappearing when that note ends.)
 
 In the expose event callback a linked-list of rectangles is
 maintained. Rectangles are added to the list and removed from the list
 as notes start and end (The application is an experimental MIDI
 sequencer/arpeggiator operating in real time).
 
 Each and every time the expose event callback is called (every 33ms)
 the background and the entire list of rectangles is drawn as well as
 various maintenance functions performed on the list.
 
 The documentation of gdk_cairo_create seems to suggest this is the
 only way of doing it when it says:
 
 Note that due to double-buffering, Cairo contexts created in a GTK+
 expose event handler cannot be cached and reused between different
 expose events.
 
 Is it possible to do this any other way?
 Cheers,
 James.

Can you avoid redrawing the entire list of rectangles on each expose
event?

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.

In your particular case, unless the notes move, you could just
invalidate only the areas representing the notes which have just begun
or ended. Depending on your program logic you may be able to dispense
with the timeout entirely: your active code which handles note changes
could call gdk_window_invalidate_* on a selective basis as necessary.

Chris


___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Performance issues of GDK deprecation in favour of Cairo

2010-08-17 Thread Chris Vine
On Tue, 17 Aug 2010 12:26:04 +0100
James Morris ja...@jwm-art.net wrote:
 On 17 August 2010 11:23, Chris Vine ch...@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


___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list