Re: problems understanding gtk3/gdk/cairo interaction

2012-04-12 Thread Roger Davis



Hi John and Simon,

OK, experiment complete. Performance for me is very clearly not as good as 
Xlib-style XOR when drawing rubberband lines which span a screen-sized 
window (which is more or less typical for my apps, unfortunately), but on 
the other hand it's not unusable either, just somewhat annoyingly jerky. 
With smaller drawing areas (e.g., 300x300) the rubberbanding is perfectly 
smooth. Playing around with motion hint events might clean this up a 
little more. I'm basically doing a cairo_rectangle()/cairo_fill() from my 
entire off-screen surface to the GtkDrawingArea after every MotionNotify 
event. There are special cases, e.g., small rectangular rubberband boxes, 
where this is horrific overkill, but I also have cases where I need to 
rubberband larger collections of unpredictably-oriented line segments 
which span the full window, so I think my worst-case scenario experimental 
implementation has been a reasonable test. The outcome could have been 
worse, and I was expecting that it would be! For now I'll tell my users to 
wait 5 years and then buy new hardware. ;-


Thanks for all your suggestions!

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


Re: problems understanding gtk3/gdk/cairo interaction

2012-04-12 Thread Simon Feltman
You should be able to just fill the delta regions between the cursor
position changes right? Basically a backwards L shape if you're dragging
upper-left to lower-right. You would need to do two rect copies (or two
calls to gtk_widget_queue_draw_area for each part of the L) as opposed to
one. If items have a visible selected state that changes as you drag, then
the regions for those items should simply be invalidated (but only if their
state changes) along with the rubber band regions using
gtk_widget_queue_draw_area.

On Thu, Apr 12, 2012 at 1:20 PM, Roger Davis r...@soest.hawaii.edu wrote:



 Hi John and Simon,

 OK, experiment complete. Performance for me is very clearly not as good as
 Xlib-style XOR when drawing rubberband lines which span a screen-sized
 window (which is more or less typical for my apps, unfortunately), but on
 the other hand it's not unusable either, just somewhat annoyingly jerky.
 With smaller drawing areas (e.g., 300x300) the rubberbanding is perfectly
 smooth. Playing around with motion hint events might clean this up a little
 more. I'm basically doing a cairo_rectangle()/cairo_fill() from my entire
 off-screen surface to the GtkDrawingArea after every MotionNotify event.
 There are special cases, e.g., small rectangular rubberband boxes, where
 this is horrific overkill, but I also have cases where I need to rubberband
 larger collections of unpredictably-oriented line segments which span the
 full window, so I think my worst-case scenario experimental implementation
 has been a reasonable test. The outcome could have been worse, and I was
 expecting that it would be! For now I'll tell my users to wait 5 years and
 then buy new hardware. ;-

 Thanks for all your suggestions!

 Roger

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


Re: problems understanding gtk3/gdk/cairo interaction

2012-04-12 Thread Roger Davis


On Thu, 12 Apr 2012, Simon Feltman wrote:


You should be able to just fill the delta regions between the cursor position
changes right? Basically a backwards L shape if you're dragging upper-left
to lower-right. You would need to do two rect copies (or two calls
to gtk_widget_queue_draw_area for each part of the L) as opposed to one. If
items have a visible selected state that changes as you drag, then the regions
for those items should simply be invalidated (but only if their state changes)
along with the rubber band regions using gtk_widget_queue_draw_area.


If I was only drawing a rubberbanding rectangle or a single line, yes. But 
sometimes I'm doing something much more complicated, like dragging an 
entire spiderweb of lines (which often spans virtually all of the visible 
window) across the top of a full-screen image -- in this case the damaged 
rect is virtually always the entire window, or near enough to it to make 
practically no difference. Xlib's bitwise-XOR was really nice for this, as 
I could individually redraw each overlaid line, probably a maximum of a 
few thousand pixels all together, instead of having to restore a full 
megapixel+, for each motion notify. cairo does have an XOR operator but 
it's not bitwise (rather some kind of Porter-Duff XOR which I don't 
exactly understand but which I am told is definitely not bitwise), hence 
of no use for this kind of thing as far as I can make out.


Thanks,

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

problems understanding gtk3/gdk/cairo interaction

2012-04-06 Thread Roger Davis

Hi all,

I am having trouble understanding gtk3/gdk/cairo interaction and thus 
developing a usable model for some large drawing applications I am porting 
from X11. I am currently working mostly on CentOS 6 with self-installed 
gtk3 3.4.0, gdk-pixbuf-2.26.0 and cairo 1.12.0 packages. Obviously I can 
minimize my effort by having the ported code conform to my existing 
X11/Motif drawing model as much as possible (besides the fact that I think 
that model works well for my own particular needs), so that's my preferred 
solution. If that's not possible then I need to adapt the code to whatever 
model gtk3/gdk/cairo actually supports, but the less modification the 
better, of course. (By 'model' I mean the way in which cairo interacts 
with gtk3 as compared with the way Xlib interacts with the Motif widget 
set.)


Here's the big picture of what I need to do (after which I'll explain the 
difficulties I am having so far in implementing a solution):


(1) I need a toplevel window to enclose a fixed-size largish (e.g., 
1000x1000) plotting area for imagery display. I need scrollbars as 
necessary so that if the user downsizes the toplevel window any part of 
the image can still be scrolled to. If the user upsizes the toplevel 
window beyond the predetermined fixed size I don't particularly care what 
happens with regard to any excess exposed area, although preferably not 
something hideously ugly. Ideally the window would be mapped at program 
initialization time at the fixed size so that scrollbars are not visible, 
and are made visible only if the user downsizes the toplevel window.


(2) Drawing operations must be immediately performable under background 
program control as well as in response to user interaction and expose 
events. The program is reading external automated data inputs which are 
supplying the imagery data on a real-time basis. Under my existing X11 
model, I have my own self-allocated X11 off-screen pixmap which I modify 
as desired via a registered work procedure which monitors these inputs. 
That pixmap can also be redrawn in response to user interaction. It is 
copied to the on-screen X11 window, which belongs to a Motif drawing area 
widget, both (i) explicitly via the work procedure as new imagery data 
become available or in response to user activity as well as (ii) 
indirectly via X11 expose events which filter through a Motif callback 
which copies any exposed rectangular pixel subsection(s) of my off-screen 
pixmap into the on-screen buffer of the Motif drawing area widget.


(3) Although wanting to perform the bulk of my drawing to an off-screen 
buffer which is fully under my own control, there are still frequent 
occasions where I want to make small transient alterations (e.g., draw a 
rubberband line) directly to the visible on-screen window as quickly and 
with as little overhead as possible.


I have embarked on a process of mimicking this model via a GtkDrawingArea 
embedded within a GtkScrolledWindow as my on-screen display and a 
cairo_surface_t as my off-screen drawing buffer, but am encountering some 
unexpected issues, primary of which is the fact that I can't figure out 
how to draw into the GtkDrawingArea except from within a GtkDrawingArea 
draw() callback, which seems insufficient for my purposes. GtkDrawingArea 
has two available callbacks, the realize() and draw() methods -- ideally 
at realize() time I would like to obtain some permanent reference into the 
widget so that at any time I wish, e.g., from within a registered work 
procedure or from within some other callback such as a menu procedure, I 
can transfer data from my self-maintained off-screen cairo surface into 
the widget's viewable on-screen buffer via that reference. I see no 
obvious way to do this, however -- it appears that the only way I can draw 
anything to the widget is via the draw() callback. I find this limiting 
because (i) I do not want to wait around to draw until some part of gtk3 
outside my control decides I should do so (and in fact, the gtk3 
documentation seems rather vague on exactly when and for what reasons the 
draw() callback is triggered), and (ii) drawing is extremely expensive for 
my application, involving compositing of many different subimages together 
with user annotations, etc. If I have to draw in response to an expose 
event, for instance, I don't want to have to do anything more involved 
than copy a rectangular area of pre-existing pixels from my off-screen 
cairo surface to the widget (and seemingly the draw() callback does not 
even provide detailed exposure region information :-( ). And of course I 
want to be able to draw directly to the widget for reasons other than 
expose events, such as rubberband lines rendered by a callback triggered 
by mouse activity.


The GtkDrawingArea documentation provides a very simple example on using 
the cairo_t context argument to draw(). In experimenting with my proposed 
model with relation to this example I discovered to 

Re: problems understanding gtk3/gdk/cairo interaction

2012-04-06 Thread jcupitt
Hi Roger,

You should do all drawing in the expose handler and nowhere else.
Don't do any direct drawing in your data hander, instead update your
model and queue an expose event.

On 7 April 2012 02:16, Roger Davis r...@soest.hawaii.edu wrote:
 presumably this includes the GtkDrawingArea widget as well. If there is
 documentation on exactly how this double-buffering works with regard to
 GtkDrawingArea I would be greatly interested in seeing it to figure out if

Here's how it works in gtk2, I think this bit hasn't changed much for gtk3:

* an expose event comes in from X11
* it gets added to the set of pending expose events on your drawing
area -- gtk computes the minimal set of non-overlapping damage
rectangles
* when gtk feels the time is right to update your window, it allocates
a backing pixmap just large enough to hold all damage
* the backing pixmap is filled with the background colour for your widget
* the expose handler is triggered, passing in the backing pixmap as the drawable
* your expose handler draws to that --- you can fill the whole thing,
or you can loop over the (possibly smaller) list of damage rects that
make it up
* gtk clips against the damage outline and writes the new pixels to the display
* the temporary pixmap is deleted

As a former xlib programmer I was slightly horrified when I head about
all this, but it actually works pretty well on non-ancient machines.
My program disables the double buffering and does its own thing for my
main data display, since I don't want the clear to background
behaviour, but I use it everywhere else.

The discipline of only drawing in the expose handler is also helpful.
It forces you to decouple drawing from updating which will make your
performance degrade much more gracefully under load. Instead of
suddenly getting lag when you run out of cycles, you'll just see a
drop in the frame rate.

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


Re: problems understanding gtk3/gdk/cairo interaction

2012-04-06 Thread Roger Davis

Hi Simon,

Thanks for your thoughts, I read them after responding to John. Sounds 
like my wild guesses about the differences between gtk2 and gtk3 here are 
not too horribly wrong. I will read the docs you pointed to and take a 
look at the Clutter stuff, after I get some time to do the required 
experimenting and figure out if the performance is as bad as I am worried 
that it might be.


Thanks again!

Roger

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