But the OpenGL/Vulkan surface is not the window surface, and I don't see why GL/VK drawing should have anything to do with their parent window surface, except passively reacting to its size changes.
(I am assuming by "window surface" you are referring to the `window_surface` abstraction)
I think the difference in perspectives stems from me considering both GDI+flushing (window surface) and GL/VK drawing to be different but equal ways of presenting contents to a window/surface, and thus the current "ack-configure along with new contents" logic applies equally to both. The fact that in the Wayland driver we have to use a subsurface to allow us to mix GDI+GL/VK content is an extra implementation detail that additionally makes us introduce the "ensure contents" logic.
My perspective was formed because these ways of providing content can and do work independently in some cases (e.g., presenting GL/VK without window surface contents, and hence this whole discussion here). This seems not to matter for other systems, but it does for Wayland as described in previous comments.
If I am not misunderstanding, your perspective is that the window surface plays a special/authoritative role in terms of window content and other ways are secondary and are, at least conceptually, dependent on the window surface.
I do think both viewpoints have merit, but perhaps that doesn't even matter in the end: if we are able to implement your proposal to ensure a flush before presentation it will effectively remove the main reason that formed my perspective.
You can create a GL/VK surface on a message or an invisible window, with no window surface, or a child window which would ultimately use its ancestor toplevel surface as a support.
Sure, but I don't see how this invalidates the necessity of "ensure contents" or "ack-configure" when rendering to a visible toplevel HWND. If these actions are not needed they just become noops. Note that for child windows GL/VK rendering we may actually need both of these recursively up the window chain (depending on what funky stuff apps want to do and how we end up implementing child GL rendering, e.g., fullscreen toplevel->fullscreen child->fullscreen GL, and toplevel/child are never drawn with GDI).
Assuming we have some logic in win32u, do you think it could work if we ensure that the toplevel window surface is flushed before presenting (ie: calling surface->funcs->flush -> wayland_window_surface_flush)?
Yes, I think doing a flush before every present would work, although I would like to experiment to verify. In the flush function the Wayland driver could check if there is a client subsurface and perform the necessary actions (i.e. ensure contents, ack configure) as needed, even if the flush bounds are empty.
One potential downside is that without other information we would base our decision just on the existence of a client subsurface, regardless of whether that subsurface is going to be rendered to. The current approach only performs the extra actions when we know it's absolutely necessary. Perhaps a hint that this is a pre-presentation flush would help if this turns out to be a problem, or use a different function altogether, e.g., "prepare_for_external_present".
I do wonder, though, if forcing a flush in this way could lead to glitches, e.g., with multiple threads, and there is complex GDI drawing going on and we flush in the middle of it (between operations that lock the window surface). Perhaps we should only perform this flush if the bounds are empty, or go with the "prepare_for_external_present" as mentioned above.