Re: Doubts about GPeriodic

Hi Owen,

A few questions, if you don't mind me picking your brain:

On Wed, 2010-10-20 at 14:58 -0400, Owen Taylor wrote:
> The real problem is that the phases of the repaint cycle matter. We
> don't just have a bunch of stuff we need to do every frame, we need to
> do things in the order:
>  * Process events

The only benefit I see to processing input events at the start of a
frame cycle is that we possibly get to merge them.  We probably do want

What about non-input events, though?  Like, if some download is
happening and packets are coming in and causing dispatches from the
mainloop that we do not have control over.

Do we try to ensure that those people treat this 'external stimulus' in
the same way that we treat events (ie: possibly merge multiple incoming
packets so that they update their UI state only once in response to it)
or do we want them to just call the GTK API on the spot and risk
duplicated work because that's quite a lot easier to understand?

Maybe we should have some mechanism that allows them to choose.

If we elect not to have that mechanism, then the input problem is
actually quite easy, by virtue of the fact that there is only ever one
person managing input from the X server.

>  * Update animations


>  * Update layout

Clutter and GDK want to do two different things here, it seems.
Presently (and almost by chance) GPeriodic is emitting a "tick" signal
after running all of the tick functions and Emmanuele is using this to
run "stage updates" on all of the Clutter stages.  This is a little bit
like Gtk managing it's geometry but not exactly.

In Gtk's case, we have a chance to do this a bit more programmatically -
only run layout adjustments on widgets/windows that have been marked as
requiring some resize (ie: toplevels and containers with
GTK_RESIZE_QUEUE themselves).  That could be handled from a 'tick'
handler, or we could add some more hooks to GPeriodic.

A reason that I think it makes sense to do layout updates separate from
repainting is that layout updates can result in us wanting to change the
size of our toplevels (eg: someone opened GtkExpander).

This is a *really* tough problem because if that happens, we can't just
paint.  We have to wait until the window manager has actually given us
our new size.  I did some benchmarking, and that tends not to happen
until about 1ms later (a bit less for metacity, a bit more for compiz
and mutter).

So do we block the mainloop for ~1-2ms and desperately suck from the X
socket until we receive ConfigureNotify (at least until some timeout)?
Do we skip drawing the window and wait until next frame if we have a
pending ConfigureNotify?  Is there some way we can abuse
_NET_WM_SYNC_REQUEST to make this problem easier?

On the Gtk experiment branch, layout updates are actually done pretty
much "on the spot" right now (ie: you make some changes to the layout
which will queue a idle that will run pretty much immediately).  There
have been no changes to this part yet.

>  * Repaint

This part is what I originally intended the damage/repair mechanism to
be used for.

> If GTK+ and Clutter are working together in the same process, then we
> still need to go through those phases in the same order and do
> everything for each phase.
> It looks like GPeriodic has two phases:
>  - Tick
>  - Repair
> Which I guess are meant to be "update animations" and "relayout and
> repaint". I can sort of see how I can squeeze the right behavior out of
> it given various assumptions. In particular, you need to only ever have
> one one repair function that does all the work of relayout then repaint
> - you can't have separate repair functions for relayout and repaint. Or
> for clutter and for GTK+.

GPeriodic is probably going to need to gain some more phases, indeed.  I
don't plan to have relayout and repaint shoved into the same stage for
the reasons listed above, but also for reasons of sanity.

> But does an abstraction make sense at that point? If we need to
> explicitly glue GTK+ into clutter or clutter into GTK+ using hooks
> provided in GTK+ and Clutter, then all that GPeriodic is doing is saving
> a bit of code reuse.

Right.  Another way we could do this is by having some hooks in Gtk:

  - do this
  - do that
  - do the other thing

and have those clocked internally by Gdk in the Gtk-runs-itself case and
by Clutter in the Clutter-runs-Gtk case.

That certainly could make sense for the "set tasks" like layout,
drawing, etc.  In fact, all of these things could be driven by
one-big-handler on the "tick" signal that GPeriodic currently emits.

For timeline advancement, however (ie: the stuff that the user wants to
do) I think an abstraction like GPeriodic is quite useful.  It gives a
common place that users can register their animation hooks that works
the same way for both Clutter and Gtk.  It prevents us from having some
timeline system within Gtk that is clocked by Clutter telling Gtk "run
all your timelines now!".  Cody is creating a timeline class right now
as part of his experimenting, and I could easily see that we might want
that in GIO alongside GPeriodic.

That seems like a bit of a weird fit, of course, but we long-ago decided
that libgio was intentionally destined to become libkitchen-sink.  Also,
the smooth changing of a variable over time is not necessarily related
to animation or graphics, and people could easily want to create their
own GPeriodic.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]