Wayland driver development - December 2021 update and next steps

Alexandros Frantzis alexandros.frantzis at collabora.com
Wed Dec 15 11:29:41 CST 2021


On Wed, Dec 15, 2021 at 09:55:39AM +0100, Giovanni Mascellani wrote:
> Hi,
> 
> first of all, thanks for your work on this.

Hi Giovanni!

> On 10/12/21 18:56, Alexandros Frantzis wrote:
> > The first is when applications try to render to window created by
> > another process. Although this not a typical scenario, it's how
> > Chrome/Chromium and thus applications using CEF, including some game
> > store apps, work. For now, the workaround is to instruct the application
> > to use "in-process" GPU handling (with the "--in-process-gpu"
> > command-line) or turn-off GPU rendering completely (typically with
> > "--disable-gpu --disable-software-rasterizer"). For example, one can run
> > GOG Galaxy with: "GalaxyClient.exe --in-process-gpu [--use-angle=d3d11]"
> 
> Could you expand a little bit on what is the problem here? My (admittedly,
> limited) understanding of Wayland's general philosophy is that it doesn't
> care about how the process computes what should appear in a window. It just
> expects a buffer with the pixel data in it, and it has some efficient way to
> move that buffer from the client to the compositor, which then does
> compositing and brings the result to the screen. But if you can efficiently
> move a buffer from a client to a compositor, it doesn't sound that much
> harder to move it from a client to another client and then to a compositor,
> thus basically allowing a process to draw on another process' window. What
> am I missing?

You aren't missing anything, your description of how things work in
Wayland is correct, and the core of the solution you describe is a
possible way forward. The issue at the moment is mainly with the
complexity of implementing such a solution, rather than with some
fundamentally unsolvable problem.

I don't think I will have a full picture of the details and pain points
until I get the chance to focus my attention on this a bit more, and
perhaps create some prototype implementation, but my current thoughts
are: the process that does the rendering needs to deal with formats,
allocate offscreen buffers, make them available to the application at
the right points (e.g., GL MakeCurrent, vkAcquireImage) so that
applications draw into them.  Then at VkQueuePresent/SwapBuffers time we
need to send them, along with any related fence objects, to the process
that owns the window. The window-owning process will then need to
present the buffer, but also keep track of when the buffer is released
and then "return" it back to the rendering process.  We might want to
add additional features like supporting the dmabuf-feedback Wayland
protocol for dynamic swapchain reconfiguration etc. We essentially need
to reimplement a large part of the functionality provided by
VkSwapchainKHR and EGLSwapBuffers in a way that works across processes,
managing and synchronizing everything manually.

Something similar would need to happen for the non-accelerated cases
when using SHM buffers.

Then there is the question of how the IPC to send the buffers and fences
would actually work. Since both buffers and fences are represented as
unix FDs, I was initially thinking that I would need to manually set up
socket based side channels. I then found wine_server_fd_to_handle and
DuplicateHandle, which along with a cross-process window message could
in theory cover all our IPC buffer/fence needs. If I am not missing
anything, and this is indeed possible, it could make things much simpler
on the IPC front.

Performing buffer passing in Wine is not the only way forward. Another
solution would involve a new Wayland extension that would give us access
to Wayland surfaces from different Wayland connections in a secure
manner. In fact there is an existing protocol that allows some very
limited interaction with such surfaces ("foreign surfaces"), namely
changing parentage/ownership of toplevel surfaces.

However, given that expanding the scope of such interactions to allow
cross-connection/process buffer commits is somewhat contrary to the
per-connection nature of Wayland objects, and that there is a client
side alternative (i.e., what I described above) however complex it may
be, such a protocol could be a hard sell to Wayland upstream.

> One problem commonly mentioned about windowing drivers is that they are hard
> to test. My understanding of the reason is that they have to interact with
> external systems (X11, Wayland, native Windows, ...) that are hard to mock
> (especially, hard to mock in a way that preserves all the quirks we have to
> care about) and hard to configure so that their behavior is predictable and
> testable. Does a Wayland driver has a hope to make things any easier here?

Wayland is a mixed bag here.

On the one hand it doesn't provide official mechanisms to inspect the
state of most objects (let alone when they originate from another
process or Wayland connection), or control some properties (e.g., global
position). There is also the inherently asynchronous nature of the
Wayland protocol, that, depending on what you are testing, may cause
complications.

On the other hand, it's at least conceivable (although not trivial) to
create a custom test compositor that would provide tailored and
predictable behavior and would expose or control state through some
custom mechanism. For example, the Weston reference Wayland compositor
implements an internal Wayland protocol extension allowing clients to
control various state for its internal testing purposes.

Furthermore, the protocol itself is relatively narrow and easy to work
with, so mocking the used protocol subset through a custom interface in
the code shouldn't be too hard. Finally, inspecting the protocol traffic
at the wire level to extract meaningful state is also an option [1].

Thanks,
Alexandros

[1] See https://wayland.freedesktop.org/extras.html for some interesting
    tools that inspect Wayland protocol traffic.



More information about the wine-devel mailing list