Re: New drawing/scrolling model

2013-05-07 Thread Alexander Larsson
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

2013-05-07 Thread Alexander Larsson
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

2013-05-07 Thread Alexander Larsson
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

2013-05-03 Thread Alexander Larsson
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

2013-05-03 Thread Alexander Larsson
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

2013-05-03 Thread Paul Davis
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

2013-05-03 Thread Alexander Larsson

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

2013-05-03 Thread Matthias Clasen
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

2013-05-02 Thread Alexander Larsson
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

2013-05-02 Thread Paul Davis
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

2013-05-02 Thread Alexander Larsson
 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

2013-05-02 Thread Bastien Nocera
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

2013-05-02 Thread Søren Sandmann
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

2013-05-02 Thread Paul Davis
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