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 that. 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 "tick" > * 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. Cheers _______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list