Re: synchronizing window frame/client repaint



Havoc Pennington <hp redhat com> writes:

> Some of us have been discussing/experimenting with ways to make opaque
> resize look better. Soeren Sandmann has a really nice analysis of the
> problem (Soeren maybe you could post that here?). 

Here is a slightly updated version of the notes I sent to you:


        - There are two laggings that we should care about,

              (a) lagging between window frame and application
              (b) lagging between mouse cursor and window frame

          Type (a) lagging is much more annoying than type (b) because
          it looks like the window breaks. Too much type (b) lagging
          makes resizing feel slow.

          It would be possible to get completely rid of type (a)
          lagging by doing double buffering and/or backing store in
          the X server, but note that the lagging does not disappear;
          the only thing an X double buffering extension will do for
          this problem is convert type (a) lagging into type (b)
          lagging.


        - The current behavior (without any patches) can be analyzed
          like this:

          The X server gives priority to the window manager over the
          application because the window manager is getting input
          events, and the application isn't. This means the window
          frame is painted one roundtrip after the mouse event is
          generated, so if we denote the roundtrip time by R, the
          type (b) lagging with the current behavior (measured in
          number of mouse events) is R/M, where M is the time between
          two mouse events.

          The type (a) lagging of the current behavior is the number
          of mouse events that arrives during the time when the
          application and the X server is relayouting and painting the
          window. Since the window manager is prioritized over the
          application, the time spent on frame painting also
          contributes to the number of events. The lagging, measured
          in mouse events, equals the number of events arriving during
          the time spent both on painting the app and on painting the
          frame:

                n = (P_a + n * P_f) / M

          Here n is the number of events of type (a) lagging, P_a is
          the time it takes to repaint the appliction, and P_f is the
          time it takes to paint the frame (both including the
          necessary roundtrips). Solving the equation in n gives:

                n = P_a / (M - P_f)

          Not surprisingly, the lagging is proportional to the time
          spent relayouting/repainting the application. What's more
          surprising is that the time spent painting the frame can be
          significant. As P_f tends to M, the denominator tends to
          zero, and the lagging tends to infinity. This is a
          reasonable explanation for the really bad lagging we are
          seeing. 

          This means that just pasting over the problem with some X
          extension is not going to solve anything, because that would
          just get us really bad type (b) lagging instead.


        - With Havoc's patches a lot of frame painting is eliminated.
          The window manager never sends a new paint request before
          the old one was completed (ignoring the timeout for now).
          The type (a) lagging is now directly proportional to the
          time spent painting:

                n = P_a / M

          This is much more reasonable, but because the lagging can
          never be zero with this scheme, it is not a full solution.
          It would have to be used with a double buffering X
          extension, at least as a long term goal.

          The type (b) lagging with the scheme is the number of events
          that arrives between two frame paintings. That number is in
          the worst case

                n = (P_a + R + P_f) / M

	  Note that the sum of the two laggings can never exceed the
	  lagging between application and mouse cursor, and that
	  lagging is also proportional to P_a + R + P_f, so what
	  happens in practice is that there is some constant lagging
	  between mouse cursor and application with the frame
	  somewhere in between.


        - If we were block the window manager on the counter, we would
          gain two things: 

                (1) the type (a) lagging would be become a short
                    flicker between when the server draws the
                    application and when it draws the frame.

                (2) we would save a round-trip in total lagging, so
                    the type (b) lagging would be (P_a + P_f)/M
                    instead of (P_a + R + P_f)/M.

          The problems doing that would be

                (1) The type (a) lagging would become type (b)
                    lagging, so we wouldn't gain much compared to
                    Havoc's patches combined with an X extension.

                (2) The window manager would become more complex, and
                    it is not clear that blocking would not be
                    harmful.

                (3) we would still have a short flicker between frame
                    and application.

          But since the only real improvement would be saving one
          round-trip, I don't think this is worth doing.

Other more random notes:

        - All these approaches take place in the window manager and
          require the same from the application. This means we can
          specify the application behavior ("increment a counter when
          you are done handling the configure event") and still
          experiment with different approaches in the window manager.

        - Since the behavior is still not as good as Windows on my
          machine, not even if I pretend the type (a) lagging is not
          there, I think some work to reduce P_a (ie., speeding up
          gtk+ and/or the X server) would be worthwhile.

	- The window manager could have separate X connections for
          each window. That would make blocking less likely to cause
          damage.


Søren



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