Re: problems understanding gtk3/gdk/cairo interaction
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
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
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
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
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
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