Hi, On Fri, Oct 22, 2010 at 10:28 AM, David Zeuthen <zeut...@gmail.com> wrote: > If you believe that the GUI thread should never perform blocking IO > (such as reading from disk or IPC) or never perform CPU-intensive > tasks (such as image- or video-decoding) then... then all that your > code in the GUI thread does, is to receive data from one thread and > maybe signal another thread.
This point only affects the "constant factor" though right, not the basic character of what's going on. If I have a spinner animation and that paints flat-out as fast as possible without a "yield gap" to let other sources run, then that _also_ starves a superfast main loop source that just sits there grabbing messages and then throwing them elsewhere, just as much as it starves a super slow main loop source. Speed is not the problem, it's whether the source runs at all. If you go the other way and want to starve painting if we're doing our fast message throwing, then you're relying on always processing messages faster than the other side can send them. Being "fast" is not enough; it has to be "faster," i.e. it has to catch up and empty the queue. In fact *all* active main loop sources have to happen to be caught up *on the same iteration*. So if you're emptying three queues you have stay ahead of all three senders at once and get them all to zero at the same moment, and only then can you paint. There's no special guarantee you can do that. You're relying on it happening to work out. Imagine two processes that are both following the rules and have 10 streams open to each other and they are both processing all 10 at a superfast rate just tossing messages back and forth. What's the latency between occasions where these processes have 0 sources to dispatch? That drives your framerate. While 10 streams between two apps sounds contrived, I don't think one big complex app with say a sound server and some downloads in the background and some other random main loop tasks is all that different. > Anyway, my point really was something like this: If you want to talk > about smooth animations and synchronoizing to vblank, it would > probably be good for GPeriodic, Clutter and GTK+ to specify what > people should and shouldn't be doing in the "GUI Thread".... I know a > lot of it is obvious to people on this list but it never hurts to > write it down anyway. With my "finite-length yield gap in the paint loop" approach, I think you can do anything in the GUI thread as long as each single dispatch is fast (and bounded in time). So you can't block, but you can do anything that is _always_ pretty fast (you can't do things that are _usually_ pretty fast, such as drain an unbounded queue, or blocking IO that sometimes decides to hang for a bit). That's how I'd document it. The one thing that still breaks is if all your fast-dispatching GSource add up to not-fast, since we have to dispatch all or nothing at each priority. Solving that could be overkill though. File under "someday." With a yield gap, you need threads to block or to do an indivisible long computation, but you don't need threads just because you have a queue (or a divisible computation, which is basically a queue). In the more classic approach (paint priority stays constant regardless of time elapsed), I think you can do anything in the GUI thread as long as: - each individual dispatch is fast AND - (an animation is allowed to starve whatever you are doing indefinitely so you can be below paint priority OR - the sum of all dispatches that could occur in a single frame timespan is fast and bounded. No queues. Long computations are no good even if split up across dispatches. So you can be above paint priority.) it isn't clear that all long, but divisible, computations can be tossed out of the UI thread. "filling a Tree/TextView" is a good example of how "UI" vs. "not UI" is kinda fuzzy.... To avoid queues in the main UI thread, you need both source and sink to be threadsafe, and real-world unthreadsafe sources include say libdbus, real-world unthreadsafe sinks include say GtkWidget. One thing, it doesn't matter if paint priority is default or idle. The issue is created when it's fixed with respect to "other stuff," instead of changing priority dynamically. Anyway, yes, this only matters for a large complex app doing lots of stuff in the same process as painting, while also trying to avoid dropping frames. For any simple case, things just muddle through. Havoc _______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list