Discussion:
[RFC wayland] System compositor protocol
Jason Ekstrand
2013-08-23 21:55:41 UTC
Permalink
Hello All,
I am in the process of picking back up the old idea of system compositors.
I am not, at the moment, looking for a review of the code; simply a review
of the concept and the proposed protocol. If you would like to look at my
implementation or try it out, it can be found in the system-compositor
branch of my personal [weston fork on github][1].

What follows is what I envision for system compositors. (Others may have a
different idea which is why I'm writing this RFC email.) The basic idea
behind a system compositor is to provide an interface for compositors whose
only job it is to display other compositors or other stand-alone
full-screen interfaces. I image three primary purposes for system
compositors:

1. As an abstraction layer. Every time someone wants to write a RDP
server, VNC server, android backend, or the like the standard answer is
"write it as a weston plugin". The problem with this is that, to my
knowledge, none of the major desktop environments (GNOME, KDE, EFL,
etc.) plan to run their compositor as a weston shell plugin. This makes
a weston plugin a poor solution in the long term. On the other hand, a
system compositor is fairly simple to implement and provides a backend
to any compositor that can run on top of a system compositor.

2. Simple full-screen clients. With standard VTs going the way of the dodo
bird (see also [David Herrmann's work on logind][2]), we will need a way
for displaying simple full-screen programs such as splashscreens without
every single one of them knowing how to talk DRM/KMS directly. David
has proposed to use a system compositor (which he calls wlsystemc in his
post) so these types of programs can be written as simple wayland
clients. My github repository contains the (almost trivial)
modifications to simple-shm that make it in to one such client.

3. As a DRM/KMS backend for other compositors. Manually dealing with
DRM/KMS isn't actually all that many lines and all of the big
compositors (mutter, Kwin, EFL, etc.) will do it themselves. However,
for people who want to write their own simple compositor, it can be a
bit tricky to get right and raises the barrier to entry. The protocol
I'm proposing is sufficiently powerful to provide most of the basic
multi-output support and modesetting that is needed for a simple
compositor. This means that all a potential compositor writer has to do
is write a system compositor client and they can let someone else get
the KMS details right.

While it sounds like a big task, implementing a system compositor isn't
that bad. The simplest system compositor is one that can simply display
surfaces. In order to do that, you need to implement the following
interfaces:

* wl_compositor
* wl_region
* wl_shm (along with wl_shm_pool and a SHM-based wl_buffer)
* wl_surface
* wl_output

None of those are particularly difficult or complicated to implement. The
hardest is probably wl_surface and that's not terrible.

For input you have two options. The first, most obvious option is to
implement wl_seat and its child interfaces. Second, I have considered the
idea of a wl_raw_input interface (only for system compositors) that simply
provides evdev file descriptors to the client. This would allow for raw
input processing without having to worry about things like weston-launch.
Also the system compositor *may* be able to handle the FD muting etc. for
playing nice with logind. (I'm not sure on that one yet, I'd have to ask
David.)

One more note on input: I do NOT expect the system compositor to do any
significant input processing. Even if the child compositor is getting its
events through wl_seat, I expect them to be about as raw as possible. In
particular, this is not where things like pointer acceleration should be
handled. Once we get a pointer_grab interface working, I expect any
compositor that runs on top of a system compositor to attempt a pointer
grab almost immediately and do its own pointer handling from there.
Otherwise it is impossible for the client compositor to re-arrange the
outputs without additional protocol.

Along with the basics as described above, a system compositor could
optionally implement additional interfaces to provide aditional
functionality. For example:

* A RDP system compositor could implement wl_data_device to allow for
drag-and-drop and clipboard sharing between host and client.

* A system compositor could expose wl_subcompositor and use subsurfaces to
allow the client compositor to take advangage of hardware compositing.
Note that this is not as simple as it sounds because hardware frequently
has limits on the number, size, and placement of such overlays and there
is currently no way to communicate that information through the
subsurface protocol. Therefore, the system compositor could find itself
doing a full composite anyway.

* A wl_user_switcher interface could be created for login managers. This
steps on logind a bit, but someone may find it useful.

That is about all I have to say for now on the subject. If you want to
check out my current implementation you can look at my github as I said
above. As of right now, I have multi-monitor weston running inside of my
weston-based system compositor. Also, I have simple-shm modified to act as
a simple system compositor client if finds the wl_system_compositor global.
The only mode that works right now is "center" but I'm working on getting
the others to work.

I appreciate any questions or comments you may have on either the main
ideas (above) or the protocol (below).

--Jason Ekstrand


[1]: https://github.com/jekstrand/weston
[2]: http://dvdhrm.wordpress.com/2013/07/08/thoughts-on-linux-system-compositors/




Protocol follows:
-----------------

<protocol name="system_compositor">
<interface name="wl_system_compositor" version="1">
<description summary="Displays a single surface per output">
Displays a single surface per output.

This interface can only be bound to by one client at a time.
</description>

<enum name="fullscreen_method">
<description summary="different method to set the surface fullscreen">
Hints to indicate to the compositor how to deal with a conflict
between the dimensions of the surface and the dimensions of the
output. The compositor is free to ignore this parameter.
</description>
<entry name="default" value="0" summary="no preference, apply default policy"/>
<entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/>
<entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/>
<entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
</enum>

<request name="present_surface">
<description summary="present surface for display">
This requests the system compositor to display surface on output.
Each client of the system compositor can have at most one surface
per output at any one time. Subsequent requests with the same
output replace the surface bound to that output. The same surface
may be presented on multiple outputs.

If the output is null, the compositor will present the surface on
whatever display (or displays) it thinks best. In particular, this
may replace any or all surfaces currently presented so it should
not be used in combination with placing surfaces on specific
outputs.

The method specifies how the surface is to be persented. These
methods are identical to those in wl_shell_surface.set_fullscreen.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="method" type="uint"/>
<arg name="framerate" type="uint"/>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>
</interface>
</protocol>
David Herrmann
2013-08-25 14:11:07 UTC
Permalink
Hi
Post by Jason Ekstrand
Hello All,
I am in the process of picking back up the old idea of system compositors.
I am not, at the moment, looking for a review of the code; simply a review
of the concept and the proposed protocol. If you would like to look at my
implementation or try it out, it can be found in the system-compositor
branch of my personal [weston fork on github][1].
What follows is what I envision for system compositors. (Others may have a
different idea which is why I'm writing this RFC email.) The basic idea
behind a system compositor is to provide an interface for compositors whose
only job it is to display other compositors or other stand-alone
full-screen interfaces. I image three primary purposes for system
1. As an abstraction layer. Every time someone wants to write a RDP
server, VNC server, android backend, or the like the standard answer is
"write it as a weston plugin". The problem with this is that, to my
knowledge, none of the major desktop environments (GNOME, KDE, EFL,
etc.) plan to run their compositor as a weston shell plugin. This makes
a weston plugin a poor solution in the long term. On the other hand, a
system compositor is fairly simple to implement and provides a backend
to any compositor that can run on top of a system compositor.
KDE planned on using weston as underlying compositor. But I doubt
GNOME or EFL want to use something like that..
Post by Jason Ekstrand
2. Simple full-screen clients. With standard VTs going the way of the dodo
bird (see also [David Herrmann's work on logind][2]), we will need a way
for displaying simple full-screen programs such as splashscreens without
every single one of them knowing how to talk DRM/KMS directly. David
has proposed to use a system compositor (which he calls wlsystemc in his
post) so these types of programs can be written as simple wayland
clients. My github repository contains the (almost trivial)
modifications to simple-shm that make it in to one such client.
Yay, I appreciate someone picking up this idea \o/
Post by Jason Ekstrand
3. As a DRM/KMS backend for other compositors. Manually dealing with
DRM/KMS isn't actually all that many lines and all of the big
compositors (mutter, Kwin, EFL, etc.) will do it themselves. However,
for people who want to write their own simple compositor, it can be a
bit tricky to get right and raises the barrier to entry. The protocol
I'm proposing is sufficiently powerful to provide most of the basic
multi-output support and modesetting that is needed for a simple
compositor. This means that all a potential compositor writer has to do
is write a system compositor client and they can let someone else get
the KMS details right.
Manually dealing with DRM/KMS _is_ hard. Yes, the basic setup is easy,
but I hate the fact that we now end up with everyone doing it on their
own. Advanced things can get pretty complex, like GPU selection,
multi-GPU handling, GPU hotplugging, CRTC hotplugging, planes,
cursors, DRM-Master, DPMS, DRM properties, atomic modesetting,
render-nodes, .. ugh, this list can get soo long. I am a little bit
scared that EFL or Gnome get it wrong, but ok, not my deal.
Post by Jason Ekstrand
While it sounds like a big task, implementing a system compositor isn't
that bad. The simplest system compositor is one that can simply display
surfaces. In order to do that, you need to implement the following
* wl_compositor
* wl_region
* wl_shm (along with wl_shm_pool and a SHM-based wl_buffer)
* wl_surface
* wl_output
None of those are particularly difficult or complicated to implement. The
hardest is probably wl_surface and that's not terrible.
For input you have two options. The first, most obvious option is to
implement wl_seat and its child interfaces. Second, I have considered the
idea of a wl_raw_input interface (only for system compositors) that simply
provides evdev file descriptors to the client. This would allow for raw
input processing without having to worry about things like weston-launch.
Also the system compositor *may* be able to handle the FD muting etc. for
playing nice with logind. (I'm not sure on that one yet, I'd have to ask
David.)
One more note on input: I do NOT expect the system compositor to do any
significant input processing. Even if the child compositor is getting its
events through wl_seat, I expect them to be about as raw as possible. In
particular, this is not where things like pointer acceleration should be
handled. Once we get a pointer_grab interface working, I expect any
compositor that runs on top of a system compositor to attempt a pointer
grab almost immediately and do its own pointer handling from there.
Otherwise it is impossible for the client compositor to re-arrange the
outputs without additional protocol.
Along with the basics as described above, a system compositor could
optionally implement additional interfaces to provide aditional
* A RDP system compositor could implement wl_data_device to allow for
drag-and-drop and clipboard sharing between host and client.
* A system compositor could expose wl_subcompositor and use subsurfaces to
allow the client compositor to take advangage of hardware compositing.
Note that this is not as simple as it sounds because hardware frequently
has limits on the number, size, and placement of such overlays and there
is currently no way to communicate that information through the
subsurface protocol. Therefore, the system compositor could find itself
doing a full composite anyway.
* A wl_user_switcher interface could be created for login managers. This
steps on logind a bit, but someone may find it useful.
That is about all I have to say for now on the subject. If you want to
check out my current implementation you can look at my github as I said
above. As of right now, I have multi-monitor weston running inside of my
weston-based system compositor. Also, I have simple-shm modified to act as
a simple system compositor client if finds the wl_system_compositor global.
The only mode that works right now is "center" but I'm working on getting
the others to work.
I appreciate any questions or comments you may have on either the main
ideas (above) or the protocol (below).
I really like having an intermediate layer for simple tasks. Some
layer that is well maintained and allows things like plymouth to run
on top of it. However, I dislike calling it system-compositor. Let me
explain why:

In a session there are several different running daemons. Each of them
provides a different service to ease device usage. This includes
pulseaudio, dbus, polkit, colord, .. and of course the
session-compositor (xserver, weston, ...). But all of these run
_inside_ the session. If properly done, they don't need any super-user
privileges. If we switch sessions (whether via logind or via VT
doesn't matter), we can simply change device-access restrictions and
the new session can start running. We handover device access from one
session to another. My work on logind doesn't change this or reinvent
it, it only tries to make it _safe_ and _reliable_.

The idea behind a system-compositor was to provide a system daemon
that runs _outside_ a session. Its sole responsibility is to control
access to graphics and input hardware. So session-compositors no
longer access hardware directly, but instead tunnel it through the
system-compositor. But this means, the system-compositor must know of
session-switches and correctly display only the session-compositor of
the active session. However, session-switching is controlled by
logind, so the system-compositor gets the session-switch notification
_after_ the session was actually switched, making this kind of racy
(but still ok!).
The bigger problem is, the system-compositor is not part of a session
so it has to be active *all the time*. You cannot have some sessions
using the system-compositor and other sessions doing it the old way.
You cannot do device-access handover from the system-compositor to a
self-hosting or legacy session. This would require ugly racy hacks and
conflict with VT!
But if the system-compositor is always active, you cannot use VTs in
text-mode. Because VTs in text-mode access graphics hardware
*directly*.

With this in mind, we ditched the idea of a system-compositor. But
that doesn't mean the idea of tunneling graphics access is wrong! In
fact, I like it a lot, but please don't call it system-compositor! A
system-compositor is what Ubuntu people are trying and RAOF just
recently made me aware that they ran in exactly the problems I just
mentioned. So please don't do that.


So back to your proposal. I'd like to see something like you did but
as a session-compositor (call it whatever you want ;)). So a session
that doesn't want to deal with DRM directly (like for instance
gdm/xdm/kdm) could avoid starting an xserver or weston and start your
session-compositor instead. It then displays it's content via the
standard wayland client APIs on this compositor. But this compositor
imho should run in a session. So it does *not* allow clients from
different sessions to connect. It is *no* system compositor. It's just
a daemon which provides graphics-access to the session. It may even
allow switching between multiple surfaces. And if you continue this
thought, you will notice that it is nothing more than weston but with
a *very* reduced wl_shell. Precisely a wl_shell that displays only one
surface at a time.

So if the protocol is well-defined, we could standardize some path
(eg., /run/user/<num>/wayland-fullscreen-<sid>.socket) which is
provided by such a session-compositor. gdm could then during startup
check whether this path exists (that is, such a compositor is running
in its session) and use it to access graphics-devices. If the API
allows multiple surfaces, a separate "system-log"-process could run in
the _same_ session and use this compositor to display the current
system-log. Your compositor could react to keypresses like alt+1 or
alt+2 (or ESC) to switch between the surfaces. That is, the gdm
session could provide the system-log just one key-press away. Both in
the same session! You don't have to run a full-blown
VT/kmscon/whatever-log for that on another session on VT12..
Post by Jason Ekstrand
-----------------
<protocol name="system_compositor">
<interface name="wl_system_compositor" version="1">
<description summary="Displays a single surface per output">
Displays a single surface per output.
This interface can only be bound to by one client at a time.
</description>
<enum name="fullscreen_method">
<description summary="different method to set the surface fullscreen">
Hints to indicate to the compositor how to deal with a conflict
between the dimensions of the surface and the dimensions of the
output. The compositor is free to ignore this parameter.
</description>
<entry name="default" value="0" summary="no preference, apply default policy"/>
<entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/>
<entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/>
<entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
</enum>
<request name="present_surface">
<description summary="present surface for display">
This requests the system compositor to display surface on output.
Each client of the system compositor can have at most one surface
per output at any one time. Subsequent requests with the same
output replace the surface bound to that output. The same surface
may be presented on multiple outputs.
If the output is null, the compositor will present the surface on
whatever display (or displays) it thinks best. In particular, this
may replace any or all surfaces currently presented so it should
not be used in combination with placing surfaces on specific
outputs.
The method specifies how the surface is to be persented. These
methods are identical to those in wl_shell_surface.set_fullscreen.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="method" type="uint"/>
<arg name="framerate" type="uint"/>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>
</interface>
</protocol>
Yepp, that's all we need. Just rename it from "system_compositor" to
"wl_fullscreen_shell" (I bet you can come up with some fancier name).
No other criticism on this proposal from my side.

Feel free to disagree ;) I am open for suggestions or criticism.
Cheers
David
David Herrmann
2013-08-26 09:02:01 UTC
Permalink
Hi
Hello,
Cedric Bail
Post by David Herrmann
Hi
Post by Jason Ekstrand
Hello All,
I am in the process of picking back up the old idea of system compositors.
I am not, at the moment, looking for a review of the code; simply a review
of the concept and the proposed protocol. If you would like to look at my
implementation or try it out, it can be found in the system-compositor
branch of my personal [weston fork on github][1].
What follows is what I envision for system compositors. (Others may have a
different idea which is why I'm writing this RFC email.) The basic idea
behind a system compositor is to provide an interface for compositors whose
only job it is to display other compositors or other stand-alone
full-screen interfaces. I image three primary purposes for system
1. As an abstraction layer. Every time someone wants to write a RDP
server, VNC server, android backend, or the like the standard answer is
"write it as a weston plugin". The problem with this is that, to my
knowledge, none of the major desktop environments (GNOME, KDE, EFL,
etc.) plan to run their compositor as a weston shell plugin. This makes
a weston plugin a poor solution in the long term. On the other hand, a
system compositor is fairly simple to implement and provides a backend
to any compositor that can run on top of a system compositor.
KDE planned on using weston as underlying compositor. But I doubt
GNOME or EFL want to use something like that..
Indeed, Enlightenment is not planning to use Weston. But if a common library
dealing with all those drm / kms, android, rpi,... did exist, I am sure we
would use it and contribute to it. I am not a big fan of adding a system
compositor as it will impact speed and power consumption. As long as we can
avoid it, and work on systemd / logind seems to go this way, I think it
would be better.
I did try this with kmscon, but I never moved the library out of the
kmscon-repo as it is a quite fast moving target. So it will probably
take a while until we figure out some proper API. And interest seems
pretty low..

[...]
Post by David Herrmann
So back to your proposal. I'd like to see something like you did but
as a session-compositor (call it whatever you want ;)). So a session
that doesn't want to deal with DRM directly (like for instance
gdm/xdm/kdm) could avoid starting an xserver or weston and start your
session-compositor instead. It then displays it's content via the
standard wayland client APIs on this compositor. But this compositor
imho should run in a session. So it does *not* allow clients from
different sessions to connect. It is *no* system compositor. It's just
a daemon which provides graphics-access to the session. It may even
allow switching between multiple surfaces. And if you continue this
thought, you will notice that it is nothing more than weston but with
a *very* reduced wl_shell. Precisely a wl_shell that displays only one
surface at a time.
What would be the benefit over a library that does the job in the
compositor/single application ?
A library would work as long as you have only a single client. But
imagine your login-session also wants a screensaver. You could make
this compositor support a shell which allows a full-screen client
(login-screen) and additionally a screen-saver client.

So as long as your wl_whatever_shell in this compositor is limited to
a single client, I agree, a library would be better. But if you make
it just a little more complex, you should rather use a compositor.

Regards
David
Jason Ekstrand
2013-08-26 17:05:04 UTC
Permalink
Hello,
Cedric Bail
Hi
On Fri, Aug 23, 2013 at 11:55 PM, Jason Ekstrand <jason at jlekstrand.net>
Post by Jason Ekstrand
Hello All,
I am in the process of picking back up the old idea of system
compositors.
Post by Jason Ekstrand
I am not, at the moment, looking for a review of the code; simply a
review
Post by Jason Ekstrand
of the concept and the proposed protocol. If you would like to look
at my
Post by Jason Ekstrand
implementation or try it out, it can be found in the system-compositor
branch of my personal [weston fork on github][1].
What follows is what I envision for system compositors. (Others may
have a
Post by Jason Ekstrand
different idea which is why I'm writing this RFC email.) The basic idea
behind a system compositor is to provide an interface for compositors
whose
Post by Jason Ekstrand
only job it is to display other compositors or other stand-alone
full-screen interfaces. I image three primary purposes for system
1. As an abstraction layer. Every time someone wants to write a RDP
server, VNC server, android backend, or the like the standard
answer is
Post by Jason Ekstrand
"write it as a weston plugin". The problem with this is that, to my
knowledge, none of the major desktop environments (GNOME, KDE, EFL,
etc.) plan to run their compositor as a weston shell plugin. This
makes
Post by Jason Ekstrand
a weston plugin a poor solution in the long term. On the other
hand, a
Post by Jason Ekstrand
system compositor is fairly simple to implement and provides a
backend
Post by Jason Ekstrand
to any compositor that can run on top of a system compositor.
KDE planned on using weston as underlying compositor. But I doubt
GNOME or EFL want to use something like that..
Indeed, Enlightenment is not planning to use Weston. But if a common
library dealing with all those drm / kms, android, rpi,... did exist, I am
sure we would use it and contribute to it. I am not a big fan of adding a
system compositor as it will impact speed and power consumption. As long as
we can avoid it, and work on systemd / logind seems to go this way, I think
it would be better.
My fear here is that if we try to write it as a library, we will end up
writing an entire toolkit-style drawing abstraction. Whatever abstraction
we come up with will not be the same as those used in Qt/EFL/Gtk, and so it
won't be used for the exact same reason they're not using Weston. Maybe
that's not the case, but I'm skeptical. Another option would be to write
some sort of common plug-in API that all of the compositors support but I
think it will suffer from some of the same issues.

Please not that I do NOT expect mutter/kwin/E to use this as a back-end for
DRM/KMS. There are two reasons for this. First is a performance reason
that you have already mentioned. For the standard use-case (desktop
environment on a local machine) we want to streamline things as much as
possible so a library or doing it yourself is a better option. The second
reason is that, in order to make things sufficiently simple that we can
take some of the load off of smaller compositors and/or simple fullscreen
apps such as terminal emulators, we can't support everything that KMS can
do. Major compositors will quite likely want more fine-grained control and
that won't be possible if we keep things simple. Maybe there is a perfect
balance somewhere, but I don't know what it is.

As far as my main use-cases go, I don't think the performance argument
really works. In the Android app case (what I'd like to do eventually), it
has to be out-of-band anyway in order to cross between systems. For
something like RDP/VNC, there is enough overhead anyway that I question
whether or not the context-switch will make any noticeable difference.
Post by Jason Ekstrand
2. Simple full-screen clients. With standard VTs going the way of the
dodo
Post by Jason Ekstrand
bird (see also [David Herrmann's work on logind][2]), we will need
a way
Post by Jason Ekstrand
for displaying simple full-screen programs such as splashscreens
without
Post by Jason Ekstrand
every single one of them knowing how to talk DRM/KMS directly.
David
Post by Jason Ekstrand
has proposed to use a system compositor (which he calls wlsystemc
in his
Post by Jason Ekstrand
post) so these types of programs can be written as simple wayland
clients. My github repository contains the (almost trivial)
modifications to simple-shm that make it in to one such client.
Yay, I appreciate someone picking up this idea \o/
Post by Jason Ekstrand
3. As a DRM/KMS backend for other compositors. Manually dealing with
DRM/KMS isn't actually all that many lines and all of the big
compositors (mutter, Kwin, EFL, etc.) will do it themselves.
However,
Post by Jason Ekstrand
for people who want to write their own simple compositor, it can be
a
Post by Jason Ekstrand
bit tricky to get right and raises the barrier to entry. The
protocol
Post by Jason Ekstrand
I'm proposing is sufficiently powerful to provide most of the basic
multi-output support and modesetting that is needed for a simple
compositor. This means that all a potential compositor writer has
to do
Post by Jason Ekstrand
is write a system compositor client and they can let someone else
get
Post by Jason Ekstrand
the KMS details right.
Manually dealing with DRM/KMS _is_ hard. Yes, the basic setup is easy,
but I hate the fact that we now end up with everyone doing it on their
own. Advanced things can get pretty complex, like GPU selection,
multi-GPU handling, GPU hotplugging, CRTC hotplugging, planes,
cursors, DRM-Master, DPMS, DRM properties, atomic modesetting,
render-nodes, .. ugh, this list can get soo long. I am a little bit
scared that EFL or Gnome get it wrong, but ok, not my deal.
Post by Jason Ekstrand
While it sounds like a big task, implementing a system compositor isn't
that bad. The simplest system compositor is one that can simply
display
Post by Jason Ekstrand
surfaces. In order to do that, you need to implement the following
* wl_compositor
* wl_region
* wl_shm (along with wl_shm_pool and a SHM-based wl_buffer)
* wl_surface
* wl_output
None of those are particularly difficult or complicated to implement.
The
Post by Jason Ekstrand
hardest is probably wl_surface and that's not terrible.
For input you have two options. The first, most obvious option is to
implement wl_seat and its child interfaces. Second, I have considered
the
Post by Jason Ekstrand
idea of a wl_raw_input interface (only for system compositors) that
simply
Post by Jason Ekstrand
provides evdev file descriptors to the client. This would allow for
raw
Post by Jason Ekstrand
input processing without having to worry about things like
weston-launch.
Post by Jason Ekstrand
Also the system compositor *may* be able to handle the FD muting etc.
for
Post by Jason Ekstrand
playing nice with logind. (I'm not sure on that one yet, I'd have to
ask
Post by Jason Ekstrand
David.)
One more note on input: I do NOT expect the system compositor to do any
significant input processing. Even if the child compositor is getting
its
Post by Jason Ekstrand
events through wl_seat, I expect them to be about as raw as possible.
In
Post by Jason Ekstrand
particular, this is not where things like pointer acceleration should
be
Post by Jason Ekstrand
handled. Once we get a pointer_grab interface working, I expect any
compositor that runs on top of a system compositor to attempt a pointer
grab almost immediately and do its own pointer handling from there.
Otherwise it is impossible for the client compositor to re-arrange the
outputs without additional protocol.
Along with the basics as described above, a system compositor could
optionally implement additional interfaces to provide aditional
* A RDP system compositor could implement wl_data_device to allow for
drag-and-drop and clipboard sharing between host and client.
* A system compositor could expose wl_subcompositor and use
subsurfaces to
Post by Jason Ekstrand
allow the client compositor to take advangage of hardware
compositing.
Post by Jason Ekstrand
Note that this is not as simple as it sounds because hardware
frequently
Post by Jason Ekstrand
has limits on the number, size, and placement of such overlays and
there
Post by Jason Ekstrand
is currently no way to communicate that information through the
subsurface protocol. Therefore, the system compositor could find
itself
Post by Jason Ekstrand
doing a full composite anyway.
* A wl_user_switcher interface could be created for login managers.
This
Post by Jason Ekstrand
steps on logind a bit, but someone may find it useful.
That is about all I have to say for now on the subject. If you want to
check out my current implementation you can look at my github as I said
above. As of right now, I have multi-monitor weston running inside of
my
Post by Jason Ekstrand
weston-based system compositor. Also, I have simple-shm modified to
act as
Post by Jason Ekstrand
a simple system compositor client if finds the wl_system_compositor
global.
Post by Jason Ekstrand
The only mode that works right now is "center" but I'm working on
getting
Post by Jason Ekstrand
the others to work.
I appreciate any questions or comments you may have on either the main
ideas (above) or the protocol (below).
I really like having an intermediate layer for simple tasks. Some
layer that is well maintained and allows things like plymouth to run
on top of it. However, I dislike calling it system-compositor. Let me
In a session there are several different running daemons. Each of them
provides a different service to ease device usage. This includes
pulseaudio, dbus, polkit, colord, .. and of course the
session-compositor (xserver, weston, ...). But all of these run
_inside_ the session. If properly done, they don't need any super-user
privileges. If we switch sessions (whether via logind or via VT
doesn't matter), we can simply change device-access restrictions and
the new session can start running. We handover device access from one
session to another. My work on logind doesn't change this or reinvent
it, it only tries to make it _safe_ and _reliable_.
The idea behind a system-compositor was to provide a system daemon
that runs _outside_ a session. Its sole responsibility is to control
access to graphics and input hardware. So session-compositors no
longer access hardware directly, but instead tunnel it through the
system-compositor. But this means, the system-compositor must know of
session-switches and correctly display only the session-compositor of
the active session. However, session-switching is controlled by
logind, so the system-compositor gets the session-switch notification
_after_ the session was actually switched, making this kind of racy
(but still ok!).
The bigger problem is, the system-compositor is not part of a session
so it has to be active *all the time*. You cannot have some sessions
using the system-compositor and other sessions doing it the old way.
You cannot do device-access handover from the system-compositor to a
self-hosting or legacy session. This would require ugly racy hacks and
conflict with VT!
But if the system-compositor is always active, you cannot use VTs in
text-mode. Because VTs in text-mode access graphics hardware
*directly*.
With this in mind, we ditched the idea of a system-compositor. But
that doesn't mean the idea of tunneling graphics access is wrong! In
fact, I like it a lot, but please don't call it system-compositor! A
system-compositor is what Ubuntu people are trying and RAOF just
recently made me aware that they ran in exactly the problems I just
mentioned. So please don't do that.
I Agree. I'm not really trying to create a system compositor. More of a
"put stuff on a screen somewhere" compositor. That said, it would be nice
if it could also handle whatever is needed to talk to logind. I'm not sure
how much there is though.

As far as names go, I'm open to suggestions. Here are a few that come to
mind:

* wl_fullscreen_shell
* wl_metacompositor
* wl_canvas
* wl_terminal
So back to your proposal. I'd like to see something like you did but
as a session-compositor (call it whatever you want ;)). So a session
that doesn't want to deal with DRM directly (like for instance
gdm/xdm/kdm) could avoid starting an xserver or weston and start your
session-compositor instead. It then displays it's content via the
standard wayland client APIs on this compositor. But this compositor
imho should run in a session. So it does *not* allow clients from
different sessions to connect. It is *no* system compositor. It's just
a daemon which provides graphics-access to the session. It may even
allow switching between multiple surfaces. And if you continue this
thought, you will notice that it is nothing more than weston but with
a *very* reduced wl_shell. Precisely a wl_shell that displays only one
surface at a time.
Agreed. Personally, I think multi-client is a bit over-the-top for now but
maybe in the future. I hope that it's going to be light enough that
running it as a daemon is unnecessary but we can one one instance per
client.
What would be the benefit over a library that does the job in the
compositor/single application ?
See above
So if the protocol is well-defined, we could standardize some path
(eg., /run/user/<num>/wayland-fullscreen-<sid>.socket) which is
provided by such a session-compositor. gdm could then during startup
check whether this path exists (that is, such a compositor is running
in its session) and use it to access graphics-devices. If the API
allows multiple surfaces, a separate "system-log"-process could run in
the _same_ session and use this compositor to display the current
system-log. Your compositor could react to keypresses like alt+1 or
alt+2 (or ESC) to switch between the surfaces. That is, the gdm
session could provide the system-log just one key-press away. Both in
the same session! You don't have to run a full-blown
VT/kmscon/whatever-log for that on another session on VT12..
Yeah, not having to burn VT's for things like logs would be nice. I'm not
sure what I think of leaving a standardized socket open. For a lot of
cases, I think I prefer either the fullscreen compositor launch the other
application (so "wlvnc --options -- gnome") or the primary compositor (i.e.
mutter) launch the fullscreen compositor, hand it the connection as a env
var and start drawing on it. This would allow a fullscreen compositor to
run as a sort of plugin to the bigger compositor if it wants to handle EGL
itself but mirror to VNC or something like that.
Post by Jason Ekstrand
-----------------
<protocol name="system_compositor">
<interface name="wl_system_compositor" version="1">
<description summary="Displays a single surface per output">
Displays a single surface per output.
This interface can only be bound to by one client at a time.
</description>
<enum name="fullscreen_method">
<description summary="different method to set the surface
fullscreen">
Post by Jason Ekstrand
Hints to indicate to the compositor how to deal with a conflict
between the dimensions of the surface and the dimensions of the
output. The compositor is free to ignore this parameter.
</description>
<entry name="default" value="0" summary="no preference, apply
default policy"/>
Post by Jason Ekstrand
<entry name="scale" value="1" summary="scale, preserve the
surface's aspect ratio and center on output"/>
Post by Jason Ekstrand
<entry name="driver" value="2" summary="switch output mode to
the smallest mode that can fit the surface, add black borders to compensate
size mismatch"/>
Post by Jason Ekstrand
<entry name="fill" value="3" summary="no upscaling, center on
output and add black borders to compensate size mismatch"/>
Post by Jason Ekstrand
</enum>
<request name="present_surface">
<description summary="present surface for display">
This requests the system compositor to display surface on
output.
Post by Jason Ekstrand
Each client of the system compositor can have at most one
surface
Post by Jason Ekstrand
per output at any one time. Subsequent requests with the same
output replace the surface bound to that output. The same
surface
Post by Jason Ekstrand
may be presented on multiple outputs.
If the output is null, the compositor will present the surface
on
Post by Jason Ekstrand
whatever display (or displays) it thinks best. In particular,
this
Post by Jason Ekstrand
may replace any or all surfaces currently presented so it
should
Post by Jason Ekstrand
not be used in combination with placing surfaces on specific
outputs.
The method specifies how the surface is to be persented. These
methods are identical to those in
wl_shell_surface.set_fullscreen.
It should be noted here that, as with wl_shell_surface.set_fullscreen, the
fullscreen compositor is more than welcome to ignore this argument and do
something else it feels to be sensible. For instance, if displaying on
something with a constant screen size (in pixels) the "driver" mode may
mean scale as far as you can by an integer multiple and add black borders.
Post by Jason Ekstrand
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="method" type="uint"/>
<arg name="framerate" type="uint"/>
<arg name="output" type="object" interface="wl_output"
allow-null="true"/>
Post by Jason Ekstrand
</request>
</interface>
</protocol>
Yepp, that's all we need. Just rename it from "system_compositor" to
"wl_fullscreen_shell" (I bet you can come up with some fancier name).
No other criticism on this proposal from my side.
Thanks for looking over it!

As one other note. I'm not sure if I will really be able to write/maintain
a fullscreen compositor solution. My knowledge of KMS is lacking (I'm a
quick study but it still takes studying) and I don't really have the time
to commit to maintaining it. That said, I am in the process of building a
weston shell that provides this functionality and that should do at least
for now. This should allow other compositors to take advantage of weston
backends without using weston's scenegraph.

Thanks for all the comments,
--Jason Ekstrand
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20130826/b50829ac/attachment-0001.html>
microcai
2013-08-27 19:16:21 UTC
Permalink
Post by David Herrmann
Hi
Post by Jason Ekstrand
Hello All,
I am in the process of picking back up the old idea of system compositors.
I am not, at the moment, looking for a review of the code; simply a review
of the concept and the proposed protocol. If you would like to look at my
implementation or try it out, it can be found in the system-compositor
branch of my personal [weston fork on github][1].
What follows is what I envision for system compositors. (Others may have a
different idea which is why I'm writing this RFC email.) The basic idea
behind a system compositor is to provide an interface for compositors whose
only job it is to display other compositors or other stand-alone
full-screen interfaces. I image three primary purposes for system
1. As an abstraction layer. Every time someone wants to write a RDP
server, VNC server, android backend, or the like the standard answer is
"write it as a weston plugin". The problem with this is that, to my
knowledge, none of the major desktop environments (GNOME, KDE, EFL,
etc.) plan to run their compositor as a weston shell plugin. This makes
a weston plugin a poor solution in the long term. On the other hand, a
system compositor is fairly simple to implement and provides a backend
to any compositor that can run on top of a system compositor.
KDE planned on using weston as underlying compositor. But I doubt
GNOME or EFL want to use something like that..
Post by Jason Ekstrand
2. Simple full-screen clients. With standard VTs going the way of the dodo
bird (see also [David Herrmann's work on logind][2]), we will need a way
for displaying simple full-screen programs such as splashscreens without
every single one of them knowing how to talk DRM/KMS directly. David
has proposed to use a system compositor (which he calls wlsystemc in his
post) so these types of programs can be written as simple wayland
clients. My github repository contains the (almost trivial)
modifications to simple-shm that make it in to one such client.
Yay, I appreciate someone picking up this idea \o/
Post by Jason Ekstrand
3. As a DRM/KMS backend for other compositors. Manually dealing with
DRM/KMS isn't actually all that many lines and all of the big
compositors (mutter, Kwin, EFL, etc.) will do it themselves. However,
for people who want to write their own simple compositor, it can be a
bit tricky to get right and raises the barrier to entry. The protocol
I'm proposing is sufficiently powerful to provide most of the basic
multi-output support and modesetting that is needed for a simple
compositor. This means that all a potential compositor writer has to do
is write a system compositor client and they can let someone else get
the KMS details right.
Manually dealing with DRM/KMS _is_ hard. Yes, the basic setup is easy,
but I hate the fact that we now end up with everyone doing it on their
own. Advanced things can get pretty complex, like GPU selection,
multi-GPU handling, GPU hotplugging, CRTC hotplugging, planes,
cursors, DRM-Master, DPMS, DRM properties, atomic modesetting,
render-nodes, .. ugh, this list can get soo long. I am a little bit
scared that EFL or Gnome get it wrong, but ok, not my deal.
Post by Jason Ekstrand
While it sounds like a big task, implementing a system compositor isn't
that bad. The simplest system compositor is one that can simply display
surfaces. In order to do that, you need to implement the following
* wl_compositor
* wl_region
* wl_shm (along with wl_shm_pool and a SHM-based wl_buffer)
* wl_surface
* wl_output
None of those are particularly difficult or complicated to implement. The
hardest is probably wl_surface and that's not terrible.
For input you have two options. The first, most obvious option is to
implement wl_seat and its child interfaces. Second, I have considered the
idea of a wl_raw_input interface (only for system compositors) that simply
provides evdev file descriptors to the client. This would allow for raw
input processing without having to worry about things like weston-launch.
Also the system compositor *may* be able to handle the FD muting etc. for
playing nice with logind. (I'm not sure on that one yet, I'd have to ask
David.)
One more note on input: I do NOT expect the system compositor to do any
significant input processing. Even if the child compositor is getting its
events through wl_seat, I expect them to be about as raw as possible. In
particular, this is not where things like pointer acceleration should be
handled. Once we get a pointer_grab interface working, I expect any
compositor that runs on top of a system compositor to attempt a pointer
grab almost immediately and do its own pointer handling from there.
Otherwise it is impossible for the client compositor to re-arrange the
outputs without additional protocol.
Along with the basics as described above, a system compositor could
optionally implement additional interfaces to provide aditional
* A RDP system compositor could implement wl_data_device to allow for
drag-and-drop and clipboard sharing between host and client.
* A system compositor could expose wl_subcompositor and use subsurfaces to
allow the client compositor to take advangage of hardware compositing.
Note that this is not as simple as it sounds because hardware frequently
has limits on the number, size, and placement of such overlays and there
is currently no way to communicate that information through the
subsurface protocol. Therefore, the system compositor could find itself
doing a full composite anyway.
* A wl_user_switcher interface could be created for login managers. This
steps on logind a bit, but someone may find it useful.
That is about all I have to say for now on the subject. If you want to
check out my current implementation you can look at my github as I said
above. As of right now, I have multi-monitor weston running inside of my
weston-based system compositor. Also, I have simple-shm modified to act as
a simple system compositor client if finds the wl_system_compositor global.
The only mode that works right now is "center" but I'm working on getting
the others to work.
I appreciate any questions or comments you may have on either the main
ideas (above) or the protocol (below).
I really like having an intermediate layer for simple tasks. Some
layer that is well maintained and allows things like plymouth to run
on top of it. However, I dislike calling it system-compositor. Let me
In a session there are several different running daemons. Each of them
provides a different service to ease device usage. This includes
pulseaudio, dbus, polkit, colord, .. and of course the
session-compositor (xserver, weston, ...). But all of these run
_inside_ the session. If properly done, they don't need any super-user
privileges. If we switch sessions (whether via logind or via VT
doesn't matter), we can simply change device-access restrictions and
the new session can start running. We handover device access from one
session to another. My work on logind doesn't change this or reinvent
it, it only tries to make it _safe_ and _reliable_.
The idea behind a system-compositor was to provide a system daemon
that runs _outside_ a session. Its sole responsibility is to control
access to graphics and input hardware. So session-compositors no
longer access hardware directly, but instead tunnel it through the
system-compositor. But this means, the system-compositor must know of
session-switches and correctly display only the session-compositor of
the active session. However, session-switching is controlled by
logind, so the system-compositor gets the session-switch notification
_after_ the session was actually switched, making this kind of racy
(but still ok!).
when the user wants to switch, logind should be notified by system-compositor.
system-compositer controls the screen and the input, not logind, so
there should be no race.
Post by David Herrmann
The bigger problem is, the system-compositor is not part of a session
so it has to be active *all the time*. You cannot have some sessions
using the system-compositor and other sessions doing it the old way.
You cannot do device-access handover from the system-compositor to a
self-hosting or legacy session. This would require ugly racy hacks and
conflict with VT!
But if the system-compositor is always active, you cannot use VTs in
text-mode. Because VTs in text-mode access graphics hardware
*directly*.
if we want to kill VT, then better we have system-compositor. I see no reason
to support kernel VTs when you could have system-compositor.

system-compositor is not always active. In fact, it only got wake up when you
do session switch. the session compositor directly render to the screen. there
is no need to wake up system-compositor here.

sessions that does not use system-compositor is a dead end.
All sessions should and must output to system-compositor.
system-compositor should be socket activated, and guaranteed to be there.
Post by David Herrmann
With this in mind, we ditched the idea of a system-compositor. But
that doesn't mean the idea of tunneling graphics access is wrong! In
fact, I like it a lot, but please don't call it system-compositor! A
system-compositor is what Ubuntu people are trying and RAOF just
recently made me aware that they ran in exactly the problems I just
mentioned. So please don't do that.
So back to your proposal. I'd like to see something like you did but
as a session-compositor (call it whatever you want ;)). So a session
that doesn't want to deal with DRM directly (like for instance
gdm/xdm/kdm) could avoid starting an xserver or weston and start your
session-compositor instead. It then displays it's content via the
standard wayland client APIs on this compositor. But this compositor
imho should run in a session. So it does *not* allow clients from
different sessions to connect. It is *no* system compositor. It's just
a daemon which provides graphics-access to the session. It may even
allow switching between multiple surfaces. And if you continue this
thought, you will notice that it is nothing more than weston but with
a *very* reduced wl_shell. Precisely a wl_shell that displays only one
surface at a time.
So if the protocol is well-defined, we could standardize some path
(eg., /run/user/<num>/wayland-fullscreen-<sid>.socket) which is
provided by such a session-compositor. gdm could then during startup
check whether this path exists (that is, such a compositor is running
in its session) and use it to access graphics-devices. If the API
allows multiple surfaces, a separate "system-log"-process could run in
the _same_ session and use this compositor to display the current
system-log. Your compositor could react to keypresses like alt+1 or
alt+2 (or ESC) to switch between the surfaces. That is, the gdm
session could provide the system-log just one key-press away. Both in
the same session! You don't have to run a full-blown
VT/kmscon/whatever-log for that on another session on VT12..
Post by Jason Ekstrand
-----------------
<protocol name="system_compositor">
<interface name="wl_system_compositor" version="1">
<description summary="Displays a single surface per output">
Displays a single surface per output.
This interface can only be bound to by one client at a time.
</description>
<enum name="fullscreen_method">
<description summary="different method to set the surface fullscreen">
Hints to indicate to the compositor how to deal with a conflict
between the dimensions of the surface and the dimensions of the
output. The compositor is free to ignore this parameter.
</description>
<entry name="default" value="0" summary="no preference, apply default policy"/>
<entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/>
<entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/>
<entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
</enum>
<request name="present_surface">
<description summary="present surface for display">
This requests the system compositor to display surface on output.
Each client of the system compositor can have at most one surface
per output at any one time. Subsequent requests with the same
output replace the surface bound to that output. The same surface
may be presented on multiple outputs.
If the output is null, the compositor will present the surface on
whatever display (or displays) it thinks best. In particular, this
may replace any or all surfaces currently presented so it should
not be used in combination with placing surfaces on specific
outputs.
The method specifies how the surface is to be persented. These
methods are identical to those in wl_shell_surface.set_fullscreen.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="method" type="uint"/>
<arg name="framerate" type="uint"/>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>
</interface>
</protocol>
Yepp, that's all we need. Just rename it from "system_compositor" to
"wl_fullscreen_shell" (I bet you can come up with some fancier name).
No other criticism on this proposal from my side.
Feel free to disagree ;) I am open for suggestions or criticism.
Cheers
David
with system-compositor, we can do cross-session visual effects
that's hard to be done without a system-compositor.

with system-compositor, we provide unified input handing,
multi-GPU handing, multi-monitor handing, and integrate that well with logind.

with system-compositor, we killed kernel VTs. we can still provide
text terminal as clients of system-compositor.

with system-compositor, we secured our GPUs.

with system-compositor, we can make system-compositor to load old Xorg drivers
to bring up OGL and do user-mode setting while native KMS drivers absent.
David Herrmann
2013-08-27 19:48:11 UTC
Permalink
Hi
[...]
Post by microcai
Post by David Herrmann
The idea behind a system-compositor was to provide a system daemon
that runs _outside_ a session. Its sole responsibility is to control
access to graphics and input hardware. So session-compositors no
longer access hardware directly, but instead tunnel it through the
system-compositor. But this means, the system-compositor must know of
session-switches and correctly display only the session-compositor of
the active session. However, session-switching is controlled by
logind, so the system-compositor gets the session-switch notification
_after_ the session was actually switched, making this kind of racy
(but still ok!).
when the user wants to switch, logind should be notified by system-compositor.
system-compositer controls the screen and the input, not logind, so
there should be no race.
Yeah, this is *not* how it works. Currently a session-switch is
controlled by either the kernel (for VTs) or by logind. I don't see
any reason why this should change. Please explain yourself if you
disagree.
Post by microcai
Post by David Herrmann
The bigger problem is, the system-compositor is not part of a session
so it has to be active *all the time*. You cannot have some sessions
using the system-compositor and other sessions doing it the old way.
You cannot do device-access handover from the system-compositor to a
self-hosting or legacy session. This would require ugly racy hacks and
conflict with VT!
But if the system-compositor is always active, you cannot use VTs in
text-mode. Because VTs in text-mode access graphics hardware
*directly*.
if we want to kill VT, then better we have system-compositor. I see no reason
to support kernel VTs when you could have system-compositor.
I don't see any reason to support VTs at all. But it's not me to
decide, so we will always support VTs for backwards compatibility.
Post by microcai
system-compositor is not always active. In fact, it only got wake up when you
do session switch. the session compositor directly render to the screen. there
is no need to wake up system-compositor here.
In this scenario, how does the system-compositor know whether the
session that you switch to renders directly or requires the
system-compositor?
Post by microcai
sessions that does not use system-compositor is a dead end.
All sessions should and must output to system-compositor.
system-compositor should be socket activated, and guaranteed to be there.
Please elaborate. You are just claiming stuff without explaining why..
Or is this just your opinion?

[...]
Post by microcai
Post by David Herrmann
Yepp, that's all we need. Just rename it from "system_compositor" to
"wl_fullscreen_shell" (I bet you can come up with some fancier name).
No other criticism on this proposal from my side.
Feel free to disagree ;) I am open for suggestions or criticism.
Cheers
David
with system-compositor, we can do cross-session visual effects
that's hard to be done without a system-compositor.
And "hard to be done" is bad?
Choosing the convenient way here means adding latency (by routing
everything through the system-compositor). We don't want that.
And "cross-session visual effects" are still possible. I will present
that at XDC in 1 month.
Post by microcai
with system-compositor, we provide unified input handing,
multi-GPU handing, multi-monitor handing, and integrate that well with logind.
Please show to me how this integrates well with logind?

"Multi-GPU", "multi-monitor", "unified input",.. that has nothing to
do with a system-compositor. You can have that with
session-compositors, too. In fact, we already have all that..
Post by microcai
with system-compositor, we killed kernel VTs. we can still provide
text terminal as clients of system-compositor.
Has nothing to do with system-compositors..
Post by microcai
with system-compositor, we secured our GPUs.
What? In your claim above you said system-compositors *don't* always
have to be active. How do you protect your GPU during such switches?
Post by microcai
with system-compositor, we can make system-compositor to load old Xorg drivers
to bring up OGL and do user-mode setting while native KMS drivers absent.
Again, this has nothing to do with system-compositors. You can
implement that in any compositor.

Regards
David
microcai
2013-08-28 18:07:21 UTC
Permalink
Post by David Herrmann
Hi
[...]
Post by microcai
Post by David Herrmann
The idea behind a system-compositor was to provide a system daemon
that runs _outside_ a session. Its sole responsibility is to control
access to graphics and input hardware. So session-compositors no
longer access hardware directly, but instead tunnel it through the
system-compositor. But this means, the system-compositor must know of
session-switches and correctly display only the session-compositor of
the active session. However, session-switching is controlled by
logind, so the system-compositor gets the session-switch notification
_after_ the session was actually switched, making this kind of racy
(but still ok!).
when the user wants to switch, logind should be notified by system-compositor.
system-compositer controls the screen and the input, not logind, so
there should be no race.
Yeah, this is *not* how it works. Currently a session-switch is
controlled by either the kernel (for VTs) or by logind. I don't see
any reason why this should change. Please explain yourself if you
disagree.
system-compositor decide to do session-switch, just as today Xorg
decide to do VT switch.

kernel should not be involved here. when system-compositor decide to
do session-switch, it notifies logind.
Post by David Herrmann
Post by microcai
Post by David Herrmann
The bigger problem is, the system-compositor is not part of a session
so it has to be active *all the time*. You cannot have some sessions
using the system-compositor and other sessions doing it the old way.
You cannot do device-access handover from the system-compositor to a
self-hosting or legacy session. This would require ugly racy hacks and
conflict with VT!
But if the system-compositor is always active, you cannot use VTs in
text-mode. Because VTs in text-mode access graphics hardware
*directly*.
if we want to kill VT, then better we have system-compositor. I see no reason
to support kernel VTs when you could have system-compositor.
I don't see any reason to support VTs at all. But it's not me to
decide, so we will always support VTs for backwards compatibility.
system-compositor can still support VTs for backwards compatibility.
But disabled by default. or disabled at all.
Post by David Herrmann
Post by microcai
system-compositor is not always active. In fact, it only got wake up when you
do session switch. the session compositor directly render to the screen. there
is no need to wake up system-compositor here.
In this scenario, how does the system-compositor know whether the
session that you switch to renders directly or requires the
system-compositor?
Post by microcai
sessions that does not use system-compositor is a dead end.
All sessions should and must output to system-compositor.
system-compositor should be socket activated, and guaranteed to be there.
Please elaborate. You are just claiming stuff without explaining why..
Or is this just your opinion?
[...]
Post by microcai
Post by David Herrmann
Yepp, that's all we need. Just rename it from "system_compositor" to
"wl_fullscreen_shell" (I bet you can come up with some fancier name).
No other criticism on this proposal from my side.
Feel free to disagree ;) I am open for suggestions or criticism.
Cheers
David
with system-compositor, we can do cross-session visual effects
that's hard to be done without a system-compositor.
And "hard to be done" is bad?
Choosing the convenient way here means adding latency (by routing
everything through the system-compositor). We don't want that.
And "cross-session visual effects" are still possible. I will present
that at XDC in 1 month.
Post by microcai
with system-compositor, we provide unified input handing,
multi-GPU handing, multi-monitor handing, and integrate that well with logind.
Please show to me how this integrates well with logind?
"Multi-GPU", "multi-monitor", "unified input",.. that has nothing to
do with a system-compositor. You can have that with
session-compositors, too. In fact, we already have all that..
Post by microcai
with system-compositor, we killed kernel VTs. we can still provide
text terminal as clients of system-compositor.
Has nothing to do with system-compositors..
Post by microcai
with system-compositor, we secured our GPUs.
What? In your claim above you said system-compositors *don't* always
have to be active. How do you protect your GPU during such switches?
The process is there, but wait stage, not consuming any CPU time. When
the user wants session-switch,
the session-compositor grabs the key press, then notifies
system-compositor. Only by that time, this process is wake.
Post by David Herrmann
Post by microcai
with system-compositor, we can make system-compositor to load old Xorg drivers
to bring up OGL and do user-mode setting while native KMS drivers absent.
Again, this has nothing to do with system-compositors. You can
implement that in any compositor.
Standard is a good thing.
Post by David Herrmann
Regards
David
Tristan Schmelcher
2013-09-10 20:30:59 UTC
Permalink
I'm not qualified to comment on the protocol, but I would definitely
like to see a standard for Wayland system compositors. I am going to be
porting a pixel orbiter to the Wayland stack (original code at
https://github.com/TristanSchmelcher/pixelorbiter) and the only secure
way to design it is as a plugin in a system compositor running as a
privileged user.
Jason Ekstrand
2013-10-23 01:48:24 UTC
Permalink
This is a second edition RFC for a fullscreen shell protocol. The first
version (along with my intentions for the protocol) can be found here:

http://lists.freedesktop.org/archives/wayland-devel/2013-August/010720.html

Since there wasn't a whole lot of dissent in the previous email, I will not
repeat it all here. Mainly, people didn't like the name wl_system_compositor
because they don't want system compositors. I have since changed this to
wl_fullscreen_shell (which is more descriptive of what it is anyway).

This patch series contains the protocol, an implementation of the
wl_fullscreen_shell as a Weston shell plugin, and modifications to
simple-shm to make it act like a simple fullscreen shell client.

Missing from this patch set (and the primary reason it is an RFC) is
patches to thw wayland backend to support wl_fullscreen_shell. I am
currently revamping the wayland backend. Once I get this to a more
reasonable state, I'll add the wl_fullscreen_shell support.

Jason Ekstrand (5):
Add a fullscreen shell protocol
Generate/build the fullscreen shell protocol files
Add a signal for when a seat updates its capabilities
Add a wl_fullscreen_shell implementation
simple-shm: Add fullscreen shell support

clients/.gitignore | 2 +
clients/Makefile.am | 4 +
clients/simple-shm.c | 32 ++-
configure.ac | 8 +
protocol/Makefile.am | 1 +
protocol/fullscreen-shell.xml | 44 ++++
src/.gitignore | 3 +
src/Makefile.am | 17 ++
src/compositor.h | 1 +
src/fullscreen-shell.c | 574 ++++++++++++++++++++++++++++++++++++++++++
src/input.c | 2 +
11 files changed, 681 insertions(+), 7 deletions(-)
create mode 100644 protocol/fullscreen-shell.xml
create mode 100644 src/fullscreen-shell.c
--
1.8.3.1
Jason Ekstrand
2013-10-23 01:48:25 UTC
Permalink
---
protocol/fullscreen-shell.xml | 44 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 protocol/fullscreen-shell.xml

diff --git a/protocol/fullscreen-shell.xml b/protocol/fullscreen-shell.xml
new file mode 100644
index 0000000..b696828
--- /dev/null
+++ b/protocol/fullscreen-shell.xml
@@ -0,0 +1,44 @@
+<protocol name="fullscreen_shell">
+ <interface name="wl_fullscreen_shell" version="1">
+ <description summary="Displays a single surface per output">
+ Displays a single surface per output.
+
+ This interface can only be bound to by one client at a time.
+ </description>
+
+ <enum name="fullscreen_method">
+ <description summary="different method to set the surface fullscreen">
+ Hints to indicate to the compositor how to deal with a conflict
+ between the dimensions of the surface and the dimensions of the
+ output. The compositor is free to ignore this parameter.
+ </description>
+ <entry name="default" value="0" summary="no preference, apply default policy"/>
+ <entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/>
+ <entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/>
+ <entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
+ </enum>
+
+ <request name="present_surface">
+ <description summary="present surface for display">
+ This requests the system compositor to display surface on output.
+ Each client of the system compositor can have at most one surface
+ per output at any one time. Subsequent requests with the same
+ output replace the surface bound to that output. The same surface
+ may be presented on multiple outputs.
+
+ If the output is null, the compositor will present the surface on
+ whatever display (or displays) it thinks best. In particular, this
+ may replace any or all surfaces currently presented so it should
+ not be used in combination with placing surfaces on specific
+ outputs.
+
+ The method specifies how the surface is to be persented. These
+ methods are identical to those in wl_shell_surface.set_fullscreen.
+ </description>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ </request>
+ </interface>
+</protocol>
--
1.8.3.1
Jonas Ådahl
2013-10-23 20:56:15 UTC
Permalink
Hi,

Using this protocol, how would the fullscreen shell client turn on and
off outputs? I can see how clone, next-to and modeset by controlling
what surface is presented and what fullscreen method is used, but that
is not enough for turning an output off, isn't it?

Another question is synchronising. Would a client ever want to change
anything atomically? Do we need something like wl_surface.commit?

Also, one wording comment below.

Thanks

Jonas
Post by Jason Ekstrand
---
protocol/fullscreen-shell.xml | 44 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 protocol/fullscreen-shell.xml
diff --git a/protocol/fullscreen-shell.xml b/protocol/fullscreen-shell.xml
new file mode 100644
index 0000000..b696828
--- /dev/null
+++ b/protocol/fullscreen-shell.xml
@@ -0,0 +1,44 @@
+<protocol name="fullscreen_shell">
+ <interface name="wl_fullscreen_shell" version="1">
+ <description summary="Displays a single surface per output">
+ Displays a single surface per output.
+
+ This interface can only be bound to by one client at a time.
+ </description>
+
+ <enum name="fullscreen_method">
+ <description summary="different method to set the surface fullscreen">
+ Hints to indicate to the compositor how to deal with a conflict
+ between the dimensions of the surface and the dimensions of the
+ output. The compositor is free to ignore this parameter.
+ </description>
+ <entry name="default" value="0" summary="no preference, apply default policy"/>
+ <entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/>
+ <entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/>
+ <entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
+ </enum>
+
+ <request name="present_surface">
+ <description summary="present surface for display">
+ This requests the system compositor to display surface on output.
+ Each client of the system compositor can have at most one surface
You still use the term 'system compositor' here. Also, it should be
"display a surface" instead of "display surface".
Post by Jason Ekstrand
+ per output at any one time. Subsequent requests with the same
+ output replace the surface bound to that output. The same surface
+ may be presented on multiple outputs.
+
+ If the output is null, the compositor will present the surface on
+ whatever display (or displays) it thinks best. In particular, this
+ may replace any or all surfaces currently presented so it should
+ not be used in combination with placing surfaces on specific
+ outputs.
+
+ The method specifies how the surface is to be persented. These
+ methods are identical to those in wl_shell_surface.set_fullscreen.
+ </description>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ </request>
+ </interface>
+</protocol>
--
1.8.3.1
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Jason Ekstrand
2013-10-23 23:08:29 UTC
Permalink
Jonas,
Thanks for the review!
Post by Jonas Ådahl
Hi,
Using this protocol, how would the fullscreen shell client turn on and
off outputs? I can see how clone, next-to and modeset by controlling
what surface is presented and what fullscreen method is used, but that
is not enough for turning an output off, isn't it?
I think that would be done by simply calling present_surface with a null
surface to remove the surface from the output. I'm not 100% sure how this
will interact with KMS surface detection, but hopefully we should be able
to make it that simple.
Post by Jonas Ådahl
Another question is synchronising. Would a client ever want to change
anything atomically? Do we need something like wl_surface.commit?
I'm not sure what would get changed atomically. There's only one operation
and different outputs will probably have different refresh rates so changes
won't be atomic anyway. Or are you thinking about trying to future-proof
stuff?
Post by Jonas Ådahl
Also, one wording comment below.
Thanks
Jonas
Post by Jason Ekstrand
---
protocol/fullscreen-shell.xml | 44
+++++++++++++++++++++++++++++++++++++++++++
Post by Jason Ekstrand
1 file changed, 44 insertions(+)
create mode 100644 protocol/fullscreen-shell.xml
diff --git a/protocol/fullscreen-shell.xml
b/protocol/fullscreen-shell.xml
Post by Jason Ekstrand
new file mode 100644
index 0000000..b696828
--- /dev/null
+++ b/protocol/fullscreen-shell.xml
@@ -0,0 +1,44 @@
+<protocol name="fullscreen_shell">
+ <interface name="wl_fullscreen_shell" version="1">
+ <description summary="Displays a single surface per output">
+ Displays a single surface per output.
+
+ This interface can only be bound to by one client at a time.
+ </description>
+
+ <enum name="fullscreen_method">
+ <description summary="different method to set the surface
fullscreen">
Post by Jason Ekstrand
+ Hints to indicate to the compositor how to deal with a conflict
+ between the dimensions of the surface and the dimensions of the
+ output. The compositor is free to ignore this parameter.
+ </description>
+ <entry name="default" value="0" summary="no preference, apply
default policy"/>
Post by Jason Ekstrand
+ <entry name="scale" value="1" summary="scale, preserve the
surface's aspect ratio and center on output"/>
Post by Jason Ekstrand
+ <entry name="driver" value="2" summary="switch output mode to the
smallest mode that can fit the surface, add black borders to compensate
size mismatch"/>
Post by Jason Ekstrand
+ <entry name="fill" value="3" summary="no upscaling, center on
output and add black borders to compensate size mismatch"/>
Post by Jason Ekstrand
+ </enum>
+
+ <request name="present_surface">
+ <description summary="present surface for display">
+ This requests the system compositor to display surface on output.
+ Each client of the system compositor can have at most one surface
You still use the term 'system compositor' here. Also, it should be
"display a surface" instead of "display surface".
Thanks. Good catch. I've fixed it locally.
Post by Jonas Ådahl
Post by Jason Ekstrand
+ per output at any one time. Subsequent requests with the same
+ output replace the surface bound to that output. The same surface
+ may be presented on multiple outputs.
+
+ If the output is null, the compositor will present the surface on
+ whatever display (or displays) it thinks best. In particular, this
+ may replace any or all surfaces currently presented so it should
+ not be used in combination with placing surfaces on specific
+ outputs.
+
+ The method specifies how the surface is to be persented. These
+ methods are identical to those in wl_shell_surface.set_fullscreen.
+ </description>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output"
allow-null="true"/>
Post by Jason Ekstrand
+ </request>
+ </interface>
+</protocol>
--
1.8.3.1
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131023/b323e040/attachment.html>
Jonas Ådahl
2013-10-24 17:33:51 UTC
Permalink
Post by Jason Ekstrand
Jonas,
Thanks for the review!
Post by Jonas Ådahl
Hi,
Using this protocol, how would the fullscreen shell client turn on and
off outputs? I can see how clone, next-to and modeset by controlling
what surface is presented and what fullscreen method is used, but that
is not enough for turning an output off, isn't it?
I think that would be done by simply calling present_surface with a null
surface to remove the surface from the output. I'm not 100% sure how this
will interact with KMS surface detection, but hopefully we should be able
to make it that simple.
I guess this could be added to the protocol clarifing what presenting a
null-surface means disabling the output. What "disabling" means, could
be up to the backend.
Post by Jason Ekstrand
Post by Jonas Ådahl
Another question is synchronising. Would a client ever want to change
anything atomically? Do we need something like wl_surface.commit?
I'm not sure what would get changed atomically. There's only one operation
and different outputs will probably have different refresh rates so changes
won't be atomic anyway. Or are you thinking about trying to future-proof
stuff?
Well, yea, atomically is probably not the correct term, and I don't know
if the KMS backend support any such functionality. What I imagine is one
might want to, for example, disable one output and enable another with
minimal time in between, or maybe avoid ending up with no output enabled
if the client would crash between calls. Might be overkill though, and
if there is no real world use case right now, maybe even more so.

Jonas
Post by Jason Ekstrand
Post by Jonas Ådahl
Also, one wording comment below.
Thanks
Jonas
Post by Jason Ekstrand
---
protocol/fullscreen-shell.xml | 44
+++++++++++++++++++++++++++++++++++++++++++
Post by Jason Ekstrand
1 file changed, 44 insertions(+)
create mode 100644 protocol/fullscreen-shell.xml
diff --git a/protocol/fullscreen-shell.xml
b/protocol/fullscreen-shell.xml
Post by Jason Ekstrand
new file mode 100644
index 0000000..b696828
--- /dev/null
+++ b/protocol/fullscreen-shell.xml
@@ -0,0 +1,44 @@
+<protocol name="fullscreen_shell">
+ <interface name="wl_fullscreen_shell" version="1">
+ <description summary="Displays a single surface per output">
+ Displays a single surface per output.
+
+ This interface can only be bound to by one client at a time.
+ </description>
+
+ <enum name="fullscreen_method">
+ <description summary="different method to set the surface
fullscreen">
Post by Jason Ekstrand
+ Hints to indicate to the compositor how to deal with a conflict
+ between the dimensions of the surface and the dimensions of the
+ output. The compositor is free to ignore this parameter.
+ </description>
+ <entry name="default" value="0" summary="no preference, apply
default policy"/>
Post by Jason Ekstrand
+ <entry name="scale" value="1" summary="scale, preserve the
surface's aspect ratio and center on output"/>
Post by Jason Ekstrand
+ <entry name="driver" value="2" summary="switch output mode to the
smallest mode that can fit the surface, add black borders to compensate
size mismatch"/>
Post by Jason Ekstrand
+ <entry name="fill" value="3" summary="no upscaling, center on
output and add black borders to compensate size mismatch"/>
Post by Jason Ekstrand
+ </enum>
+
+ <request name="present_surface">
+ <description summary="present surface for display">
+ This requests the system compositor to display surface on output.
+ Each client of the system compositor can have at most one surface
You still use the term 'system compositor' here. Also, it should be
"display a surface" instead of "display surface".
Thanks. Good catch. I've fixed it locally.
Post by Jonas Ådahl
Post by Jason Ekstrand
+ per output at any one time. Subsequent requests with the same
+ output replace the surface bound to that output. The same surface
+ may be presented on multiple outputs.
+
+ If the output is null, the compositor will present the surface on
+ whatever display (or displays) it thinks best. In particular, this
+ may replace any or all surfaces currently presented so it should
+ not be used in combination with placing surfaces on specific
+ outputs.
+
+ The method specifies how the surface is to be persented. These
+ methods are identical to those in wl_shell_surface.set_fullscreen.
+ </description>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output"
allow-null="true"/>
Post by Jason Ekstrand
+ </request>
+ </interface>
+</protocol>
--
1.8.3.1
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Jason Ekstrand
2013-10-25 00:43:21 UTC
Permalink
Post by Jonas Ådahl
Post by Jason Ekstrand
Jonas,
Thanks for the review!
Post by Jonas Ådahl
Hi,
Using this protocol, how would the fullscreen shell client turn on and
off outputs? I can see how clone, next-to and modeset by controlling
what surface is presented and what fullscreen method is used, but that
is not enough for turning an output off, isn't it?
I think that would be done by simply calling present_surface with a null
surface to remove the surface from the output. I'm not 100% sure how
this
Post by Jason Ekstrand
will interact with KMS surface detection, but hopefully we should be able
to make it that simple.
I guess this could be added to the protocol clarifing what presenting a
null-surface means disabling the output. What "disabling" means, could
be up to the backend.
Yeah, I can make that more clear. I'll send another draft here with things
stated better.
Post by Jonas Ådahl
Post by Jason Ekstrand
Post by Jonas Ådahl
Another question is synchronising. Would a client ever want to change
anything atomically? Do we need something like wl_surface.commit?
I'm not sure what would get changed atomically. There's only one
operation
Post by Jason Ekstrand
and different outputs will probably have different refresh rates so
changes
Post by Jason Ekstrand
won't be atomic anyway. Or are you thinking about trying to future-proof
stuff?
Well, yea, atomically is probably not the correct term, and I don't know
if the KMS backend support any such functionality. What I imagine is one
might want to, for example, disable one output and enable another with
minimal time in between, or maybe avoid ending up with no output enabled
if the client would crash between calls. Might be overkill though, and
if there is no real world use case right now, maybe even more so.
I think I would tend to say that this usually isn't really practical. For
KMS, for instance, switching stuff around may make monitors turn on and
there's no way to make that atomic. If the client is worried about being
on no outputs whatsoever, it can just set the one before removing the
other. Then it will get the surface.enter before the surface.leave.
Post by Jonas Ådahl
Jonas
Post by Jason Ekstrand
Post by Jonas Ådahl
Also, one wording comment below.
Thanks
Jonas
Post by Jason Ekstrand
---
protocol/fullscreen-shell.xml | 44
+++++++++++++++++++++++++++++++++++++++++++
Post by Jason Ekstrand
1 file changed, 44 insertions(+)
create mode 100644 protocol/fullscreen-shell.xml
diff --git a/protocol/fullscreen-shell.xml
b/protocol/fullscreen-shell.xml
Post by Jason Ekstrand
new file mode 100644
index 0000000..b696828
--- /dev/null
+++ b/protocol/fullscreen-shell.xml
@@ -0,0 +1,44 @@
+<protocol name="fullscreen_shell">
+ <interface name="wl_fullscreen_shell" version="1">
+ <description summary="Displays a single surface per output">
+ Displays a single surface per output.
+
+ This interface can only be bound to by one client at a time.
+ </description>
+
+ <enum name="fullscreen_method">
+ <description summary="different method to set the surface
fullscreen">
Post by Jason Ekstrand
+ Hints to indicate to the compositor how to deal with a conflict
+ between the dimensions of the surface and the dimensions of the
+ output. The compositor is free to ignore this parameter.
+ </description>
+ <entry name="default" value="0" summary="no preference, apply
default policy"/>
Post by Jason Ekstrand
+ <entry name="scale" value="1" summary="scale, preserve the
surface's aspect ratio and center on output"/>
Post by Jason Ekstrand
+ <entry name="driver" value="2" summary="switch output mode to
the
Post by Jason Ekstrand
Post by Jonas Ådahl
smallest mode that can fit the surface, add black borders to compensate
size mismatch"/>
Post by Jason Ekstrand
+ <entry name="fill" value="3" summary="no upscaling, center on
output and add black borders to compensate size mismatch"/>
Post by Jason Ekstrand
+ </enum>
+
+ <request name="present_surface">
+ <description summary="present surface for display">
+ This requests the system compositor to display surface on
output.
Post by Jason Ekstrand
Post by Jonas Ådahl
Post by Jason Ekstrand
+ Each client of the system compositor can have at most one
surface
Post by Jason Ekstrand
Post by Jonas Ådahl
You still use the term 'system compositor' here. Also, it should be
"display a surface" instead of "display surface".
Thanks. Good catch. I've fixed it locally.
Post by Jonas Ådahl
Post by Jason Ekstrand
+ per output at any one time. Subsequent requests with the same
+ output replace the surface bound to that output. The same
surface
Post by Jason Ekstrand
Post by Jonas Ådahl
Post by Jason Ekstrand
+ may be presented on multiple outputs.
+
+ If the output is null, the compositor will present the surface
on
Post by Jason Ekstrand
Post by Jonas Ådahl
Post by Jason Ekstrand
+ whatever display (or displays) it thinks best. In particular,
this
Post by Jason Ekstrand
Post by Jonas Ådahl
Post by Jason Ekstrand
+ may replace any or all surfaces currently presented so it
should
Post by Jason Ekstrand
Post by Jonas Ådahl
Post by Jason Ekstrand
+ not be used in combination with placing surfaces on specific
+ outputs.
+
+ The method specifies how the surface is to be persented. These
+ methods are identical to those in
wl_shell_surface.set_fullscreen.
Post by Jason Ekstrand
Post by Jonas Ådahl
Post by Jason Ekstrand
+ </description>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output"
allow-null="true"/>
Post by Jason Ekstrand
+ </request>
+ </interface>
+</protocol>
--
1.8.3.1
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131024/56b2a572/attachment.html>
Jason Ekstrand
2013-10-25 00:43:41 UTC
Permalink
---
protocol/fullscreen-shell.xml | 61 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
create mode 100644 protocol/fullscreen-shell.xml

diff --git a/protocol/fullscreen-shell.xml b/protocol/fullscreen-shell.xml
new file mode 100644
index 0000000..9bef555
--- /dev/null
+++ b/protocol/fullscreen-shell.xml
@@ -0,0 +1,61 @@
+<protocol name="fullscreen_shell">
+ <interface name="wl_fullscreen_shell" version="1">
+ <description summary="Displays a single surface per output">
+ Displays a single surface per output.
+
+ This interface can only be bound to by one client at a time.
+ </description>
+
+ <enum name="present_method">
+ <description summary="different method to set the surface fullscreen">
+ Hints to indicate to the compositor how to deal with a conflict
+ between the dimensions of the surface and the dimensions of the
+ output. The compositor is free to ignore this parameter.
+ </description>
+ <entry name="default" value="0" summary="no preference, apply default policy"/>
+ <entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/>
+ <entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/>
+ <entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
+ </enum>
+
+ <request name="present_surface">
+ <description summary="present surface for display">
+ Present a surface on the given output.
+
+ This requests the fullscreen shell to display the given surface on
+ the given output. Each client of the fullscreen shell can have at
+ most one surface per output at any one time. Subsequent requests
+ with the same output replace the surface bound to that output.
+ Setting a null surface on an output effectively disables that
+ output for whatever definition of "disables" applies to the
+ implementaiton. The same surface may be presented on multiple
+ outputs.
+
+ If the output is null, the compositor will present the surface on
+ whatever display (or displays) it thinks best. In particular, this
+ may replace any or all surfaces currently presented so it should
+ not be used in combination with placing surfaces on specific
+ outputs.
+
+ The method specifies how the surface is to be persented. In
+ particular, this instructs the compositor how to handle a size
+ mismatch between the presented surface and the output.
+
+ The framerate parameter is used only when the method is set
+ to "driver", to indicate the preferred framerate. A value of 0
+ indicates that the app does not care about framerate. The
+ framerate is specified in mHz, that is framerate of 60000 is 60Hz.
+
+ A method of "scale" or "driver" implies a scaling operation of
+ the surface, either via a direct scaling operation or a change of
+ the output mode. This will override any kind of output scaling, so
+ that mapping a surface with a buffer size equal to the mode can
+ fill the screen independent of buffer_scale.
+ </description>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ </request>
+ </interface>
+</protocol>
--
1.8.3.1
Jason Ekstrand
2013-10-23 01:48:26 UTC
Permalink
---
protocol/Makefile.am | 1 +
src/.gitignore | 3 +++
src/Makefile.am | 5 +++++
3 files changed, 9 insertions(+)

diff --git a/protocol/Makefile.am b/protocol/Makefile.am
index 924e48f..2117a14 100644
--- a/protocol/Makefile.am
+++ b/protocol/Makefile.am
@@ -8,4 +8,5 @@ EXTRA_DIST = \
workspaces.xml \
subsurface.xml \
text-cursor-position.xml \
+ fullscreen-shell.xml \
wayland-test.xml
diff --git a/src/.gitignore b/src/.gitignore
index 539150d..b328577 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -21,4 +21,7 @@ input-method-protocol.c
input-method-server-protocol.h
subsurface-server-protocol.h
subsurface-protocol.c
+fullscreen-shell-server-protocol.h
+fullscreen-shell-client-protocol.h
+fullscreen-shell-protocol.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 4224495..792d58e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,6 +38,8 @@ weston_SOURCES = \
workspaces-server-protocol.h \
subsurface-protocol.c \
subsurface-server-protocol.h \
+ fullscreen-shell-protocol.c \
+ fullscreen-shell-server-protocol.h \
bindings.c \
animation.c \
noop-renderer.c \
@@ -346,6 +348,9 @@ BUILT_SOURCES = \
workspaces-protocol.c \
subsurface-server-protocol.h \
subsurface-protocol.c \
+ fullscreen-shell-server-protocol.h \
+ fullscreen-shell-client-protocol.h \
+ fullscreen-shell-protocol.c \
git-version.h

CLEANFILES = $(BUILT_SOURCES)
--
1.8.3.1
Jason Ekstrand
2013-10-23 01:48:27 UTC
Permalink
---
src/compositor.h | 1 +
src/input.c | 2 ++
2 files changed, 3 insertions(+)

diff --git a/src/compositor.h b/src/compositor.h
index 5b813fc..78e19b9 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -463,6 +463,7 @@ struct weston_seat {
struct weston_output *output; /* constraint */

struct wl_signal destroy_signal;
+ struct wl_signal updated_caps_signal;

struct weston_compositor *compositor;
struct wl_list link;
diff --git a/src/input.c b/src/input.c
index 2fed718..774545c 100644
--- a/src/input.c
+++ b/src/input.c
@@ -466,6 +466,7 @@ seat_send_updated_caps(struct weston_seat *seat)
wl_resource_for_each(resource, &seat->base_resource_list) {
wl_seat_send_capabilities(resource, caps);
}
+ wl_signal_emit(&seat->updated_caps_signal, seat);
}

WL_EXPORT void
@@ -1888,6 +1889,7 @@ weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
wl_signal_init(&seat->selection_signal);
wl_list_init(&seat->drag_resource_list);
wl_signal_init(&seat->destroy_signal);
+ wl_signal_init(&seat->updated_caps_signal);

seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 3,
seat, bind_seat);
--
1.8.3.1
Jason Ekstrand
2013-10-23 01:48:28 UTC
Permalink
---
configure.ac | 8 +
src/Makefile.am | 12 ++
src/fullscreen-shell.c | 574 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 594 insertions(+)
create mode 100644 src/fullscreen-shell.c

diff --git a/configure.ac b/configure.ac
index cfd4540..815e3c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -367,6 +367,13 @@ AC_ARG_ENABLE(tablet-shell,
AM_CONDITIONAL(ENABLE_TABLET_SHELL,
test "x$enable_tablet_shell" = "xyes")

+AC_ARG_ENABLE(fullscreen-shell,
+ AS_HELP_STRING([--disable-fullscreen-shell],
+ [do not build fullscreen-shell server plugin]),,
+ enable_fullscreen_shell=yes)
+AM_CONDITIONAL(ENABLE_FULLSCREEN_SHELL,
+ test "x$enable_fullscreen_shell" = "xyes")
+
# CMS modules
AC_ARG_ENABLE(colord,
AS_HELP_STRING([--disable-colord],
@@ -500,6 +507,7 @@ AC_MSG_RESULT([

Build wcap utility ${enable_wcap_tools}
Build Tablet Shell ${enable_tablet_shell}
+ Build Fullscreen Shell ${enable_fullscreen_shell}

weston-launch utility ${enable_weston_launch}
systemd-login support ${have_systemd_login}
diff --git a/src/Makefile.am b/src/Makefile.am
index 792d58e..5f06bbc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -112,6 +112,7 @@ moduledir = $(libdir)/weston
module_LTLIBRARIES = \
$(desktop_shell) \
$(tablet_shell) \
+ $(fullscreen_shell) \
$(cms_static) \
$(cms_colord) \
$(gl_renderer) \
@@ -299,6 +300,17 @@ tablet_shell_la_SOURCES = \
tablet-shell-server-protocol.h
endif

+if ENABLE_FULLSCREEN_SHELL
+fullscreen_shell = fullscreen-shell.la
+fullscreen_shell_la_LDFLAGS = -module -avoid-version
+fullscreen_shell_la_LIBADD = $(COMPOSITOR_LIBS)
+fullscreen_shell_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS)
+fullscreen_shell_la_SOURCES = \
+ fullscreen-shell.c \
+ fullscreen-shell-protocol.c \
+ fullscreen-shell-server-protocol.h
+endif
+
if HAVE_LCMS
cms_static = cms-static.la
cms_static_la_LDFLAGS = -module -avoid-version
diff --git a/src/fullscreen-shell.c b/src/fullscreen-shell.c
new file mode 100644
index 0000000..ff7c303
--- /dev/null
+++ b/src/fullscreen-shell.c
@@ -0,0 +1,574 @@
+/*
+ * Copyright ? 2013 Jason Ekstrand
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "compositor.h"
+#include "fullscreen-shell-server-protocol.h"
+
+struct fullscreen_shell {
+ struct wl_client *client;
+ struct wl_listener client_destroyed;
+ struct weston_compositor *compositor;
+
+ struct weston_layer layer;
+ struct wl_list outputs;
+ struct wl_listener output_created_listener;
+
+ struct wl_listener seat_created_listener;
+};
+
+struct fs_output {
+ struct fullscreen_shell *shell;
+ struct wl_list link;
+
+ struct weston_output *output;
+ struct wl_listener output_destroyed;
+
+ struct weston_surface *surface;
+ struct wl_listener surface_destroyed;
+ struct weston_view *view;
+ struct weston_view *black_view;
+ struct weston_transform transform; /* matrix from x, y */
+
+ enum wl_fullscreen_shell_fullscreen_method method;
+ uint32_t framerate;
+};
+
+struct pointer_focus_listener {
+ struct wl_listener pointer_focus;
+ struct wl_listener seat_caps;
+ struct wl_listener seat_destroyed;
+};
+
+static void
+pointer_focus_changed(struct wl_listener *listener, void *data)
+{
+ struct weston_pointer *pointer = data;
+
+ if (pointer->focus)
+ weston_surface_activate(pointer->focus->surface, pointer->seat);
+}
+
+static void
+seat_caps_changed(struct wl_listener *l, void *data)
+{
+ struct weston_seat *seat = data;
+ struct pointer_focus_listener *listener;
+
+ listener = container_of(l, struct pointer_focus_listener, seat_caps);
+
+ /* no pointer */
+ if (seat->pointer) {
+ if (!listener->pointer_focus.link.prev) {
+ wl_signal_add(&seat->pointer->focus_signal,
+ &listener->pointer_focus);
+ }
+ } else {
+ if (listener->pointer_focus.link.prev) {
+ wl_list_remove(&listener->pointer_focus.link);
+ }
+ }
+}
+
+static void
+seat_destroyed(struct wl_listener *l, void *data)
+{
+ struct pointer_focus_listener *listener;
+
+ listener = container_of(l, struct pointer_focus_listener,
+ seat_destroyed);
+
+ free(listener);
+}
+
+static void
+seat_created(struct wl_listener *l, void *data)
+{
+ struct weston_seat *seat = data;
+ struct pointer_focus_listener *listener;
+
+ listener = malloc(sizeof *listener);
+ if (!listener)
+ return;
+ memset(listener, 0, sizeof *listener);
+
+ listener->pointer_focus.notify = pointer_focus_changed;
+ listener->seat_caps.notify = seat_caps_changed;
+ listener->seat_destroyed.notify = seat_destroyed;
+
+ wl_signal_add(&seat->destroy_signal, &listener->seat_destroyed);
+ wl_signal_add(&seat->updated_caps_signal, &listener->seat_caps);
+
+ seat_caps_changed(&listener->seat_caps, seat);
+}
+
+static void
+black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy,
+ int32_t width, int32_t height)
+{
+}
+
+static struct weston_view *
+create_black_surface(struct weston_compositor *ec, struct fs_output *fsout,
+ float x, float y, int w, int h)
+{
+ struct weston_surface *surface = NULL;
+ struct weston_view *view;
+
+ surface = weston_surface_create(ec);
+ if (surface == NULL) {
+ weston_log("no memory\n");
+ return NULL;
+ }
+ view = weston_view_create(surface);
+ if (!view) {
+ weston_surface_destroy(surface);
+ weston_log("no memory\n");
+ return NULL;
+ }
+
+ surface->configure = black_surface_configure;
+ surface->configure_private = fsout;
+ surface->width = w;
+ surface->height = h;
+ weston_surface_set_color(surface, 0.0f, 0.0f, 0.0f, 1.0f);
+ pixman_region32_fini(&surface->opaque);
+ pixman_region32_init_rect(&surface->opaque, 0, 0, w, h);
+ pixman_region32_fini(&surface->input);
+ pixman_region32_init_rect(&surface->input, 0, 0, w, h);
+
+ weston_view_configure(view, x, y, w, h);
+
+ return view;
+}
+
+static void
+fs_output_destroy(struct fs_output *fsout)
+{
+ wl_list_remove(&fsout->link);
+
+ if (fsout->output)
+ wl_list_remove(&fsout->output_destroyed.link);
+
+ if (fsout->view) {
+ weston_view_destroy(fsout->view);
+ wl_list_remove(&fsout->surface_destroyed.link);
+ }
+}
+
+static void
+output_destroyed(struct wl_listener *listener, void *data)
+{
+ struct fs_output *output = container_of(listener,
+ struct fs_output,
+ output_destroyed);
+ fs_output_destroy(output);
+}
+
+static void
+surface_destroyed(struct wl_listener *listener, void *data)
+{
+ struct fs_output *output = container_of(listener,
+ struct fs_output,
+ output_destroyed);
+ output->surface = NULL;
+ output->view = NULL;
+}
+
+static struct fs_output *
+fs_output_create(struct fullscreen_shell *shell, struct weston_output *output)
+{
+ struct fs_output *fsout;
+
+ fsout = malloc(sizeof *fsout);
+ if (!fsout)
+ return NULL;
+ memset(fsout, 0, sizeof *fsout);
+
+ fsout->shell = shell;
+ wl_list_insert(&shell->outputs, &fsout->link);
+
+ fsout->output = output;
+ fsout->output_destroyed.notify = output_destroyed;
+ wl_signal_add(&output->destroy_signal, &fsout->output_destroyed);
+
+ fsout->surface_destroyed.notify = surface_destroyed;
+ fsout->black_view = create_black_surface(shell->compositor, fsout,
+ output->x, output->y,
+ output->width, output->height);
+ wl_list_insert(&shell->layer.view_list,
+ &fsout->black_view->layer_link);
+ return fsout;
+}
+
+static struct fs_output *
+fs_output_for_output(struct weston_output *output)
+{
+ struct wl_listener *listener;
+
+ if (!output)
+ return NULL;
+
+ listener = wl_signal_get(&output->destroy_signal, output_destroyed);
+
+ return container_of(listener, struct fs_output, output_destroyed);
+}
+
+static void
+restore_output_mode(struct weston_output *output)
+{
+ if (output->current_mode != output->original_mode ||
+ (int32_t)output->current_scale != output->original_scale)
+ weston_output_switch_mode(output,
+ output->original_mode,
+ output->original_scale,
+ WESTON_MODE_SWITCH_RESTORE_NATIVE);
+}
+
+/*
+ * Returns the bounding box of a surface and all its sub-surfaces,
+ * in the surface coordinates system. */
+static void
+surface_subsurfaces_boundingbox(struct weston_surface *surface, int32_t *x,
+ int32_t *y, int32_t *w, int32_t *h) {
+ pixman_region32_t region;
+ pixman_box32_t *box;
+ struct weston_subsurface *subsurface;
+
+ pixman_region32_init_rect(&region, 0, 0,
+ surface->width,
+ surface->height);
+
+ wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
+ pixman_region32_union_rect(&region, &region,
+ subsurface->position.x,
+ subsurface->position.y,
+ subsurface->surface->width,
+ subsurface->surface->height);
+ }
+
+ box = pixman_region32_extents(&region);
+ if (x)
+ *x = box->x1;
+ if (y)
+ *y = box->y1;
+ if (w)
+ *w = box->x2 - box->x1;
+ if (h)
+ *h = box->y2 - box->y1;
+
+ pixman_region32_fini(&region);
+}
+
+static void
+fs_output_center_view(struct fs_output *fsout)
+{
+ int32_t surf_x, surf_y, surf_width, surf_height;
+ float x, y;
+ struct weston_output *output = fsout->output;
+
+ surface_subsurfaces_boundingbox(fsout->view->surface, &surf_x, &surf_y,
+ &surf_width, &surf_height);
+
+ x = output->x + (output->width - surf_width) / 2 - surf_x / 2;
+ y = output->y + (output->height - surf_height) / 2 - surf_y / 2;
+
+ weston_view_set_position(fsout->view, x, y);
+}
+
+static void
+fs_output_scale_view(struct fs_output *fsout)
+{
+ float scale, output_aspect, surface_aspect, x, y;
+ int32_t surf_x, surf_y, surf_width, surf_height;
+ struct weston_matrix *matrix;
+ struct weston_view *view = fsout->view;
+ struct weston_output *output = fsout->output;
+
+ surface_subsurfaces_boundingbox(view->surface, &surf_x, &surf_y,
+ &surf_width, &surf_height);
+
+ if (output->width == surf_width && output->height == surf_height) {
+ weston_view_set_position(view,
+ fsout->output->x - surf_x,
+ fsout->output->y - surf_y);
+ } else {
+ matrix = &fsout->transform.matrix;
+ weston_matrix_init(matrix);
+
+ output_aspect = (float) output->width / (float) output->height;
+ surface_aspect = (float) surf_width / (float) surf_height;
+
+ if (output_aspect < surface_aspect)
+ scale = (float) output->width / (float) surf_width;
+ else
+ scale = (float) output->height / (float) surf_height;
+
+ weston_matrix_scale(matrix, scale, scale, 1);
+ wl_list_remove(&fsout->transform.link);
+ wl_list_insert(&fsout->view->geometry.transformation_list,
+ &fsout->transform.link);
+
+ x = output->x + (output->width - surf_width * scale) / 2 - surf_x;
+ y = output->y + (output->height - surf_height * scale) / 2 - surf_y;
+
+ weston_view_set_position(view, x, y);
+ }
+}
+
+static void
+configure_output(struct fs_output *fsout)
+{
+ int32_t surf_x, surf_y, surf_width, surf_height;
+ struct weston_mode mode;
+
+ assert(fsout->view);
+
+ weston_view_configure(fsout->view, fsout->output->x, fsout->output->y,
+ fsout->surface->width,
+ fsout->surface->height);
+
+ if (fsout->method != WL_FULLSCREEN_SHELL_FULLSCREEN_METHOD_DRIVER)
+ restore_output_mode(fsout->output);
+
+ switch (fsout->method) {
+ case WL_FULLSCREEN_SHELL_FULLSCREEN_METHOD_DEFAULT:
+ fs_output_center_view(fsout);
+ break;
+
+ case WL_FULLSCREEN_SHELL_FULLSCREEN_METHOD_SCALE:
+ fs_output_scale_view(fsout);
+ break;
+
+ case WL_FULLSCREEN_SHELL_FULLSCREEN_METHOD_DRIVER:
+ surface_subsurfaces_boundingbox(fsout->view->surface,
+ &surf_x, &surf_y,
+ &surf_width, &surf_height);
+
+ mode.flags = 0;
+ mode.width = surf_width * fsout->view->surface->buffer_scale;
+ mode.height = surf_height * fsout->view->surface->buffer_scale;
+ mode.refresh = fsout->framerate;
+
+ if (weston_output_switch_mode(fsout->output, &mode,
+ fsout->view->surface->buffer_scale,
+ WESTON_MODE_SWITCH_SET_TEMPORARY) == 0) {
+ weston_view_set_position(fsout->view,
+ fsout->output->x - surf_x,
+ fsout->output->y - surf_y);
+ weston_view_configure(fsout->black_view,
+ fsout->output->x - surf_x,
+ fsout->output->y - surf_y,
+ fsout->output->width,
+ fsout->output->height);
+ break;
+ } else {
+ restore_output_mode(fsout->output);
+ fs_output_center_view(fsout);
+ }
+ break;
+
+ case WL_FULLSCREEN_SHELL_FULLSCREEN_METHOD_FILL:
+ fs_output_center_view(fsout);
+ break;
+
+ default:
+ break;
+ }
+
+ weston_output_schedule_repaint(fsout->output);
+}
+
+static void
+configure_presented_surface(struct weston_surface *surface, int32_t sx,
+ int32_t sy, int32_t width, int32_t height)
+{
+ struct fullscreen_shell *shell = surface->configure_private;
+ struct fs_output *fsout;
+
+ if (surface->configure != configure_presented_surface)
+ return;
+
+ wl_list_for_each(fsout, &shell->outputs, link)
+ if (fsout->view && fsout->view->surface == surface)
+ configure_output(fsout);
+}
+
+static void
+fs_output_set_surface(struct fs_output *fsout, struct weston_surface *surface,
+ enum wl_fullscreen_shell_fullscreen_method method,
+ uint32_t framerate)
+{
+ if (fsout->view && fsout->surface != surface) {
+ wl_list_remove(&fsout->surface_destroyed.link);
+
+ weston_view_destroy(fsout->view);
+ fsout->view = NULL;
+
+ if (wl_list_empty(&fsout->surface->views)) {
+ fsout->surface->configure = NULL;
+ fsout->surface->configure_private = NULL;
+ }
+ }
+
+ fsout->method = method;
+ fsout->framerate = framerate;
+
+ if (surface && fsout->surface != surface) {
+ if (!surface->configure) {
+ surface->configure = configure_presented_surface;
+ surface->configure_private = fsout->shell;
+ }
+
+ fsout->view = weston_view_create(surface);
+ if (!fsout->view) {
+ weston_log("no memory\n");
+ return;
+ }
+
+ fsout->surface = surface;
+ wl_signal_add(&surface->destroy_signal,
+ &fsout->surface_destroyed);
+ wl_list_insert(&fsout->shell->layer.view_list,
+ &fsout->view->layer_link);
+ }
+
+ configure_output(fsout);
+ weston_output_schedule_repaint(fsout->output);
+}
+
+static void
+fullscreen_shell_present_surface(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *surface_res,
+ uint32_t method, uint32_t framerate,
+ struct wl_resource *output_res)
+{
+ struct fullscreen_shell *shell =
+ wl_resource_get_user_data(resource);
+ struct weston_output *output;
+ struct weston_surface *surface;
+ struct fs_output *fsout;
+
+ surface = surface_res ? wl_resource_get_user_data(surface_res) : NULL;
+
+ if (output_res) {
+ output = wl_resource_get_user_data(output_res);
+ fsout = fs_output_for_output(output);
+ fs_output_set_surface(fsout, surface, method, framerate);
+ } else {
+ wl_list_for_each(fsout, &shell->outputs, link)
+ fs_output_set_surface(fsout, surface, method, framerate);
+ }
+}
+
+struct wl_fullscreen_shell_interface fullscreen_shell_implementation = {
+ fullscreen_shell_present_surface,
+};
+
+static void
+output_created(struct wl_listener *listener, void *data)
+{
+ struct fullscreen_shell *shell;
+
+ shell = container_of(listener, struct fullscreen_shell,
+ output_created_listener);
+
+ fs_output_create(shell, data);
+}
+
+static void
+client_destroyed(struct wl_listener *listener, void *data)
+{
+ struct fullscreen_shell *shell = container_of(listener,
+ struct fullscreen_shell,
+ client_destroyed);
+ shell->client = NULL;
+}
+
+static void
+bind_fullscreen_shell(struct wl_client *client, void *data, uint32_t version,
+ uint32_t id)
+{
+ struct fullscreen_shell *shell = data;
+ struct wl_resource *resource;
+
+ if (shell->client != NULL && shell->client != client)
+ return;
+ else if (shell->client == NULL) {
+ shell->client = client;
+ wl_client_add_destroy_listener(client, &shell->client_destroyed);
+ }
+
+ resource = wl_resource_create(client, &wl_fullscreen_shell_interface,
+ 1, id);
+ wl_resource_set_implementation(resource,
+ &fullscreen_shell_implementation,
+ shell, NULL);
+}
+
+WL_EXPORT int
+module_init(struct weston_compositor *compositor,
+ int *argc, char *argv[])
+{
+ struct fullscreen_shell *shell;
+ struct weston_seat *seat;
+ struct weston_output *output;
+
+ shell = malloc(sizeof *shell);
+ if (shell == NULL)
+ return -1;
+
+ memset(shell, 0, sizeof *shell);
+ shell->compositor = compositor;
+
+ shell->client_destroyed.notify = client_destroyed;
+
+ weston_layer_init(&shell->layer, &compositor->cursor_layer.link);
+
+ wl_list_init(&shell->outputs);
+ shell->output_created_listener.notify = output_created;
+ wl_signal_add(&compositor->output_created_signal,
+ &shell->output_created_listener);
+ wl_list_for_each(output, &compositor->output_list, link)
+ fs_output_create(shell, output);
+
+ shell->seat_created_listener.notify = seat_created;
+ wl_signal_add(&compositor->seat_created_signal,
+ &shell->seat_created_listener);
+ wl_list_for_each(seat, &compositor->seat_list, link)
+ seat_created(NULL, seat);
+
+ wl_global_create(compositor->wl_display,
+ &wl_fullscreen_shell_interface, 1, shell,
+ bind_fullscreen_shell);
+
+ return 0;
+}
--
1.8.3.1
Jason Ekstrand
2013-10-23 01:48:29 UTC
Permalink
This makes simple-shm act like a very simple fullscreen shell client. This
is the kind of interaction one would expect out of a boot splash screen or
similar.
---
clients/.gitignore | 2 ++
clients/Makefile.am | 4 ++++
clients/simple-shm.c | 32 +++++++++++++++++++++++++-------
3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/clients/.gitignore b/clients/.gitignore
index 23959cc..4f7d9d4 100644
--- a/clients/.gitignore
+++ b/clients/.gitignore
@@ -21,6 +21,8 @@ weston-view

desktop-shell-client-protocol.h
desktop-shell-protocol.c
+fullscreen-shell-protocol.c
+fullscreen-shell-client-protocol.h
input-method-protocol.c
input-method-client-protocol.h
weston-keyboard
diff --git a/clients/Makefile.am b/clients/Makefile.am
index 4f9dc48..a65d83e 100644
--- a/clients/Makefile.am
+++ b/clients/Makefile.am
@@ -36,6 +36,8 @@ simple_clients_programs = \
weston-multi-resource

weston_simple_shm_SOURCES = simple-shm.c \
+ fullscreen-shell-client-protocol.h \
+ fullscreen-shell-protocol.c \
../shared/os-compatibility.c \
../shared/os-compatibility.h
weston_simple_shm_CPPFLAGS = $(SIMPLE_CLIENT_CFLAGS)
@@ -225,6 +227,8 @@ BUILT_SOURCES = \
input-method-client-protocol.h \
desktop-shell-client-protocol.h \
desktop-shell-protocol.c \
+ fullscreen-shell-client-protocol.h \
+ fullscreen-shell-protocol.c \
tablet-shell-client-protocol.h \
tablet-shell-protocol.c \
subsurface-client-protocol.h \
diff --git a/clients/simple-shm.c b/clients/simple-shm.c
index 81bb54e..b55f13a 100644
--- a/clients/simple-shm.c
+++ b/clients/simple-shm.c
@@ -34,12 +34,14 @@

#include <wayland-client.h>
#include "../shared/os-compatibility.h"
+#include "fullscreen-shell-client-protocol.h"

struct display {
struct wl_display *display;
struct wl_registry *registry;
struct wl_compositor *compositor;
struct wl_shell *shell;
+ struct wl_fullscreen_shell *fshell;
struct wl_shm *shm;
uint32_t formats;
};
@@ -148,16 +150,25 @@ create_window(struct display *display, int width, int height)
window->width = width;
window->height = height;
window->surface = wl_compositor_create_surface(display->compositor);
- window->shell_surface = wl_shell_get_shell_surface(display->shell,
- window->surface);

- if (window->shell_surface)
+ if (display->shell) {
+ window->shell_surface =
+ wl_shell_get_shell_surface(display->shell,
+ window->surface);
+ assert(window->shell_surface);
wl_shell_surface_add_listener(window->shell_surface,
&shell_surface_listener, window);

- wl_shell_surface_set_title(window->shell_surface, "simple-shm");
-
- wl_shell_surface_set_toplevel(window->shell_surface);
+ wl_shell_surface_set_title(window->shell_surface, "simple-shm");
+ wl_shell_surface_set_toplevel(window->shell_surface);
+ } else if (display->fshell) {
+ wl_fullscreen_shell_present_surface(display->fshell,
+ window->surface,
+ WL_FULLSCREEN_SHELL_FULLSCREEN_METHOD_DEFAULT,
+ 0, NULL);
+ } else {
+ assert(0);
+ }

return window;
}
@@ -173,7 +184,8 @@ destroy_window(struct window *window)
if (window->buffers[1].buffer)
wl_buffer_destroy(window->buffers[1].buffer);

- wl_shell_surface_destroy(window->shell_surface);
+ if (window->shell_surface)
+ wl_shell_surface_destroy(window->shell_surface);
wl_surface_destroy(window->surface);
free(window);
}
@@ -313,6 +325,9 @@ registry_handle_global(void *data, struct wl_registry *registry,
} else if (strcmp(interface, "wl_shell") == 0) {
d->shell = wl_registry_bind(registry,
id, &wl_shell_interface, 1);
+ } else if (strcmp(interface, "wl_fullscreen_shell") == 0) {
+ d->fshell = wl_registry_bind(registry,
+ id, &wl_fullscreen_shell_interface, 1);
} else if (strcmp(interface, "wl_shm") == 0) {
d->shm = wl_registry_bind(registry,
id, &wl_shm_interface, 1);
@@ -375,6 +390,9 @@ destroy_display(struct display *display)
if (display->shell)
wl_shell_destroy(display->shell);

+ if (display->fshell)
+ wl_fullscreen_shell_destroy(display->fshell);
+
if (display->compositor)
wl_compositor_destroy(display->compositor);
--
1.8.3.1
Jason Ekstrand
2014-02-14 04:37:09 UTC
Permalink
This RFC is for the third version of my fullscreen shell implementation.
The contents of this RFC are:

* A new wl_fullscreen_shell protocol
* A weston shell that provides wl_fullscreen_shell
* Additions to the Wayland backend for Weston to take advantage of
wl_fullscreen_shell
* Additions to weston-simple-shm and weston-fullscreen to demonstrate the
wl_fullscreen_shell protocol.

This RFC improves the second version in a couple of ways:

* Changes the possible presentation modes to allow more options for clients
* Adds support in weston-fullscreen for fully testing wl_fullscreen_shell
* Various bugfixes

The previous version of this RFC can be found here:
http://lists.freedesktop.org/archives/wayland-devel/2013-October/011626.html

The original RFC can be found here:
http://lists.freedesktop.org/archives/wayland-devel/2013-August/010720.html

This RFC is primarily to provide a preview of the implementation, so I am
not going to spam the list with patches. Instead, you can view it in its
entirety on my github:
https://github.com/jekstrand/weston/tree/fullscreen-shell-RFCv3

Immediately following this e-mail will be a fourth protocol-only RFC that
contains substantial changes to the modesetting portion of the protocol.
Feedback there is appreciated as well.

Thanks,
--Jason Ekstrand


Jason Ekstrand (11):
Add a fullscreen shell protocol
Generate/build the fullscreen shell protocol files
Add a signal for when a seat updates its capabilities
Add a wl_fullscreen_shell implementation
simple-shm: Add fullscreen shell support
toytoolkit: Only require xdg_shell if the window is not custom
Add wl_fullscreen_shell support to weston-fullscreen
compositor-wayland: Add support for running on top of
wl_fullscreen_shell
compositor-wayland: Add a --sprawl option
Automatically select the wayland backend if WAYLAND_SOCKET is set
Properly handle running inside a compositor that does not provide
keymaps

Makefile.am | 32 +++
clients/fullscreen.c | 84 +++++-
clients/simple-shm.c | 31 ++-
clients/window.c | 2 +-
configure.ac | 8 +
protocol/fullscreen-shell.xml | 70 +++++
src/compositor-wayland.c | 347 ++++++++++++++++++++---
src/compositor.c | 3 +-
src/compositor.h | 1 +
src/fullscreen-shell.c | 626 ++++++++++++++++++++++++++++++++++++++++++
src/input.c | 2 +
11 files changed, 1145 insertions(+), 61 deletions(-)
create mode 100644 protocol/fullscreen-shell.xml
create mode 100644 src/fullscreen-shell.c
--
1.8.5.3
Jason Ekstrand
2014-02-14 04:37:53 UTC
Permalink
The following is yet another take on the fullscreen shell protocol.
Previous versions more-or-less followed the approach taken in wl_shell.
This version completely reworks the concept. In particular, the protocol
is split into two use-cases. The first is that of a simple client that
wants to present a surface or set of surfaces possibly with some scaling.
This happens through the present_surface request which looks similar to
that of wl_shell only without the modesetting.

The second use-case is of a client that wants more control over the
outputs. In this case, the client uses the present_surface_for_mode
request to present the surface at a particular output mode. This request
provides a more-or-less atomic modeset operation. If the compositor can
satisfy the requested mode, then the mode is changed and the new surface is
presented. Otherwise, the compositor harmlessly falls back to the
previously presented surface and the client is informed that the switch
failed. This way, the surface is either displayed correctly or not at all.
Of course, a client is free to call present_surface_for_mode with the
currently presented surface and hope for the best. However, this may
result in strange behavior and there is no reliable fallback if the mode
switch fails.

In particular, I would like feedback on the modesetting portion of this
protocol. This is particularly targetted at compositors that want to run
inside weston or some other fullscreen compositor. In the next week or so,
I will attempt to implement all this in weston and see how well it works.
However, I would also like to know how well this will work for other
compositors such as KWin or Hawaii.

Thanks for your feedback,
--Jason Ekstrand

===== Protocol follows: =====

<protocol name="fullscreen_shell">
<interface name="wl_fullscreen_shell" version="1">
<description summary="Displays a single surface per output">
Displays a single surface per output.

This interface provides a mechanism for a single client to display
simple full-screen surfaces. While there technically may be multiple
clients bound to this interface, only one of those clients should be
shown at a time.

To present a surface, the client uses either the present_surface or
present_surface_for_mode requests. Presenting a surface takes effect
on the next wl_surface.commit. See the individual requests for
details about scaling and mode switches.

The client can have at most one surface per output at any time.
Requesting a surface be presented on an output that already has a
surface replaces the previously presented surface. Presenting a null
surface removes its content and effectively disables the output.
Exactly what happens when an output is "disabled" is
compositor-specific. The same surface may be presented multiple
outputs simultaneously.
</description>

<enum name="present_method">
<description summary="different method to set the surface fullscreen">
Hints to indicate to the compositor how to deal with a conflict
between the dimensions of the surface and the dimensions of the
output. The compositor is free to ignore this parameter.
</description>
<entry name="default" value="0" summary="no preference, apply default policy"/>
<entry name="center" value="1" summary="center the surface on the output"/>
<entry name="zoom" value="2" summary="scale the surface, preserving aspect ratio, to the largest size that will fit on the output" />
<entry name="zoom_crop" value="3" summary="scale the surface, preserving aspect ratio, to fully fill the output cropping if needed" />
<entry name="stretch" value="4" summary="scale the surface to the size of the output ignoring aspect ratio" />
</enum>

<request name="present_surface">
<description summary="present surface for display">
Present a surface on the given output.

If the output is null, the compositor will present the surface on
whatever display (or displays) it thinks best. In particular, this
may replace any or all surfaces currently presented so it should
not be used in combination with placing surfaces on specific
outputs.

The method parameter is a hit to the compositor for how the surface
is to be presented. In particular, it tells the compostior how to
handle a size mismatch between the presented surface and the
output. The compositor is free to ignore this parameter.

The "zoom", "zoom_crop", and "stretch" methods imply a scaling
operation on the surface. This will override any kind of output
scaling, so the buffer_scale property of the surface is effectively
ignored.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="method" type="uint"/>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>

<request name="present_surface_for_mode">
<description summary="present surface for display at a particular mode">
Presents a surface on the given output for a particular mode.

If the current size of the output differs from that of the surface,
the compositor will attempt to change the size of the output to
match the surface. The result of the mode-swith operation will be
returned via the provided wl_fullscreen_shell_mode_feedback object.

If the current output mode matches the one requested or if the
compositor successfully switches the mode to match the surface,
then the mode_successfull event will be sent and the output will
contain the contents of the given surface. If the compositor
cannot match the output size to the surface size, the mode_failed
will be sent and the output will contain the contents of the
previously presented surface (if any). If another surface is
presented on the given output before either of these has a chance
to happen, the present_canceled event will be sent.

If the size of the presented surface changes, the resulting output
is undefined. The compositor may attempt to change the output mode
to compensate. However, there is no guarantee that a suitable mode
will be found and the client has no way to be notified of success
or failure.

The framerate parameter specifies the target framerate for the
output. The compositor is free to ignore this parameter. A value
of 0 indicates that the client has no preference.

If the surface has a buffer_scale greater than 1, the compositor
may choose a mode that matches either the buffer size or the
surface size. In either case, the surface will fill the output.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="output" type="object" interface="wl_output"/>
<arg name="framerate" type="int"/>
<arg name="feedback" type="new_id" interface="wl_fullscreen_shell_mode_feedback"/>
</request>

<enum name="error">
<description summary="wl_fullscreen_shell error values">
These errors can be emitted in response to wl_fullscreen_shell requests
</description>
<entry name="invalid_method" value="0" summary="present_method is not known"/>
</enum>
</interface>

<interface name="wl_fullscreen_shell_mode_feedback" version="1">
<event name="mode_successful">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation was
successful. A surface of the size requested in the mode switch
will fill the output without scaling.

Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="mode_failed">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation
failed. This may be because the requested output mode is not
possible or it may mean that the compositor does not want to allow
mode switches at this time.

Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="present_canceled">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation was
canceled. Most likely this is because the client requested a
second mode switch before the first one completed.

Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
</interface>
</protocol>
Pekka Paalanen
2014-02-14 07:14:03 UTC
Permalink
Hi Jason

On Thu, 13 Feb 2014 22:37:53 -0600
Post by Jason Ekstrand
The following is yet another take on the fullscreen shell protocol.
Previous versions more-or-less followed the approach taken in wl_shell.
This version completely reworks the concept. In particular, the protocol
is split into two use-cases. The first is that of a simple client that
wants to present a surface or set of surfaces possibly with some scaling.
This happens through the present_surface request which looks similar to
that of wl_shell only without the modesetting.
The second use-case is of a client that wants more control over the
outputs. In this case, the client uses the present_surface_for_mode
request to present the surface at a particular output mode. This request
provides a more-or-less atomic modeset operation. If the compositor can
satisfy the requested mode, then the mode is changed and the new surface is
presented. Otherwise, the compositor harmlessly falls back to the
previously presented surface and the client is informed that the switch
failed. This way, the surface is either displayed correctly or not at all.
Of course, a client is free to call present_surface_for_mode with the
currently presented surface and hope for the best. However, this may
result in strange behavior and there is no reliable fallback if the mode
switch fails.
In particular, I would like feedback on the modesetting portion of this
protocol. This is particularly targetted at compositors that want to run
inside weston or some other fullscreen compositor. In the next week or so,
I will attempt to implement all this in weston and see how well it works.
However, I would also like to know how well this will work for other
compositors such as KWin or Hawaii.
Thanks for your feedback,
--Jason Ekstrand
===== Protocol follows: =====
<protocol name="fullscreen_shell">
<interface name="wl_fullscreen_shell" version="1">
This interface should have a destructor request IMO. It's not stricly
required, but I think it would be consistent (I think all global
interfaces need an explicit destructor request) and more future-proof.
Post by Jason Ekstrand
<description summary="Displays a single surface per output">
Displays a single surface per output.
This interface provides a mechanism for a single client to display
simple full-screen surfaces. While there technically may be multiple
clients bound to this interface, only one of those clients should be
shown at a time.
To present a surface, the client uses either the present_surface or
present_surface_for_mode requests. Presenting a surface takes effect
on the next wl_surface.commit. See the individual requests for
details about scaling and mode switches.
The client can have at most one surface per output at any time.
Requesting a surface be presented on an output that already has a
surface replaces the previously presented surface. Presenting a null
surface removes its content and effectively disables the output.
Exactly what happens when an output is "disabled" is
compositor-specific. The same surface may be presented multiple
outputs simultaneously.
If the same surface is presented on multiple outputs, should the client
have a way to say which output is to be considered the surface's main
output, where e.g. presentation feedback is synced to?

Maybe also note explicitly, that once a surface has been presented on
an output, it stays on that output until explicitly removed, or output
is unplugged? So that simple attach+damage+commit can be used to update
the content, if that is the intention.
Post by Jason Ekstrand
</description>
<enum name="present_method">
<description summary="different method to set the surface fullscreen">
Hints to indicate to the compositor how to deal with a conflict
between the dimensions of the surface and the dimensions of the
output. The compositor is free to ignore this parameter.
</description>
<entry name="default" value="0" summary="no preference, apply default policy"/>
<entry name="center" value="1" summary="center the surface on the output"/>
<entry name="zoom" value="2" summary="scale the surface, preserving aspect ratio, to the largest size that will fit on the output" />
<entry name="zoom_crop" value="3" summary="scale the surface, preserving aspect ratio, to fully fill the output cropping if needed" />
<entry name="stretch" value="4" summary="scale the surface to the size of the output ignoring aspect ratio" />
</enum>
<request name="present_surface">
<description summary="present surface for display">
Present a surface on the given output.
If the output is null, the compositor will present the surface on
whatever display (or displays) it thinks best. In particular, this
may replace any or all surfaces currently presented so it should
not be used in combination with placing surfaces on specific
outputs.
The method parameter is a hit to the compositor for how the surface
*hint
Post by Jason Ekstrand
is to be presented. In particular, it tells the compostior how to
handle a size mismatch between the presented surface and the
output. The compositor is free to ignore this parameter.
The "zoom", "zoom_crop", and "stretch" methods imply a scaling
operation on the surface. This will override any kind of output
scaling, so the buffer_scale property of the surface is effectively
ignored.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="method" type="uint"/>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>
<request name="present_surface_for_mode">
<description summary="present surface for display at a particular mode">
Presents a surface on the given output for a particular mode.
If the current size of the output differs from that of the surface,
the compositor will attempt to change the size of the output to
match the surface. The result of the mode-swith operation will be
returned via the provided wl_fullscreen_shell_mode_feedback object.
Is it sufficient to infer the mode from the buffer size, or could there
be use cases for forcing a particular mode and scaling a buffer from a
different size?

If you had a separate "set_mode" request, you could do with only the
"present_surface" request for setting the surface.

Taking this idea further, like atomic mode setting over all outputs,
we're getting pretty close to the DRM KMS APIs. Would it make sense to
model these interfaces according to the KMS APIs but sanitized to offer
all the modern features like atomic modeset and planes in a clean
uniform way, or do you intentionally want to keep this protocol
interface simple and not e.g. consider planes explicitly?
Post by Jason Ekstrand
If the current output mode matches the one requested or if the
compositor successfully switches the mode to match the surface,
then the mode_successfull event will be sent and the output will
contain the contents of the given surface. If the compositor
cannot match the output size to the surface size, the mode_failed
will be sent and the output will contain the contents of the
previously presented surface (if any). If another surface is
presented on the given output before either of these has a chance
to happen, the present_canceled event will be sent.
If the size of the presented surface changes, the resulting output
is undefined. The compositor may attempt to change the output mode
to compensate. However, there is no guarantee that a suitable mode
will be found and the client has no way to be notified of success
or failure.
The above sounds to me like you want the client be in explicit control
of the video mode when it asks one, without the server fuzzing in
between with scaling.

With an explicit "set_mode" request, I think you could make the above
cases defined.

How much control do you want to give to the client? Apparently you want
the two different cases: simple client, smart server; and smart client
with explicit mode setting, simple server just obeying or refusing
without any fuzz.
Post by Jason Ekstrand
The framerate parameter specifies the target framerate for the
output. The compositor is free to ignore this parameter. A value
of 0 indicates that the client has no preference.
If the surface has a buffer_scale greater than 1, the compositor
may choose a mode that matches either the buffer size or the
surface size. In either case, the surface will fill the output.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="output" type="object" interface="wl_output"/>
<arg name="framerate" type="int"/>
<arg name="feedback" type="new_id" interface="wl_fullscreen_shell_mode_feedback"/>
</request>
<enum name="error">
<description summary="wl_fullscreen_shell error values">
These errors can be emitted in response to wl_fullscreen_shell requests
</description>
<entry name="invalid_method" value="0" summary="present_method is not known"/>
</enum>
</interface>
<interface name="wl_fullscreen_shell_mode_feedback" version="1">
<event name="mode_successful">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation was
successful. A surface of the size requested in the mode switch
will fill the output without scaling.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="mode_failed">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation
failed. This may be because the requested output mode is not
possible or it may mean that the compositor does not want to allow
mode switches at this time.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="present_canceled">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation was
canceled. Most likely this is because the client requested a
second mode switch before the first one completed.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
This interface has no destructor protocol, so the server cannot know
when it gets destroyed by the client. I'm always a bit wary of that,
but here it seems ok, since this is a one-shot feedback object without
any requests. It is short-lived, doesn't take resources in the server
much nor bandwidth when it triggers, so there's no need to ever be able
to cancel it.


Thanks,
pq
Post by Jason Ekstrand
</interface>
</protocol>
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Jason Ekstrand
2014-02-14 17:11:33 UTC
Permalink
Hi Pekka! Thanks for the review. Comments follow.
Post by Pekka Paalanen
Hi Jason
On Thu, 13 Feb 2014 22:37:53 -0600
Post by Jason Ekstrand
The following is yet another take on the fullscreen shell protocol.
Previous versions more-or-less followed the approach taken in wl_shell.
This version completely reworks the concept. In particular, the protocol
is split into two use-cases. The first is that of a simple client that
wants to present a surface or set of surfaces possibly with some scaling.
This happens through the present_surface request which looks similar to
that of wl_shell only without the modesetting.
The second use-case is of a client that wants more control over the
outputs. In this case, the client uses the present_surface_for_mode
request to present the surface at a particular output mode. This request
provides a more-or-less atomic modeset operation. If the compositor can
satisfy the requested mode, then the mode is changed and the new surface
is
Post by Jason Ekstrand
presented. Otherwise, the compositor harmlessly falls back to the
previously presented surface and the client is informed that the switch
failed. This way, the surface is either displayed correctly or not at
all.
Post by Jason Ekstrand
Of course, a client is free to call present_surface_for_mode with the
currently presented surface and hope for the best. However, this may
result in strange behavior and there is no reliable fallback if the mode
switch fails.
In particular, I would like feedback on the modesetting portion of this
protocol. This is particularly targetted at compositors that want to run
inside weston or some other fullscreen compositor. In the next week or
so,
Post by Jason Ekstrand
I will attempt to implement all this in weston and see how well it works.
However, I would also like to know how well this will work for other
compositors such as KWin or Hawaii.
Thanks for your feedback,
--Jason Ekstrand
===== Protocol follows: =====
<protocol name="fullscreen_shell">
<interface name="wl_fullscreen_shell" version="1">
This interface should have a destructor request IMO. It's not stricly
required, but I think it would be consistent (I think all global
interfaces need an explicit destructor request) and more future-proof.
Thanks for reminding me. I'll get one added.
Post by Pekka Paalanen
Post by Jason Ekstrand
<description summary="Displays a single surface per output">
Displays a single surface per output.
This interface provides a mechanism for a single client to display
simple full-screen surfaces. While there technically may be
multiple
Post by Jason Ekstrand
clients bound to this interface, only one of those clients should
be
Post by Jason Ekstrand
shown at a time.
To present a surface, the client uses either the present_surface or
present_surface_for_mode requests. Presenting a surface takes
effect
Post by Jason Ekstrand
on the next wl_surface.commit. See the individual requests for
details about scaling and mode switches.
The client can have at most one surface per output at any time.
Requesting a surface be presented on an output that already has a
surface replaces the previously presented surface. Presenting a
null
Post by Jason Ekstrand
surface removes its content and effectively disables the output.
Exactly what happens when an output is "disabled" is
compositor-specific. The same surface may be presented multiple
outputs simultaneously.
If the same surface is presented on multiple outputs, should the client
have a way to say which output is to be considered the surface's main
output, where e.g. presentation feedback is synced to?
That's a good question. Simple clients probably don't care. More complex
clients such as compositors probably will. However, I'd expect them to
have one surface per output most of the time anyway. I'll give that some
thought.
Post by Pekka Paalanen
Maybe also note explicitly, that once a surface has been presented on
an output, it stays on that output until explicitly removed, or output
is unplugged? So that simple attach+damage+commit can be used to update
the content, if that is the intention.
Yes, that's a good point. And I do intend to provide that guarantee.
Post by Pekka Paalanen
Post by Jason Ekstrand
</description>
<enum name="present_method">
<description summary="different method to set the surface
fullscreen">
Post by Jason Ekstrand
Hints to indicate to the compositor how to deal with a conflict
between the dimensions of the surface and the dimensions of the
output. The compositor is free to ignore this parameter.
</description>
<entry name="default" value="0" summary="no preference, apply
default policy"/>
Post by Jason Ekstrand
<entry name="center" value="1" summary="center the surface on the
output"/>
Post by Jason Ekstrand
<entry name="zoom" value="2" summary="scale the surface,
preserving aspect ratio, to the largest size that will fit on the output" />
Post by Jason Ekstrand
<entry name="zoom_crop" value="3" summary="scale the surface,
preserving aspect ratio, to fully fill the output cropping if needed" />
Post by Jason Ekstrand
<entry name="stretch" value="4" summary="scale the surface to the
size of the output ignoring aspect ratio" />
Post by Jason Ekstrand
</enum>
<request name="present_surface">
<description summary="present surface for display">
Present a surface on the given output.
If the output is null, the compositor will present the surface on
whatever display (or displays) it thinks best. In particular, this
may replace any or all surfaces currently presented so it should
not be used in combination with placing surfaces on specific
outputs.
The method parameter is a hit to the compositor for how the surface
*hint
Thanks
Post by Pekka Paalanen
Post by Jason Ekstrand
is to be presented. In particular, it tells the compostior how to
handle a size mismatch between the presented surface and the
output. The compositor is free to ignore this parameter.
The "zoom", "zoom_crop", and "stretch" methods imply a scaling
operation on the surface. This will override any kind of output
scaling, so the buffer_scale property of the surface is effectively
ignored.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="method" type="uint"/>
<arg name="output" type="object" interface="wl_output"
allow-null="true"/>
Post by Jason Ekstrand
</request>
<request name="present_surface_for_mode">
<description summary="present surface for display at a particular
mode">
Post by Jason Ekstrand
Presents a surface on the given output for a particular mode.
If the current size of the output differs from that of the surface,
the compositor will attempt to change the size of the output to
match the surface. The result of the mode-swith operation will be
returned via the provided wl_fullscreen_shell_mode_feedback object.
Is it sufficient to infer the mode from the buffer size, or could there
be use cases for forcing a particular mode and scaling a buffer from a
different size?
If you had a separate "set_mode" request, you could do with only the
"present_surface" request for setting the surface.
Hehe. That was my original thought on the matter. Later, I thought better
of it. I'll have more comments on the matter at the end.
Post by Pekka Paalanen
Taking this idea further, like atomic mode setting over all outputs,
we're getting pretty close to the DRM KMS APIs. Would it make sense to
model these interfaces according to the KMS APIs but sanitized to offer
all the modern features like atomic modeset and planes in a clean
uniform way, or do you intentionally want to keep this protocol
interface simple and not e.g. consider planes explicitly?
I'll take a look at KMS. However, I think planes are better left to
subsurfaces. More on that below.
Post by Pekka Paalanen
Post by Jason Ekstrand
If the current output mode matches the one requested or if the
compositor successfully switches the mode to match the surface,
then the mode_successfull event will be sent and the output will
contain the contents of the given surface. If the compositor
cannot match the output size to the surface size, the mode_failed
will be sent and the output will contain the contents of the
previously presented surface (if any). If another surface is
presented on the given output before either of these has a chance
to happen, the present_canceled event will be sent.
If the size of the presented surface changes, the resulting output
is undefined. The compositor may attempt to change the output mode
to compensate. However, there is no guarantee that a suitable mode
will be found and the client has no way to be notified of success
or failure.
The above sounds to me like you want the client be in explicit control
of the video mode when it asks one, without the server fuzzing in
between with scaling.
With an explicit "set_mode" request, I think you could make the above
cases defined.
How much control do you want to give to the client? Apparently you want
the two different cases: simple client, smart server; and smart client
with explicit mode setting, simple server just obeying or refusing
without any fuzz.
Pretty much. Again, read below.
Post by Pekka Paalanen
Post by Jason Ekstrand
The framerate parameter specifies the target framerate for the
output. The compositor is free to ignore this parameter. A value
of 0 indicates that the client has no preference.
If the surface has a buffer_scale greater than 1, the compositor
may choose a mode that matches either the buffer size or the
surface size. In either case, the surface will fill the output.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="output" type="object" interface="wl_output"/>
<arg name="framerate" type="int"/>
<arg name="feedback" type="new_id"
interface="wl_fullscreen_shell_mode_feedback"/>
Post by Jason Ekstrand
</request>
<enum name="error">
<description summary="wl_fullscreen_shell error values">
These errors can be emitted in response to wl_fullscreen_shell
requests
Post by Jason Ekstrand
</description>
<entry name="invalid_method" value="0" summary="present_method is
not known"/>
Post by Jason Ekstrand
</enum>
</interface>
<interface name="wl_fullscreen_shell_mode_feedback" version="1">
<event name="mode_successful">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation was
successful. A surface of the size requested in the mode switch
will fill the output without scaling.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="mode_failed">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation
failed. This may be because the requested output mode is not
possible or it may mean that the compositor does not want to allow
mode switches at this time.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="present_canceled">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation was
canceled. Most likely this is because the client requested a
second mode switch before the first one completed.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
This interface has no destructor protocol, so the server cannot know
when it gets destroyed by the client. I'm always a bit wary of that,
but here it seems ok, since this is a one-shot feedback object without
any requests. It is short-lived, doesn't take resources in the server
much nor bandwidth when it triggers, so there's no need to ever be able
to cancel it.
Yeah, I thought about having a destructor but it's intentionally a one-shot
and that just adds more protocol noise for little benefit. Maybe it's a
good idea, but I don't think it's needed.

Ok, now for the promised "more detail"...

When designing this interface, I have three primary use-cases in mind:

1) Simple clients such as splash screens and terminal emulators. These
would rather not mess with KMS and, in a world without VT's, need some way
to get to the screen. I want to provide a simple but powerful enough
interface to serve these clients.

2) Full compositors such as KWin that would rather not deal with KMS
themselves but would prefer to let Weston or some other implementation
handle it. In this case, we want more fine-grained control and we want
things like planes, cursors, etc.

3) Other non-KMS "backends" such as VNC/RDP servers, screen recorders, or
anything else where it may not be practical to implement full DRM/KMS.

As you surmised, the first request is to handle the first of these
use-cases and the second request is for the other two. Breaking it into
two completely separate cases was a deliberate decision. Maybe not the
right one, but deliberate none the less. Allow me to explain.

First, I think that planes and the like are already pretty-well covered by
wl_subsurface and wl_viewport. There's no reason for me to duplicate that
protocol here if it's already covered by those. This may not map
perfectly, but I think it will cover well enough for most cases. Axel,
this also covers cursors and the like.

Second, I wanted to ensure that things were atomic. By having presentation
explicitly tied to mode set, we can ensure this. There is the issue of the
fallback not being atomic. One solution to this would be to have a
fallback mode option so if it can't find a mode it will scale or something.
However, I would rather clients pick one interface and stick with it than
switching between the two. I thought about splitting it into a set_mode
request and a present_surface request. However, a) it's harder (not
impossible) to make this atomic and b) it makes the compositor's life more
difficult (see next paragraph). If they want scaling+modeset, they can
just use a wl_viewport.

Third, I want to allow VNC/RDP-type compositors to be as simple as
possible. If they don't provide wl_subsurface and wl_viewport then they
don't have to do any real composting. They still have to handle the first
request but that's easily enough done with pixman or similar. Also, it
explicitly states that they can ignore the method parameter and just always
center the surface or something. For the present_for_mode request, it
means that they can always do a direct pixel copy from the source to the
destination (or directly flip in the case of DRM/KMS). By requiring the
surface and output size to match, it takes a lot of the guesswork out of
the mode switches.

I hope that makes my thinking on this whole protocol more clear. Thanks
for reviewing; I look forward to any future comments you may have!
--Jason Ekstrand
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20140214/c7b4d98f/attachment-0001.html>
Pekka Paalanen
2014-02-15 07:12:09 UTC
Permalink
On Fri, 14 Feb 2014 11:11:33 -0600
Post by Jason Ekstrand
Hi Pekka! Thanks for the review. Comments follow.
On Fri, Feb 14, 2014 at 1:14 AM, Pekka Paalanen
Post by Pekka Paalanen
Hi Jason
On Thu, 13 Feb 2014 22:37:53 -0600
Post by Jason Ekstrand
The following is yet another take on the fullscreen shell
protocol. Previous versions more-or-less followed the
approach taken in wl_shell. This version completely reworks
the concept. In particular, the protocol is split into two
use-cases. The first is that of a simple client that wants
to present a surface or set of surfaces possibly with some
scaling. This happens through the present_surface request
which looks similar to that of wl_shell only without the
modesetting.
The second use-case is of a client that wants more control
over the outputs. In this case, the client uses the
present_surface_for_mode request to present the surface at a
particular output mode. This request provides a more-or-less
atomic modeset operation. If the compositor can satisfy the
requested mode, then the mode is changed and the new surface
is
Post by Jason Ekstrand
presented. Otherwise, the compositor harmlessly falls back
to the previously presented surface and the client is
informed that the switch failed. This way, the surface is
either displayed correctly or not at
all.
Post by Jason Ekstrand
Of course, a client is free to call present_surface_for_mode
with the currently presented surface and hope for the best.
However, this may result in strange behavior and there is no
reliable fallback if the mode switch fails.
In particular, I would like feedback on the modesetting
portion of this protocol. This is particularly targetted at
compositors that want to run inside weston or some other
fullscreen compositor. In the next week or
so,
Post by Jason Ekstrand
I will attempt to implement all this in weston and see how
well it works. However, I would also like to know how well
this will work for other compositors such as KWin or Hawaii.
Thanks for your feedback,
--Jason Ekstrand
===== Protocol follows: =====
<protocol name="fullscreen_shell">
<interface name="wl_fullscreen_shell" version="1">
This interface should have a destructor request IMO. It's not
stricly required, but I think it would be consistent (I think
all global interfaces need an explicit destructor request) and
more future-proof.
Thanks for reminding me. I'll get one added.
Post by Pekka Paalanen
Post by Jason Ekstrand
<description summary="Displays a single surface per
output"> Displays a single surface per output.
This interface provides a mechanism for a single client
to display simple full-screen surfaces. While there
technically may be
multiple
Post by Jason Ekstrand
clients bound to this interface, only one of those
clients should
be
Post by Jason Ekstrand
shown at a time.
To present a surface, the client uses either the
present_surface or present_surface_for_mode requests.
Presenting a surface takes
effect
Post by Jason Ekstrand
on the next wl_surface.commit. See the individual
requests for details about scaling and mode switches.
The client can have at most one surface per output at
any time. Requesting a surface be presented on an output that
already has a surface replaces the previously presented
surface. Presenting a
null
Post by Jason Ekstrand
surface removes its content and effectively disables
the output. Exactly what happens when an output is "disabled"
is compositor-specific. The same surface may be presented
multiple outputs simultaneously.
If the same surface is presented on multiple outputs, should
the client have a way to say which output is to be considered
the surface's main output, where e.g. presentation feedback is
synced to?
That's a good question. Simple clients probably don't care.
More complex clients such as compositors probably will. However,
I'd expect them to have one surface per output most of the time
anyway. I'll give that some thought.
Post by Pekka Paalanen
Maybe also note explicitly, that once a surface has been
presented on an output, it stays on that output until
explicitly removed, or output is unplugged? So that simple
attach+damage+commit can be used to update the content, if that
is the intention.
Yes, that's a good point. And I do intend to provide that
guarantee.
Post by Pekka Paalanen
Post by Jason Ekstrand
</description>
<enum name="present_method">
<description summary="different method to set the
surface
fullscreen">
Post by Jason Ekstrand
Hints to indicate to the compositor how to deal with a
conflict between the dimensions of the surface and the
dimensions of the output. The compositor is free to ignore
this parameter. </description>
<entry name="default" value="0" summary="no preference, apply
default policy"/>
Post by Jason Ekstrand
<entry name="center" value="1" summary="center the
surface on the
output"/>
Post by Jason Ekstrand
<entry name="zoom" value="2" summary="scale the surface,
preserving aspect ratio, to the largest size that will fit on the output" />
Post by Jason Ekstrand
<entry name="zoom_crop" value="3" summary="scale the
surface,
preserving aspect ratio, to fully fill the output cropping if needed" />
Post by Jason Ekstrand
<entry name="stretch" value="4" summary="scale the
surface to the
size of the output ignoring aspect ratio" />
Post by Jason Ekstrand
</enum>
<request name="present_surface">
<description summary="present surface for display">
Present a surface on the given output.
If the output is null, the compositor will present the
surface on whatever display (or displays) it thinks best. In
particular, this may replace any or all surfaces currently
presented so it should not be used in combination with
placing surfaces on specific outputs.
The method parameter is a hit to the compositor for how the surface
*hint
Thanks
Post by Pekka Paalanen
Post by Jason Ekstrand
is to be presented. In particular, it tells the
compostior how to handle a size mismatch between the
presented surface and the output. The compositor is free to
ignore this parameter.
The "zoom", "zoom_crop", and "stretch" methods imply a
scaling operation on the surface. This will override any
kind of output scaling, so the buffer_scale property of the
surface is effectively ignored.
</description>
<arg name="surface" type="object"
interface="wl_surface"/> <arg name="method" type="uint"/>
<arg name="output" type="object" interface="wl_output"
allow-null="true"/>
Post by Jason Ekstrand
</request>
<request name="present_surface_for_mode">
<description summary="present surface for display at a particular
mode">
Post by Jason Ekstrand
Presents a surface on the given output for a particular mode.
If the current size of the output differs from that of
the surface, the compositor will attempt to change the size
of the output to match the surface. The result of the
mode-swith operation will be returned via the provided
wl_fullscreen_shell_mode_feedback object.
Is it sufficient to infer the mode from the buffer size, or
could there be use cases for forcing a particular mode and
scaling a buffer from a different size?
If you had a separate "set_mode" request, you could do with
only the "present_surface" request for setting the surface.
Hehe. That was my original thought on the matter. Later, I
thought better of it. I'll have more comments on the matter at
the end.
Post by Pekka Paalanen
Taking this idea further, like atomic mode setting over all
outputs, we're getting pretty close to the DRM KMS APIs. Would
it make sense to model these interfaces according to the KMS
APIs but sanitized to offer all the modern features like atomic
modeset and planes in a clean uniform way, or do you
intentionally want to keep this protocol interface simple and
not e.g. consider planes explicitly?
I'll take a look at KMS. However, I think planes are better left
to subsurfaces. More on that below.
Post by Pekka Paalanen
Post by Jason Ekstrand
If the current output mode matches the one requested or
if the compositor successfully switches the mode to match the
surface, then the mode_successfull event will be sent and the
output will contain the contents of the given surface. If
the compositor cannot match the output size to the surface
size, the mode_failed will be sent and the output will
contain the contents of the previously presented surface (if
any). If another surface is presented on the given output
before either of these has a chance to happen, the
present_canceled event will be sent.
If the size of the presented surface changes, the
resulting output is undefined. The compositor may attempt to
change the output mode to compensate. However, there is no
guarantee that a suitable mode will be found and the client
has no way to be notified of success or failure.
The above sounds to me like you want the client be in explicit
control of the video mode when it asks one, without the server
fuzzing in between with scaling.
With an explicit "set_mode" request, I think you could make the
above cases defined.
How much control do you want to give to the client? Apparently
you want the two different cases: simple client, smart server;
and smart client with explicit mode setting, simple server just
obeying or refusing without any fuzz.
Pretty much. Again, read below.
Post by Pekka Paalanen
Post by Jason Ekstrand
The framerate parameter specifies the target framerate
for the output. The compositor is free to ignore this
parameter. A value of 0 indicates that the client has no
preference.
If the surface has a buffer_scale greater than 1, the
compositor may choose a mode that matches either the buffer
size or the surface size. In either case, the surface will
fill the output. </description>
<arg name="surface" type="object"
interface="wl_surface"/> <arg name="output" type="object"
interface="wl_output"/> <arg name="framerate" type="int"/>
<arg name="feedback" type="new_id"
interface="wl_fullscreen_shell_mode_feedback"/>
Post by Jason Ekstrand
</request>
<enum name="error">
<description summary="wl_fullscreen_shell error values">
These errors can be emitted in response to
wl_fullscreen_shell
requests
Post by Jason Ekstrand
</description>
<entry name="invalid_method" value="0"
summary="present_method is
not known"/>
Post by Jason Ekstrand
</enum>
</interface>
<interface name="wl_fullscreen_shell_mode_feedback"
version="1"> <event name="mode_successful">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch
operation was successful. A surface of the size requested in
the mode switch will fill the output without scaling.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="mode_failed">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch
operation failed. This may be because the requested output
mode is not possible or it may mean that the compositor does
not want to allow mode switches at this time.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="present_canceled">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch
operation was canceled. Most likely this is because the
client requested a second mode switch before the first one
completed.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
This interface has no destructor protocol, so the server cannot
know when it gets destroyed by the client. I'm always a bit
wary of that, but here it seems ok, since this is a one-shot
feedback object without any requests. It is short-lived,
doesn't take resources in the server much nor bandwidth when it
triggers, so there's no need to ever be able to cancel it.
Yeah, I thought about having a destructor but it's intentionally
a one-shot and that just adds more protocol noise for little
benefit. Maybe it's a good idea, but I don't think it's needed.
Ok, now for the promised "more detail"...
1) Simple clients such as splash screens and terminal emulators.
These would rather not mess with KMS and, in a world without
VT's, need some way to get to the screen. I want to provide a
simple but powerful enough interface to serve these clients.
2) Full compositors such as KWin that would rather not deal with
KMS themselves but would prefer to let Weston or some other
implementation handle it. In this case, we want more
fine-grained control and we want things like planes, cursors, etc.
3) Other non-KMS "backends" such as VNC/RDP servers, screen
recorders, or anything else where it may not be practical to
implement full DRM/KMS.
As you surmised, the first request is to handle the first of these
use-cases and the second request is for the other two. Breaking
it into two completely separate cases was a deliberate decision.
Maybe not the right one, but deliberate none the less. Allow me
to explain.
First, I think that planes and the like are already pretty-well
covered by wl_subsurface and wl_viewport. There's no reason for
me to duplicate that protocol here if it's already covered by
those. This may not map perfectly, but I think it will cover
well enough for most cases. Axel, this also covers cursors and
the like.
Hi,

the sub-surface approach for planes has one complication. If your
fullscreen-compositor is the one making all decisions about hw
plane usage and never exposing any details of them to the
child-compositor, then the child-compositor must always forward all
surfaces as sub-surfaces to give the fullscreen-compositor a chance
to use all planes. If the child-compositor composites itself, it
excludes some opportunities to use hw planes.

Is the cost of forwarding all surfaces into sub-surfaces
significant? I don't really know. Is it your intended way of
working?

It certainly does make the protocol simple and easy to use.
Post by Jason Ekstrand
Second, I wanted to ensure that things were atomic. By having
presentation explicitly tied to mode set, we can ensure this.
There is the issue of the fallback not being atomic. One
solution to this would be to have a fallback mode option so if it
can't find a mode it will scale or something. However, I would
rather clients pick one interface and stick with it than
switching between the two. I thought about splitting it into a
set_mode request and a present_surface request. However, a) it's
harder (not impossible) to make this atomic and b) it makes the
compositor's life more difficult (see next paragraph). If they
want scaling+modeset, they can just use a wl_viewport.
Sorry, perhaps I wasn't clear. I meant to keep your semantics the
same, mode set being triggered on wl_surface.commit. The set_mode
request would be just the mode set part of your
present_surface_for_mode. Atomicity would be exactly the same. That
way you could replace present_surface_for_mode with a pair of
set_mode and present_surface, and have the very same result.
Post by Jason Ekstrand
Third, I want to allow VNC/RDP-type compositors to be as simple as
possible. If they don't provide wl_subsurface and wl_viewport
then they don't have to do any real composting. They still have
to handle the first request but that's easily enough done with
pixman or similar. Also, it explicitly states that they can
ignore the method parameter and just always center the surface or
something. For the present_for_mode request, it means that they
can always do a direct pixel copy from the source to the
destination (or directly flip in the case of DRM/KMS). By
requiring the surface and output size to match, it takes a lot of
the guesswork out of the mode switches.
You could still keep those semantics too, I guess, but now I
realize that you indeed do not have the "method" argument for
present_surface_for_mode. Yes, your design makes sense.
Post by Jason Ekstrand
I hope that makes my thinking on this whole protocol more clear.
Thanks for reviewing; I look forward to any future comments you
may have! --Jason Ekstrand
Sure!

Thanks,
pq
Jason Ekstrand
2014-02-18 04:28:01 UTC
Permalink
I just added an implementation of RFCv4 which can be found here:

https://github.com/jekstrand/weston/tree/fullscreen-shell-RFCv4

Thanks,
--Jason Ekstrand
Post by Pekka Paalanen
On Fri, 14 Feb 2014 11:11:33 -0600
Post by Jason Ekstrand
Hi Pekka! Thanks for the review. Comments follow.
On Fri, Feb 14, 2014 at 1:14 AM, Pekka Paalanen
Post by Pekka Paalanen
Hi Jason
On Thu, 13 Feb 2014 22:37:53 -0600
Post by Jason Ekstrand
The following is yet another take on the fullscreen shell
protocol. Previous versions more-or-less followed the
approach taken in wl_shell. This version completely reworks
the concept. In particular, the protocol is split into two
use-cases. The first is that of a simple client that wants
to present a surface or set of surfaces possibly with some
scaling. This happens through the present_surface request
which looks similar to that of wl_shell only without the
modesetting.
The second use-case is of a client that wants more control
over the outputs. In this case, the client uses the
present_surface_for_mode request to present the surface at a
particular output mode. This request provides a more-or-less
atomic modeset operation. If the compositor can satisfy the
requested mode, then the mode is changed and the new surface
is
Post by Jason Ekstrand
presented. Otherwise, the compositor harmlessly falls back
to the previously presented surface and the client is
informed that the switch failed. This way, the surface is
either displayed correctly or not at
all.
Post by Jason Ekstrand
Of course, a client is free to call present_surface_for_mode
with the currently presented surface and hope for the best.
However, this may result in strange behavior and there is no
reliable fallback if the mode switch fails.
In particular, I would like feedback on the modesetting
portion of this protocol. This is particularly targetted at
compositors that want to run inside weston or some other
fullscreen compositor. In the next week or
so,
Post by Jason Ekstrand
I will attempt to implement all this in weston and see how
well it works. However, I would also like to know how well
this will work for other compositors such as KWin or Hawaii.
Thanks for your feedback,
--Jason Ekstrand
===== Protocol follows: =====
<protocol name="fullscreen_shell">
<interface name="wl_fullscreen_shell" version="1">
This interface should have a destructor request IMO. It's not
stricly required, but I think it would be consistent (I think
all global interfaces need an explicit destructor request) and
more future-proof.
Thanks for reminding me. I'll get one added.
Post by Pekka Paalanen
Post by Jason Ekstrand
<description summary="Displays a single surface per
output"> Displays a single surface per output.
This interface provides a mechanism for a single client
to display simple full-screen surfaces. While there
technically may be
multiple
Post by Jason Ekstrand
clients bound to this interface, only one of those
clients should
be
Post by Jason Ekstrand
shown at a time.
To present a surface, the client uses either the
present_surface or present_surface_for_mode requests.
Presenting a surface takes
effect
Post by Jason Ekstrand
on the next wl_surface.commit. See the individual
requests for details about scaling and mode switches.
The client can have at most one surface per output at
any time. Requesting a surface be presented on an output that
already has a surface replaces the previously presented
surface. Presenting a
null
Post by Jason Ekstrand
surface removes its content and effectively disables
the output. Exactly what happens when an output is "disabled"
is compositor-specific. The same surface may be presented
multiple outputs simultaneously.
If the same surface is presented on multiple outputs, should
the client have a way to say which output is to be considered
the surface's main output, where e.g. presentation feedback is
synced to?
That's a good question. Simple clients probably don't care.
More complex clients such as compositors probably will. However,
I'd expect them to have one surface per output most of the time
anyway. I'll give that some thought.
Post by Pekka Paalanen
Maybe also note explicitly, that once a surface has been
presented on an output, it stays on that output until
explicitly removed, or output is unplugged? So that simple
attach+damage+commit can be used to update the content, if that
is the intention.
Yes, that's a good point. And I do intend to provide that
guarantee.
Post by Pekka Paalanen
Post by Jason Ekstrand
</description>
<enum name="present_method">
<description summary="different method to set the
surface
fullscreen">
Post by Jason Ekstrand
Hints to indicate to the compositor how to deal with a
conflict between the dimensions of the surface and the
dimensions of the output. The compositor is free to ignore
this parameter. </description>
<entry name="default" value="0" summary="no preference, apply
default policy"/>
Post by Jason Ekstrand
<entry name="center" value="1" summary="center the
surface on the
output"/>
Post by Jason Ekstrand
<entry name="zoom" value="2" summary="scale the surface,
preserving aspect ratio, to the largest size that will fit on the output" />
Post by Jason Ekstrand
<entry name="zoom_crop" value="3" summary="scale the surface,
preserving aspect ratio, to fully fill the output cropping if needed" />
Post by Jason Ekstrand
<entry name="stretch" value="4" summary="scale the
surface to the
size of the output ignoring aspect ratio" />
Post by Jason Ekstrand
</enum>
<request name="present_surface">
<description summary="present surface for display">
Present a surface on the given output.
If the output is null, the compositor will present the
surface on whatever display (or displays) it thinks best. In
particular, this may replace any or all surfaces currently
presented so it should not be used in combination with
placing surfaces on specific outputs.
The method parameter is a hit to the compositor for how the surface
*hint
Thanks
Post by Pekka Paalanen
Post by Jason Ekstrand
is to be presented. In particular, it tells the
compostior how to handle a size mismatch between the
presented surface and the output. The compositor is free to
ignore this parameter.
The "zoom", "zoom_crop", and "stretch" methods imply a
scaling operation on the surface. This will override any
kind of output scaling, so the buffer_scale property of the
surface is effectively ignored.
</description>
<arg name="surface" type="object"
interface="wl_surface"/> <arg name="method" type="uint"/>
<arg name="output" type="object" interface="wl_output"
allow-null="true"/>
Post by Jason Ekstrand
</request>
<request name="present_surface_for_mode">
<description summary="present surface for display at a particular
mode">
Post by Jason Ekstrand
Presents a surface on the given output for a particular mode.
If the current size of the output differs from that of
the surface, the compositor will attempt to change the size
of the output to match the surface. The result of the
mode-swith operation will be returned via the provided
wl_fullscreen_shell_mode_feedback object.
Is it sufficient to infer the mode from the buffer size, or
could there be use cases for forcing a particular mode and
scaling a buffer from a different size?
If you had a separate "set_mode" request, you could do with
only the "present_surface" request for setting the surface.
Hehe. That was my original thought on the matter. Later, I
thought better of it. I'll have more comments on the matter at
the end.
Post by Pekka Paalanen
Taking this idea further, like atomic mode setting over all
outputs, we're getting pretty close to the DRM KMS APIs. Would
it make sense to model these interfaces according to the KMS
APIs but sanitized to offer all the modern features like atomic
modeset and planes in a clean uniform way, or do you
intentionally want to keep this protocol interface simple and
not e.g. consider planes explicitly?
I'll take a look at KMS. However, I think planes are better left
to subsurfaces. More on that below.
Post by Pekka Paalanen
Post by Jason Ekstrand
If the current output mode matches the one requested or
if the compositor successfully switches the mode to match the
surface, then the mode_successfull event will be sent and the
output will contain the contents of the given surface. If
the compositor cannot match the output size to the surface
size, the mode_failed will be sent and the output will
contain the contents of the previously presented surface (if
any). If another surface is presented on the given output
before either of these has a chance to happen, the
present_canceled event will be sent.
If the size of the presented surface changes, the
resulting output is undefined. The compositor may attempt to
change the output mode to compensate. However, there is no
guarantee that a suitable mode will be found and the client
has no way to be notified of success or failure.
The above sounds to me like you want the client be in explicit
control of the video mode when it asks one, without the server
fuzzing in between with scaling.
With an explicit "set_mode" request, I think you could make the
above cases defined.
How much control do you want to give to the client? Apparently
you want the two different cases: simple client, smart server;
and smart client with explicit mode setting, simple server just
obeying or refusing without any fuzz.
Pretty much. Again, read below.
Post by Pekka Paalanen
Post by Jason Ekstrand
The framerate parameter specifies the target framerate
for the output. The compositor is free to ignore this
parameter. A value of 0 indicates that the client has no
preference.
If the surface has a buffer_scale greater than 1, the
compositor may choose a mode that matches either the buffer
size or the surface size. In either case, the surface will
fill the output. </description>
<arg name="surface" type="object"
interface="wl_surface"/> <arg name="output" type="object"
interface="wl_output"/> <arg name="framerate" type="int"/>
<arg name="feedback" type="new_id"
interface="wl_fullscreen_shell_mode_feedback"/>
Post by Jason Ekstrand
</request>
<enum name="error">
<description summary="wl_fullscreen_shell error values">
These errors can be emitted in response to
wl_fullscreen_shell
requests
Post by Jason Ekstrand
</description>
<entry name="invalid_method" value="0"
summary="present_method is
not known"/>
Post by Jason Ekstrand
</enum>
</interface>
<interface name="wl_fullscreen_shell_mode_feedback"
version="1"> <event name="mode_successful">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch
operation was successful. A surface of the size requested in
the mode switch will fill the output without scaling.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="mode_failed">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch
operation failed. This may be because the requested output
mode is not possible or it may mean that the compositor does
not want to allow mode switches at this time.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="present_canceled">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch
operation was canceled. Most likely this is because the
client requested a second mode switch before the first one
completed.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
This interface has no destructor protocol, so the server cannot
know when it gets destroyed by the client. I'm always a bit
wary of that, but here it seems ok, since this is a one-shot
feedback object without any requests. It is short-lived,
doesn't take resources in the server much nor bandwidth when it
triggers, so there's no need to ever be able to cancel it.
Yeah, I thought about having a destructor but it's intentionally
a one-shot and that just adds more protocol noise for little
benefit. Maybe it's a good idea, but I don't think it's needed.
Ok, now for the promised "more detail"...
1) Simple clients such as splash screens and terminal emulators.
These would rather not mess with KMS and, in a world without
VT's, need some way to get to the screen. I want to provide a
simple but powerful enough interface to serve these clients.
2) Full compositors such as KWin that would rather not deal with
KMS themselves but would prefer to let Weston or some other
implementation handle it. In this case, we want more
fine-grained control and we want things like planes, cursors, etc.
3) Other non-KMS "backends" such as VNC/RDP servers, screen
recorders, or anything else where it may not be practical to
implement full DRM/KMS.
As you surmised, the first request is to handle the first of these
use-cases and the second request is for the other two. Breaking
it into two completely separate cases was a deliberate decision.
Maybe not the right one, but deliberate none the less. Allow me
to explain.
First, I think that planes and the like are already pretty-well
covered by wl_subsurface and wl_viewport. There's no reason for
me to duplicate that protocol here if it's already covered by
those. This may not map perfectly, but I think it will cover
well enough for most cases. Axel, this also covers cursors and
the like.
Hi,
the sub-surface approach for planes has one complication. If your
fullscreen-compositor is the one making all decisions about hw
plane usage and never exposing any details of them to the
child-compositor, then the child-compositor must always forward all
surfaces as sub-surfaces to give the fullscreen-compositor a chance
to use all planes. If the child-compositor composites itself, it
excludes some opportunities to use hw planes.
Is the cost of forwarding all surfaces into sub-surfaces
significant? I don't really know. Is it your intended way of
working?
It certainly does make the protocol simple and easy to use.
Post by Jason Ekstrand
Second, I wanted to ensure that things were atomic. By having
presentation explicitly tied to mode set, we can ensure this.
There is the issue of the fallback not being atomic. One
solution to this would be to have a fallback mode option so if it
can't find a mode it will scale or something. However, I would
rather clients pick one interface and stick with it than
switching between the two. I thought about splitting it into a
set_mode request and a present_surface request. However, a) it's
harder (not impossible) to make this atomic and b) it makes the
compositor's life more difficult (see next paragraph). If they
want scaling+modeset, they can just use a wl_viewport.
Sorry, perhaps I wasn't clear. I meant to keep your semantics the
same, mode set being triggered on wl_surface.commit. The set_mode
request would be just the mode set part of your
present_surface_for_mode. Atomicity would be exactly the same. That
way you could replace present_surface_for_mode with a pair of
set_mode and present_surface, and have the very same result.
Post by Jason Ekstrand
Third, I want to allow VNC/RDP-type compositors to be as simple as
possible. If they don't provide wl_subsurface and wl_viewport
then they don't have to do any real composting. They still have
to handle the first request but that's easily enough done with
pixman or similar. Also, it explicitly states that they can
ignore the method parameter and just always center the surface or
something. For the present_for_mode request, it means that they
can always do a direct pixel copy from the source to the
destination (or directly flip in the case of DRM/KMS). By
requiring the surface and output size to match, it takes a lot of
the guesswork out of the mode switches.
You could still keep those semantics too, I guess, but now I
realize that you indeed do not have the "method" argument for
present_surface_for_mode. Yes, your design makes sense.
Post by Jason Ekstrand
I hope that makes my thinking on this whole protocol more clear.
Thanks for reviewing; I look forward to any future comments you
may have! --Jason Ekstrand
Sure!
Thanks,
pq
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20140217/f35d4003/attachment-0001.html>
Axel Davy
2014-02-14 11:29:46 UTC
Permalink
Post by Jason Ekstrand
The following is yet another take on the fullscreen shell protocol.
If the client manages the inpust, it would likely want to use the
display ability to draw cursors.

Thus your interface should integrate a way to create a cursor, and
choose its location/sprite (and should take into account there could be
several cursors).

Axel Davy
Jonas Ådahl
2014-02-24 22:03:13 UTC
Permalink
Post by Jason Ekstrand
The following is yet another take on the fullscreen shell protocol.
Previous versions more-or-less followed the approach taken in wl_shell.
This version completely reworks the concept. In particular, the protocol
is split into two use-cases. The first is that of a simple client that
wants to present a surface or set of surfaces possibly with some scaling.
This happens through the present_surface request which looks similar to
that of wl_shell only without the modesetting.
The second use-case is of a client that wants more control over the
outputs. In this case, the client uses the present_surface_for_mode
request to present the surface at a particular output mode. This request
provides a more-or-less atomic modeset operation. If the compositor can
satisfy the requested mode, then the mode is changed and the new surface is
presented. Otherwise, the compositor harmlessly falls back to the
previously presented surface and the client is informed that the switch
failed. This way, the surface is either displayed correctly or not at all.
Of course, a client is free to call present_surface_for_mode with the
currently presented surface and hope for the best. However, this may
result in strange behavior and there is no reliable fallback if the mode
switch fails.
In particular, I would like feedback on the modesetting portion of this
protocol. This is particularly targetted at compositors that want to run
inside weston or some other fullscreen compositor. In the next week or so,
I will attempt to implement all this in weston and see how well it works.
However, I would also like to know how well this will work for other
compositors such as KWin or Hawaii.
Hi Jason,

Some follow up comments from last round inline.
Post by Jason Ekstrand
Thanks for your feedback,
--Jason Ekstrand
===== Protocol follows: =====
<protocol name="fullscreen_shell">
<interface name="wl_fullscreen_shell" version="1">
<description summary="Displays a single surface per output">
Displays a single surface per output.
This interface provides a mechanism for a single client to display
simple full-screen surfaces. While there technically may be multiple
clients bound to this interface, only one of those clients should be
shown at a time.
To present a surface, the client uses either the present_surface or
present_surface_for_mode requests. Presenting a surface takes effect
on the next wl_surface.commit. See the individual requests for
details about scaling and mode switches.
The client can have at most one surface per output at any time.
Requesting a surface be presented on an output that already has a
surface replaces the previously presented surface. Presenting a null
surface removes its content and effectively disables the output.
Exactly what happens when an output is "disabled" is
compositor-specific. The same surface may be presented multiple
outputs simultaneously.
</description>
<enum name="present_method">
<description summary="different method to set the surface fullscreen">
Hints to indicate to the compositor how to deal with a conflict
between the dimensions of the surface and the dimensions of the
output. The compositor is free to ignore this parameter.
</description>
<entry name="default" value="0" summary="no preference, apply default policy"/>
<entry name="center" value="1" summary="center the surface on the output"/>
<entry name="zoom" value="2" summary="scale the surface, preserving aspect ratio, to the largest size that will fit on the output" />
<entry name="zoom_crop" value="3" summary="scale the surface, preserving aspect ratio, to fully fill the output cropping if needed" />
<entry name="stretch" value="4" summary="scale the surface to the size of the output ignoring aspect ratio" />
</enum>
<request name="present_surface">
<description summary="present surface for display">
Present a surface on the given output.
If the output is null, the compositor will present the surface on
whatever display (or displays) it thinks best. In particular, this
may replace any or all surfaces currently presented so it should
not be used in combination with placing surfaces on specific
outputs.
The method parameter is a hit to the compositor for how the surface
is to be presented. In particular, it tells the compostior how to
handle a size mismatch between the presented surface and the
output. The compositor is free to ignore this parameter.
The "zoom", "zoom_crop", and "stretch" methods imply a scaling
operation on the surface. This will override any kind of output
scaling, so the buffer_scale property of the surface is effectively
ignored.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
I think you might be missing an 'allow-null="true"' parameter here, as
you above specify that presenting a null-surface on non-null output
would "disable" that output.

It might also be a good idea to add a note that presenting a
null-surface on a null-output should raise a protocol error as I assume
it should.

Regarding present_surface_for_mode, it is unclear if it is expected
that it will handle null-surface (if you'd add allow-null="true") as one
need to provide a frame rate, while the description doesn't say anything
of what method of presenting has the described effect.


Jonas
Post by Jason Ekstrand
<arg name="method" type="uint"/>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>
<request name="present_surface_for_mode">
<description summary="present surface for display at a particular mode">
Presents a surface on the given output for a particular mode.
If the current size of the output differs from that of the surface,
the compositor will attempt to change the size of the output to
match the surface. The result of the mode-swith operation will be
returned via the provided wl_fullscreen_shell_mode_feedback object.
If the current output mode matches the one requested or if the
compositor successfully switches the mode to match the surface,
then the mode_successfull event will be sent and the output will
contain the contents of the given surface. If the compositor
cannot match the output size to the surface size, the mode_failed
will be sent and the output will contain the contents of the
previously presented surface (if any). If another surface is
presented on the given output before either of these has a chance
to happen, the present_canceled event will be sent.
If the size of the presented surface changes, the resulting output
is undefined. The compositor may attempt to change the output mode
to compensate. However, there is no guarantee that a suitable mode
will be found and the client has no way to be notified of success
or failure.
The framerate parameter specifies the target framerate for the
output. The compositor is free to ignore this parameter. A value
of 0 indicates that the client has no preference.
If the surface has a buffer_scale greater than 1, the compositor
may choose a mode that matches either the buffer size or the
surface size. In either case, the surface will fill the output.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="output" type="object" interface="wl_output"/>
<arg name="framerate" type="int"/>
<arg name="feedback" type="new_id" interface="wl_fullscreen_shell_mode_feedback"/>
</request>
<enum name="error">
<description summary="wl_fullscreen_shell error values">
These errors can be emitted in response to wl_fullscreen_shell requests
</description>
<entry name="invalid_method" value="0" summary="present_method is not known"/>
</enum>
</interface>
<interface name="wl_fullscreen_shell_mode_feedback" version="1">
<event name="mode_successful">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation was
successful. A surface of the size requested in the mode switch
will fill the output without scaling.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="mode_failed">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation
failed. This may be because the requested output mode is not
possible or it may mean that the compositor does not want to allow
mode switches at this time.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="present_canceled">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation was
canceled. Most likely this is because the client requested a
second mode switch before the first one completed.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
</interface>
</protocol>
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Jason Ekstrand
2014-02-25 02:07:06 UTC
Permalink
Jonas, thanks for reviewing.
Post by Jonas Ådahl
Post by Jason Ekstrand
The following is yet another take on the fullscreen shell protocol.
Previous versions more-or-less followed the approach taken in wl_shell.
This version completely reworks the concept. In particular, the protocol
is split into two use-cases. The first is that of a simple client that
wants to present a surface or set of surfaces possibly with some scaling.
This happens through the present_surface request which looks similar to
that of wl_shell only without the modesetting.
The second use-case is of a client that wants more control over the
outputs. In this case, the client uses the present_surface_for_mode
request to present the surface at a particular output mode. This request
provides a more-or-less atomic modeset operation. If the compositor can
satisfy the requested mode, then the mode is changed and the new surface is
presented. Otherwise, the compositor harmlessly falls back to the
previously presented surface and the client is informed that the switch
failed. This way, the surface is either displayed correctly or not at all.
Of course, a client is free to call present_surface_for_mode with the
currently presented surface and hope for the best. However, this may
result in strange behavior and there is no reliable fallback if the mode
switch fails.
In particular, I would like feedback on the modesetting portion of this
protocol. This is particularly targetted at compositors that want to run
inside weston or some other fullscreen compositor. In the next week or so,
I will attempt to implement all this in weston and see how well it works.
However, I would also like to know how well this will work for other
compositors such as KWin or Hawaii.
Hi Jason,
Some follow up comments from last round inline.
Post by Jason Ekstrand
Thanks for your feedback,
--Jason Ekstrand
===== Protocol follows: =====
<protocol name="fullscreen_shell">
<interface name="wl_fullscreen_shell" version="1">
<description summary="Displays a single surface per output">
Displays a single surface per output.
This interface provides a mechanism for a single client to display
simple full-screen surfaces. While there technically may be multiple
clients bound to this interface, only one of those clients should be
shown at a time.
To present a surface, the client uses either the present_surface or
present_surface_for_mode requests. Presenting a surface takes effect
on the next wl_surface.commit. See the individual requests for
details about scaling and mode switches.
The client can have at most one surface per output at any time.
Requesting a surface be presented on an output that already has a
surface replaces the previously presented surface. Presenting a null
surface removes its content and effectively disables the output.
Exactly what happens when an output is "disabled" is
compositor-specific. The same surface may be presented multiple
outputs simultaneously.
</description>
<enum name="present_method">
<description summary="different method to set the surface fullscreen">
Hints to indicate to the compositor how to deal with a conflict
between the dimensions of the surface and the dimensions of the
output. The compositor is free to ignore this parameter.
</description>
<entry name="default" value="0" summary="no preference, apply default policy"/>
<entry name="center" value="1" summary="center the surface on the output"/>
<entry name="zoom" value="2" summary="scale the surface,
preserving aspect ratio, to the largest size that will fit on the output" />
Post by Jonas Ådahl
Post by Jason Ekstrand
<entry name="zoom_crop" value="3" summary="scale the surface,
preserving aspect ratio, to fully fill the output cropping if needed" />
Post by Jonas Ådahl
Post by Jason Ekstrand
<entry name="stretch" value="4" summary="scale the surface to the
size of the output ignoring aspect ratio" />
Post by Jonas Ådahl
Post by Jason Ekstrand
</enum>
<request name="present_surface">
<description summary="present surface for display">
Present a surface on the given output.
If the output is null, the compositor will present the surface on
whatever display (or displays) it thinks best. In particular, this
may replace any or all surfaces currently presented so it should
not be used in combination with placing surfaces on specific
outputs.
The method parameter is a hit to the compositor for how the surface
is to be presented. In particular, it tells the compostior how to
handle a size mismatch between the presented surface and the
output. The compositor is free to ignore this parameter.
The "zoom", "zoom_crop", and "stretch" methods imply a scaling
operation on the surface. This will override any kind of output
scaling, so the buffer_scale property of the surface is effectively
ignored.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
I think you might be missing an 'allow-null="true"' parameter here, as
you above specify that presenting a null-surface on non-null output
would "disable" that output.
Yes, it does. I have it fixed locally.
Post by Jonas Ådahl
It might also be a good idea to add a note that presenting a
null-surface on a null-output should raise a protocol error as I assume
it should.
Nope, that's fine. It should clear whatever default stuff you've presented.
In my implementation, it clears everything.
Post by Jonas Ådahl
Regarding present_surface_for_mode, it is unclear if it is expected
that it will handle null-surface (if you'd add allow-null="true") as one
need to provide a frame rate, while the description doesn't say anything
of what method of presenting has the described effect.
Yeah. You could make null here the same as the other or not accept null.
Post by Jonas Ådahl
From a client perspective it shouldn't make much difference whether they
call one or the other. I think we can make allow-null=false for
present_surface_for_mode for now. If we ever have reason to change that we
can later.
Post by Jonas Ådahl
Jonas
Post by Jason Ekstrand
<arg name="method" type="uint"/>
<arg name="output" type="object" interface="wl_output"
allow-null="true"/>
Post by Jonas Ådahl
Post by Jason Ekstrand
</request>
<request name="present_surface_for_mode">
<description summary="present surface for display at a particular mode">
Presents a surface on the given output for a particular mode.
If the current size of the output differs from that of the surface,
the compositor will attempt to change the size of the output to
match the surface. The result of the mode-swith operation will be
returned via the provided wl_fullscreen_shell_mode_feedback object.
If the current output mode matches the one requested or if the
compositor successfully switches the mode to match the surface,
then the mode_successfull event will be sent and the output will
contain the contents of the given surface. If the compositor
cannot match the output size to the surface size, the mode_failed
will be sent and the output will contain the contents of the
previously presented surface (if any). If another surface is
presented on the given output before either of these has a chance
to happen, the present_canceled event will be sent.
If the size of the presented surface changes, the resulting output
is undefined. The compositor may attempt to change the output mode
to compensate. However, there is no guarantee that a suitable mode
will be found and the client has no way to be notified of success
or failure.
The framerate parameter specifies the target framerate for the
output. The compositor is free to ignore this parameter. A value
of 0 indicates that the client has no preference.
If the surface has a buffer_scale greater than 1, the compositor
may choose a mode that matches either the buffer size or the
surface size. In either case, the surface will fill the output.
</description>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="output" type="object" interface="wl_output"/>
<arg name="framerate" type="int"/>
<arg name="feedback" type="new_id"
interface="wl_fullscreen_shell_mode_feedback"/>
Post by Jonas Ådahl
Post by Jason Ekstrand
</request>
<enum name="error">
<description summary="wl_fullscreen_shell error values">
These errors can be emitted in response to wl_fullscreen_shell requests
</description>
<entry name="invalid_method" value="0" summary="present_method is not known"/>
</enum>
</interface>
<interface name="wl_fullscreen_shell_mode_feedback" version="1">
<event name="mode_successful">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation was
successful. A surface of the size requested in the mode switch
will fill the output without scaling.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="mode_failed">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation
failed. This may be because the requested output mode is not
possible or it may mean that the compositor does not want to allow
mode switches at this time.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
<event name="present_canceled">
<description summary="mode switch succeeded">
This event indicates that the attempted mode switch operation was
canceled. Most likely this is because the client requested a
second mode switch before the first one completed.
Upon recieving this event, the client should destroy the
wl_fullscreen_shell_mode_feedback object.
</description>
</event>
</interface>
</protocol>
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20140224/e41b2987/attachment-0001.html>
Loading...