Re: New drawing/scrolling model
On fre, 2013-05-03 at 21:59 -0400, Matthias Clasen wrote: On Thu, May 2, 2013 at 2:40 PM, Alexander Larsson al...@redhat.com wrote: I've tried a bunch of apps and most things seem to work. Currently I know of two problems: I've gone through gtk3-demo and our other test programs with this branch, and could only find one noticable breakage: The GtkStack crossfade transitions seem to be somewhat messed up with the branch. If you look at the example in the second page of gtk3-widget-factory, you'll notice how the colors of the cube change before it starts to fade out. This is not happening with master. I fixed this. It was a bug in GtkStack where it didn't check gtk_cairo_should_draw_window() so it ADDed the crossfaded surface twice creating the weird colors. This wasn't a problem before as then the alpha/opacity-group case only called draw() once for each widget (rather than once per gdkwindow), but that is really not quite correct. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: New drawing/scrolling model
On fre, 2013-05-03 at 21:59 -0400, Matthias Clasen wrote: On Thu, May 2, 2013 at 2:40 PM, Alexander Larsson al...@redhat.com wrote: I've tried a bunch of apps and most things seem to work. Currently I know of two problems: I've gone through gtk3-demo and our other test programs with this branch, and could only find one noticable breakage: The GtkStack crossfade transitions seem to be somewhat messed up with the branch. If you look at the example in the second page of gtk3-widget-factory, you'll notice how the colors of the cube change before it starts to fade out. This is not happening with master. This breaks with GdStack too. I pushed a fix for it. Anyone using it in gnome 3.8 apps should update if they do a new 3.8.x release. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
New drawing/scrolling model landed
I just merged the wip/simple-draw4 branch with master. It seems to work pretty well now. Open issues i know of: Anything using GdStack to do crossfades will show some weird coloring during the fade, these apps should upgrade to the latest libgd (or ideally to GtkStack). The gnome-cc background panel uses gdk_cairo_create() rather than use the passed in cairo_t in draw(), so it looks weird in the crossfade. There is some things left to do for this, some we really need to do before 3.10 is released: * Make GtkIconView use GtkPixelCache * Make GtkTextView use GtkPixelCache Some are optional but may be interesting: * Allow some kind of hinting to GtkPixelCache so that e.g. we always fit full rows in a GtkTreeview. This is nice as there is some per-row drawing overhead which we then avoid when scrolling. * GtkViewport generally always has a transparent background, but it often happens that the child does not. Atm this means that we render the pixel cache as RGBA starting at transparent and then composite it using OVER. However, in the case of a child with a non-transparent background (like a white EggListBox) we really would want to know that the child is opaque so that we can just use a RGB buffer and SOURCE rendering. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: New drawing/scrolling model
On fre, 2013-05-03 at 00:03 +0200, Søren Sandmann wrote: Alexander Larsson al...@redhat.com writes: * Try a tile-based approach for GtkPixelCache to avoid having to do a same-surface copy (usign an intermediate surface) when scrolling the cache. An alternative to tiles is to keep track of an origin within the surface: ++--+ | Bot R | Bottom left | || | +O--+ | Top R | Top left | || | || | || | || | || | || | || | ++--+ with the contents of the surface addressed modulo width and height. Scrolling is then just a matter of moving that origin, but copying from the surface may require four separate blits. Similarly, rendering to some rectangle may have to be split into four separate operations. Yeah, a 2d circular buffer. I've thought about this and its clearly doable, although somewhat of a nightmare to handle all the cases. t still has some overhead that it shares with the tiled version though, we need to traverse the scenegraph multiple times, which isn't super cheap currently. It would be nice it cairo could let us stitch together a surface made out of multiple subsurfaces, then we could avoid such overhead. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: New drawing/scrolling model
On tor, 2013-05-02 at 18:20 -0400, Paul Davis wrote: On Thu, May 2, 2013 at 6:03 PM, Søren Sandmann sandm...@cs.au.dk wrote: Alexander Larsson al...@redhat.com writes: * Try a tile-based approach for GtkPixelCache to avoid having to do a same-surface copy (usign an intermediate surface) when scrolling the cache. An alternative to tiles is to keep track of an origin within the surface: ++--+ | Bot R | Bottom left | || | +O--+ | Top R | Top left | || | || | || | || | || | || | || | ++--+ with the contents of the surface addressed modulo width and height. Scrolling is then just a matter of moving that origin, but copying from the surface may require four separate blits. Similarly, rendering to some rectangle may have to be split into four separate operations. this is where trying to be too generic hurts. a given widget knows its aspect ratio. for things that are short and wide, their pixel cache will consist of a set of full-height, partial-width surfaces. for things that are tall and narrow, their pixel cache will consist of a set of full-width, partial-height caches. for things that are short and narrow, their cache will consist of a single surface. for things that are wide and tall ... well, they're on their own ... This is not really a problem the pixel cache knows the size of the canvas and the viewport so it will automatically not pick an unnecessarily wide/tall offscreen surface. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: New drawing/scrolling model
On Fri, May 3, 2013 at 3:02 AM, Alexander Larsson al...@redhat.com wrote: things that are wide and tall ... well, they're on their own ... This is not really a problem the pixel cache knows the size of the canvas and the viewport so it will automatically not pick an unnecessarily wide/tall offscreen surface. if true, then i don't see where the two dimensional multi-surface blit issue arises. you may need to blit several surfaces along one axis, but that is sort of the definition of the pixel cache. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: New drawing/scrolling model
On fre, 2013-05-03 at 05:52 -0400, Paul Davis wrote: On Fri, May 3, 2013 at 3:02 AM, Alexander Larsson al...@redhat.com wrote: things that are wide and tall ... well, they're on their own ... This is not really a problem the pixel cache knows the size of the canvas and the viewport so it will automatically not pick an unnecessarily wide/tall offscreen surface. if true, then i don't see where the two dimensional multi-surface blit issue arises. you may need to blit several surfaces along one axis, but that is sort of the definition of the pixel cache. Not sure which issue you mean. The current code doesn't do any kind of tiling or circular buffers, all it does is keep an offscreen of the visible area and then some extra (64 pixels). As long as we're scrolling less than 64 pixels from what we drawn the first time all we have to do when scrolling is to copy a different area of the offscreen surface to the window. However, when we scroll past the 64 pixels we currently do a copy on the offscreen surface to itself of the area that will still be visible, and then we render the rest. This copy is an issue, since: a) It is a self-surface copy so we have to use an intermediate surface to do it b) Its not technically necessary, there are alternatives like tiles and circular buffers that avoid this copy Of course, the alternatives have a cost too. For once they make the code more complicated, but they also will render the widget hierarchy multiple times to the different tiles / parts-of-circular-buffer, and for each time we have to traverse and draw all the children of the scrolled container. For some containers this is probably ok, like the treeview as it can quickly find the affected rows to redraw, but for others its more of a problem. For instance GtkTextView only keeps a cache of the latest 2 rendered PangoLayouts, so it may relayout the text for each rendered tile. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: New drawing/scrolling model
On Thu, May 2, 2013 at 2:40 PM, Alexander Larsson al...@redhat.com wrote: I've tried a bunch of apps and most things seem to work. Currently I know of two problems: I've gone through gtk3-demo and our other test programs with this branch, and could only find one noticable breakage: The GtkStack crossfade transitions seem to be somewhat messed up with the branch. If you look at the example in the second page of gtk3-widget-factory, you'll notice how the colors of the cube change before it starts to fade out. This is not happening with master. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
New drawing/scrolling model
I've just pushed the wip/simple-draw4 branch which is the latest version of my work trying to simplify and modernize the Gtk drawing machinery. Its now in a state where I think its time to discuss the merging of this. The very first commit in the branch makes gdk_window_move() and gdk_window_scroll() very dumb. Previously it tried to copy as much as possible of the existing pixels and only invalidate the areas that were previously not visible. Now it just invalidates the entire scrolled area and redraws it. This may seem a bit crazy and slow, but in fact its just the first step in making the gdk drawing model more modern. Doing scrolling by same-surface copying is an old technology has some problems in the modern world. First of all, on modern hardware a same-surface copy doesn't work very well (for technical reasons). In fact, the operation is a no-op in the wayland backend atm. Secondly, in a more modern scene graph like in recent gtk3 most windows have alpha pixels and render over the window background rather than each window rendering its own opaque background, so scrolling via copy doesn't work. So, the branch continues with deleting lots of very tricky code inside gdk where does things like figuring out the cases where we can apply the copy optimization, and handling async exposes from the xserver racing with copy-area of the same region from the app. A more modern way to do scrolling is to keep an offscreen buffer for the content inside the scrolling region, covering what is currently visible in the viewport plus a bit more. Then when we draw the window we just draw the buffer in the right place, making scrolling very fast. Although if you scroll to far we have to render a new piece of the offscreen buffer. To do this kind of scrolling a container needs two things, a way to get told when a child needs redrawing so that we can make our cache dirty, and a way to retarget rendering the children to the offscreen buffer. We add some gdk API (gdk_window_set_invalidate_handler) for the first, but the second is a bit more complex. Right now rendering is done in many separate phases, one per GdkWindow where for each GdkWindow there may be several non-window widgets (and each widget may have several windows too). The branch completely redoes this so that Gtk+ only ever handles expose events on native windows (i.e. generally toplevels only) and then renders everything inside the ::draw signal handler of the toplevel widget. In order to maximize backwards compatibility we still call draw() multiple times on multi-window widgets, with the right clipping set up and the right window backgrounds rendered, however, there are still some minor differences. For instance, we expose primarily in widget order whereas we previously exposed in window order (although for windows in the same widget we respect the window order), but this is rarely a problem because intra-widget window order in gdk is hard to control anyway due to realize being called in unexpected places. With this in place the branch then does some further simplifications and then adds fast scrolling support to GtkViewport and GtkTreeView via the new GtkPixelCache helper object. I've tried a bunch of apps and most things seem to work. Currently I know of two problems: The control-center background panel calls gdk_cairo_create() inside the draw() handler, which draws directly to the window rather than the passed in cairo_t. This works in a sense, but the rendering is then unaffected by the cairo_push()/pop() that the stack uses for crossfading, so the crossfade effect breaks. This could possibly happen in other cases, but it seems like it is pretty uncommon (I didn't find any other problematic use in all of Gnome). The control-center display panel does this weird thing where it draws areas using cairo, and then reads it back to use as input regions. This code assumes that the coordinates on the cairo_t when converted via cairo_user_to_device() is in the coordinate space of the widgets windows, whereas it is now in the coordinate space of the toplevel. This makes the input regions offset by the position of the widget making it hard to click/drag them. This is a pretty weird thing to do, and i don't expect we'll run into other apps doing the same thing. IMHO we can just land the branch and fix these issues inside the control-center. Its a minor incompatibility change, but I think its still worth it. There is still some further work we may want to work on after the branch lands, in case someone wants to help out: * Port GtkIconView to GtkPixelCache * Port GtkTextView to GtkPixelCache * Have some way to hint a GtkPixelCache so that we e.g. always render an entire treeview row or textview paragraph when painting, to avoid multiple setups for drawing it when scrolling. * Try a tile-based approach for GtkPixelCache to avoid having to do a same-surface copy (usign an intermediate surface) when scrolling the cache.
Re: New drawing/scrolling model
On Thu, May 2, 2013 at 2:40 PM, Alexander Larsson al...@redhat.com wrote: I've just pushed the wip/simple-draw4 branch which is the latest version of my work trying to simplify and modernize the Gtk drawing machinery. Its now in a state where I think its time to discuss the merging of this. yay! Now it just invalidates the entire scrolled area and redraws it. completely correct. particularly when using a drawing API that may not render any pixels in memory anyway.. . Secondly, in a more modern scene graph like in recent gtk3 most windows have alpha pixels and render over the window background rather than each window rendering its own opaque background, so scrolling via copy doesn't work. which really touches on whether simple-draw5 or some future WIP will just use a scene graph for everything anyway ... A more modern way to do scrolling is to keep an offscreen buffer for the content inside the scrolling region, covering what is currently visible in the viewport plus a bit more. Then when we draw the window we just draw the buffer in the right place, making scrolling very fast. Although if you scroll to far we have to render a new piece of the offscreen buffer. yes. thus replicating the design of any sensible canvas implementation ... do you have any plans to go further in this direction? and finally, does simple-draw4 attempt to work hard on behalf of particular widgets, or is complexity left to the widgets? i think it is far preferable to go the latter route, although there may be a small cost of duplicated effort. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: New drawing/scrolling model
On Thu, May 2, 2013 at 2:40 PM, Alexander Larsson al...@redhat.com wrote: . Secondly, in a more modern scene graph like in recent gtk3 most windows have alpha pixels and render over the window background rather than each window rendering its own opaque background, so scrolling via copy doesn't work. which really touches on whether simple-draw5 or some future WIP will just use a scene graph for everything anyway ... simple-draw4 targets 3.10, its not very large: 23 files changed, 1274 insertions(+), 2212 deletions(-) But, the long term for Gtk4 is to move to a scene graph based on clutter. and finally, does simple-draw4 attempt to work hard on behalf of particular widgets, or is complexity left to the widgets? i think it is far preferable to go the latter route, although there may be a small cost of duplicated effort. All complexity is left to the individual widgets, although there is a helper object to share code. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: New drawing/scrolling model
Em Thu, 2013-05-02 às 14:40 -0400, Alexander Larsson escreveu: I've tried a bunch of apps and most things seem to work. Currently I know of two problems: The control-center background panel calls gdk_cairo_create() inside the draw() handler, which draws directly to the window rather than the passed in cairo_t. This works in a sense, but the rendering is then unaffected by the cairo_push()/pop() that the stack uses for crossfading, so the crossfade effect breaks. This could possibly happen in other cases, but it seems like it is pretty uncommon (I didn't find any other problematic use in all of Gnome). The control-center display panel does this weird thing where it draws areas using cairo, and then reads it back to use as input regions. This code assumes that the coordinates on the cairo_t when converted via cairo_user_to_device() is in the coordinate space of the widgets windows, whereas it is now in the coordinate space of the toplevel. This makes the input regions offset by the position of the widget making it hard to click/drag them. This is a pretty weird thing to do, and i don't expect we'll run into other apps doing the same thing. Both of those are just plain bugs/misuse of cairo. The display panel at least is ported from old GNOME2 code, and hasn't been eyeballed properly (at least, I stopped when mine started bleeding). It's also due a rewrite/redesign. Cheers ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: New drawing/scrolling model
Alexander Larsson al...@redhat.com writes: * Try a tile-based approach for GtkPixelCache to avoid having to do a same-surface copy (usign an intermediate surface) when scrolling the cache. An alternative to tiles is to keep track of an origin within the surface: ++--+ | Bot R | Bottom left | || | +O--+ | Top R | Top left | || | || | || | || | || | || | || | ++--+ with the contents of the surface addressed modulo width and height. Scrolling is then just a matter of moving that origin, but copying from the surface may require four separate blits. Similarly, rendering to some rectangle may have to be split into four separate operations. Søren ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: New drawing/scrolling model
On Thu, May 2, 2013 at 6:03 PM, Søren Sandmann sandm...@cs.au.dk wrote: Alexander Larsson al...@redhat.com writes: * Try a tile-based approach for GtkPixelCache to avoid having to do a same-surface copy (usign an intermediate surface) when scrolling the cache. An alternative to tiles is to keep track of an origin within the surface: ++--+ | Bot R | Bottom left | || | +O--+ | Top R | Top left | || | || | || | || | || | || | || | ++--+ with the contents of the surface addressed modulo width and height. Scrolling is then just a matter of moving that origin, but copying from the surface may require four separate blits. Similarly, rendering to some rectangle may have to be split into four separate operations. this is where trying to be too generic hurts. a given widget knows its aspect ratio. for things that are short and wide, their pixel cache will consist of a set of full-height, partial-width surfaces. for things that are tall and narrow, their pixel cache will consist of a set of full-width, partial-height caches. for things that are short and narrow, their cache will consist of a single surface. for things that are wide and tall ... well, they're on their own ... ___ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list