On Thu, 2012-10-04 at 08:09 -0400, Alexander Larsson wrote: > > Some open questions in my head about the frame synchronization work:
[...] > > * For pausing the main event delivery, what we currently do is that > > we queue events but don't dispatch them. This could conceivably > > cause ordering problems for apps that use filters, or for work > > in GDK that is done at the translate stage - since we are not > > pausing translation, just pausing delivery. Alternatives: > > Are you sure that is really a problem? The x11 gdk_event_source_check() > code will never even look for a message if there is any GdkEvent queued. > And if there is nothing queued _gdk_x11_display_queue_events() will stop > as soon any X event was converted to a queued GdkEvent. And, since this > queued event will not be read due to the pause we will never process more > X events until resume events. That gets into the details of exactly how I implemented event pausing, but logically speaking, if event delivery is paused, and a new event happens, it needs to be queued up in GDK, Xlib, or in the X server. If we don't translate events, then either: * Event is queued in Xlib, XPending() starts returning TRUE * Event is queued in XServer, the file descriptor Either situation is going to make us start spinning currently. But leaving that aside, we *need* to translate events or we'll never get _NET_WM_FRAME_DONE and unfreeze event delivery. My current preference is to just unfreeze all event delivery at the end of drawing the frame, and not wait for _NET_WM_FRAME_DONE. Then we can make pausing *really* pausing - not unqueue, not translate, etc. I don't see any real disadvantage of doing things that way. [...] > What I do however worry about is the combination of multiple GdkPaintClocks > and gdk_display_set_events_paused(). It seems to me that each paint clock > assumes it has full ownership of the display, calling set_events_paused(FALSE) > whenever it has finished its paint cycle. However, could there not be other > paintclocks (say for another toplevel) being active at that time? Yes, this is an issue. However, if you switch to the above approach, then all you have to do is to properly reference count the event-pausing - once we reach the GDK_PRIORITY_EVENTS + 1 idle, we want to pause *all* event delivery until we are done with new frame handling. > Another thing I worry about is offscreen window animation. If you have an > window > with an embedded offscreen inside, then queueing a redraw on a widget inside > the > offscreen will cause a repaint cycle. When drawing to the offscreen this will > generate damage events that will cause the embedding widget to repaint itself. > However the damage events will be emitted during the paint phase, and the > parent > widget will not get these until the next frame. This will cause a delay of on > frame > which may look weird. Hmm. So your concern is that the connection between the embedded offscreen and the embedder is purely at the GTK+ level - if GDK_DAMAGE events are not delivered to GTK+, then the the embedder won't know to repaint. I think the normal way it would end up working is: offscreen paints a frame, damage events are generated damage events are delivered, new frame is queued for the embedder embedder paints a frame, waits for _NET_WM_FRAME_DONE offscreen paints a frame, damage events are generated damage events are delivered, new frame is queued for the embedder _NET_WM_FRAME_DONE arrives embedder paints a frame, waits for _NET_WM_FRAME_DONE offscreen paints a frame, damage events are generated damage events are delivered, new frame is queued for the embedder _NET_WM_FRAME_DONE arrives So the offscreen will generally paint during the wait for _NET_WM_FRAME_DONE, and immediately get incorporated into the next output frame. Though once things get loaded down and slow, there is no guarantee of this. To do better than this, I think you need to slave the clock for the offscreen into the clock for the window that is embedding it. If the size of the embedded widget is free-floating and not constrained by the allocation of the embedder, then the slave clock would simply do the complete cycle inside an ::update handler. If you want integration of size-negotiation, then you'd have to do different phases at different points in the master clock cycle. And yes, the delivery of damage as events is problematical for that kind of slaving - maybe we would need to have a signal on GdkOffscreenWindow to allow getting as-it-happens notification of damage. - Owen _______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-devel-list