I feel configure events and requests are messed up

Giovanni Campagna scampa.giovanni at gmail.com
Thu Sep 8 12:58:34 PDT 2011


Il giorno gio, 08/09/2011 alle 14.31 -0400, Kristian Høgsberg ha
scritto:
> 2011/9/7 Giovanni Campagna <scampa.giovanni at gmail.com>:
> > [...]
> >
> > You say it: "it's more important that clients always know exactly that
> > the buffer size of the EGLSurface they're rendering to corresponds to
> > the size of the window". If you don't resize the buffer as soon as the
> > window is resized server-side, you end with the client drawing a buffer
> > of the wrong size, at which point either the compositor bows to the
> > client and draws the entire buffer, or the buffer is clipped.
> > The only way to control rogue clients is to ensure that the
> > implementation, at the either side of the socket, agrees and enforces
> > the same limits - and since policy should not be in the hands of
> > low-level libraries, it flows naturally that whatever the compositor
> > says, they client must obey.
> > A great, positive advantage X11 has, compared to other windowing system,
> > is the window manager, that ensures consistent behavior and policy
> > across all applications, irrespective of the toolkit used or the Human
> > Interface Guidelines of the originating project. xterm resizes like
> > konsole, like gnome-terminal, like xfce4-terminal, despite being all
> > completely different code bases, and this only thanks to window manager.
> > Consistency is what I want to achieve (or rather, to preserve, as this
> > is already in X11) - by centralizing all decisions.
> 
> I dont see anything in what you say here that argues against the way
> Wayland works today.

Yes, because you are letting applications call gdk_window_move_resize()
and the compositor has no way to prevent the effects. I have nothing
against having GDK calling wl_egl_window_resize,
cairo_gl_surface_set_size, cogl_onscreen_update_size, etc. as part of
interactive resizing, and I have nothing against the compositor
accepting any buffer in that time. But outside of that, I want
applications to respect the given size.
It's like a widget system: from a widget implementation, you can ask a
bigger size, but you cannot actually draw at the new size until you're
allocated again, and you have no guarantee that you'll be actually given
the preferred size.

> > You want a concrete example? Consider edge tiling: in that mode, the
> > window is not resizable, and attempts to programmatically resize it
> > should be cached and reapplied when the window is desnapped. Shall we
> > tell the client it is edge tiled? If we go that road, we end up with
> > EMWH, trying to specify all possible window states...
> 
> Yes, the client needs to know that it can't resize at that time.  You
> can't force clients to behave a certain way by just clamping their
> size, they have to understand that they're being displayed in a
> certain way that means they can't currently resize freely.  Maybe
> we'll need a flag in the configiure event that tells the client "be
> this exact size" or maybe the client just needs to know that it's edge
> tiled and cant try to resize.

I disagree. There are two paths here: one is programmatical resize, for
example because the logical contents (the widgets, that is) of the
window changed, and the other is interactive resize.
The former should be preceded by a constraint change (so if the
egde-tiled size is no longer possible, the compositor automatically
de-tiles), but should be vetted by the wm before it actually happens.
This is not a problem for flashes, as it will happen only once in a
while.
The latter instead should be always initiated by the compositor, using
keybindings or server-side frames. There is no need for the client to
know if the window is resizable by the user or not, as UI hints will be
placed by the compositor.
The middle ground is animating a programmatical resize, and this is
where wayland works well, as the buffer is first prepared at the new
size and then immediately composited. We can still let the compositor
have a say in this with a flow similar to this:
- the higher level toolkit notices that the window should change size,
and invokes gdk_window_resize with the target size
- GDK asks the compositor if this is OK
- the compositor replies with a configure_notify event with the target
size, essentially saying "go ahead", and enters a special "animated
resizing" mode
- the higher level toolkit animates the resizing by issuing a redraw at
a fixed interval and asking GDK for a buffer of the interpolated size;
the redraw function invoked by the higher level toolkit is given the
interpolated size, rather than the value of gdk_window_get_size()
- once each buffer is complete, libEGL attaches it and the compositor
blits it on screen, until it receives a buffer of the target size, at
which point the animated resize is over and the compositor goes back to
normal policy of wrongly sized buffers

>>[...]
> >
> > And that's my problem with it: toolkits needs to be mixed. I'm not
> > saying mixing Qt and GDK (although Qt wants to load Gtk to render GNOME
> > themes...), but of GDK, Cairo and Cogl. You don't want Cairo to depend
> > on Gdk or Cogl (one of the maintainers already told me that this is not
> > acceptable, as Cairo wants the maximum portability),
> 
> Did you notice cairo_xlib_surface_set_size()?  Cairo doesn't magically
> listen for X events and resizes the cairo surface behind the toolkits
> back.  Cairo works the same way.

True, but the only place that wants to call
cairo_xlib_surface_set_size() is Gdk (or whoever created the surface in
the first place). Bad things happen if application code invokes it, and
I consider it cleaner if we can prevent it from the very beginning, by
not having a cairo_wayland_surface_set_size().
But anyway, this is not important, as long as it updates only cairo
internal state, and not actually resize the window on screen.

> > and neither Cogl
> > probably wants to depend on GDK; but on the other hand, the window
> > should be created by GDK and handled by GDK (as most of non-rendering
> > stuff, like events, drags and management must be handed by GDK, if not
> > by the upper layers), so there should be a way for GDK to hand out some
> > sort of "window object" down to Cogl and Cairo, with all necessary state
> > and change notifications. And then there is the problem of libEGL, as it
> > can't of course depend on any toolkit, but must still preserve state and
> > receive notifications.
> 
> There is no window object other than GdkWindow in GTK.  Gdk manages
> the event for the underlying window, and creates a cairo surface at
> the size it things the window is.  I don't know the details of Clutter
> and GDK integration, but I understand you know that area pretty well.
> However, in that case, GDK is still going to handle resizing and can
> just push the size down to cogl, which then calls
> wl_egl_window_resize().  In that way, cogl would work much like cairo.

GdkWindow is not a window object, or at least not what I mean with
window object. GdkWindow is an abstraction over window objects provided
by the native system (Window XID, HWND), and shares state with the
underlying objects, allowing a different library that only implements
the native system.
This is what allows for example Gdk and Cogl to work together, without
Cogl knowing about Gdk or Gdk knowing about Cogl: all they know about,
and the only interface for them is libX11. Resizing is just part of the
picture: if all events and client state changes need to be pushed down
by an integrating library, I imagine things will get messy as soon as
wayland becomes more complex.

> > In X11, handling a Window XID plus a set of XEvents is enough;
> 
> No, in X11 there is a different event stream for resizing the
> underlying GLX/EGL surface.  In DRI1 it was really bad, since we used
> a bit in a shared memory area to notify libGL that the window had
> changed and libGL would then do a roundtrip to the server to get the
> new size.  In DRI2 we're now using a DRI2 invalidate event that
> triggers libGL to go out and do a roundtrip to ask for a new set of
> buffers in the size that X thinks the window is.  X, the wm and the
> client are all different processes.  At any given time during
> interactive or animated resizing, the toolkits idea of size, libGL
> idea and the X servers idea is likely to be out of sync.
> 
> We don't want the EGL buffers to match the latest size from the
> server, we want them to match the size that the client saw when it
> scheduled its redraw.  Wayland resizing is designed so that there's
> one predictable flow or pipeline of resize events instead of hitting
> different parts of the stack with different resize events at different
> times:  The new size comes from the compositor (in case of interactive
> resizing) or the clients animation framework (in case of animated
> resizing).  The toolkit receives that size and relayouts widgets and
> schedules a redraw.  The redraw triggers and tells the rendering
> library what size we want the surface to be, renders the frame and
> then finally presents the frame to the compositor, which atomically
> updates the contents, size and position of the surface.

You don't want EGL buffers to match the size when the client scheduled
the redraw, you want them to match the size that will be drawn on the
screen. Since you first create a buffer and then draw on it, the
application can query (or obtain) the buffer size at the beginning of
redraw procedure, so if the compositor in the mean time comes in and
says "no, this size is not good for you", the application won't map the
wrong buffer.

> And I suspect this talk about "letting the toolkit have the final say"
> is what is making you see red, but realize I'm not arguing that we
> should let clients go crazy.  Well behaved clients will allocate the
> size they're asked to, render a new frame and send that back to the
> compositor.  That's what pretty much what all clients will do and
> that's the case we have to optimize for.  The case where a badly
> behaved client tries to use a wrong size is going to look bad when we
> clip it, whether we do it in client side EGL or in the compositor.

Yes, but in the middle of this is policy. If the originator of a resize
is not the user, how the application can know that the new size is good?
We need some way for central policy to kick in, and that's what I'm
asking for with the explicit "configure" request. All the rest,
including buffer sizes, is tangential and a big misunderstanding caused
by my original email.

Giovanni

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 316 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20110908/de66e851/attachment.pgp>


More information about the wayland-devel mailing list