Skip to content
This repository has been archived by the owner on Nov 1, 2021. It is now read-only.

[WIP] Add output manager protocol #23

Closed
wants to merge 11 commits into from

Conversation

VincentVanlaer
Copy link

Fixes #15
I still need to do a some descriptions and a final spell/grammar check, but the protocol itself can be reviewed.
The protocol references the wl_output.transform enum, so it will only build on the alpha that was just released.

Prior art by KDE:
https://cgit.kde.org/kwayland.git/tree/src/client/protocols/outputdevice.xml
https://cgit.kde.org/kwayland.git/tree/src/client/protocols/output-management.xml

Difference with the KDE protocols

  • One protocol instead of two. No preference either way, one protocol was just easier to write.
  • Removed subpixel. Doesn't seem very relevant for configuring outputs.
  • Removed make & model. Replaced by name & description.
  • Removed phys size. Not sure whether it should be added or not, would be useful to have a constant dpi across all output devices.
  • Removed EDID. Including EDID feels like an overkill.
  • Removed uuid. Name + description should be sufficient. Besides, I don't think its a good idea to force compositors to remember stuff across restarts for a protocol like this.
  • Removed scale. Replaced by size.
  • Removed requirement that outputs should not overlap or cause gaps. This is i.m.o. compositor dependent.
  • Added name & description.
  • Added size. Similar to xdg-output's logical_size event. Allows for fractional scaling.
  • Added disconnected. Outputs can be removed.
  • Added destructors.
  • Added the requirement that the server should try to rollback on failures.
  • Added the requirement that only property changes requested explicitly by the client are applied. this improve consistency across compositors.
  • Split mode into supported_mode and active_mode. Allows a client to set a custom mode.

Questions I still have:

  • On a failed event, should we inform the client what caused the failure? Maybe an enum describing which request failed and the output the configuration change was applied to.
  • What's the consensus on the copyright? Some descriptions are from the core protocol, the KDE protocol and xdg-output. I assume I need to add the copyright holders from those protocols as well?

</description>
</event>

<event name="disconnected">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a global, we can just remove the global instead.

This event is sent after the client binds to the output_device
and whenever the output device is enabled or disabled.
</description>
<arg name="enabled" type="int" summary="output enabled state"/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having an enum, we can just have an int which is non-zero when enabled

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or something like:
<event name="wl_output> <arg name="output" type="object" interface="wl_output" nullable/> <event>

non-null when it's active, and null when sent to inactivity.
A direct link to wl_output (avoiding string comparisons) is missing either way IMO

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not against a link between this and wl_output, but iirc there was some discussion on #wayland about different protocols creating the same interfaces and why that was a bad idea. Might be wrong on that. This would also be a server-created object, which is tricky to destroy. (see http://ppaalanen.blogspot.com/2014/07/wayland-protocol-design-object-lifespan.html )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"A link to wl_output" would not mean that this interface would create wl_output objects.

However it is tricky, because output_device objects are published as globals, and we can "link" wl_outputs only after the client has bound to the global…

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, got it, that would be tricky indeed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The more I think about this, the more I don't like this approach. An alternative solution would be to send the name that the registry gives to the global. However, as far as I can tell, it's not possible to obtain that in the current api.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be client specific, because you may hide others, and they are just a counter from what I've seen.

Well, it would be sent with all other events on binding. It can't be linked to it like xdg-output is either way. It's just an "attribute" the client can track.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the libwayland code, the names are indeed a counter. However, there's currently no way to obtain the name of a global, except guessing it.

@Ongy
Copy link

Ongy commented Jul 13, 2018

Removed uuid. Name + description should be sufficient. Besides, I don't think its a good idea to force compositors to remember stuff across restarts for a protocol like this.

I think we should try to get this used by KDE as well, might be nicer to have it as optional output attribute for those that want to support it for that purpose (and in general)


The naming convention is compositor defined, but limited to
alphanumeric characters and dashes (-). Each name is unique among all
wl_output globals, but if a wl_output global is destroyed the same name
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wl_output globals? :)

I think you copy+pasted a bit eagerly.

Should probably reference the xdg-output name event (and force equality?).

@Ongy
Copy link

Ongy commented Jul 13, 2018

On a failed event, should we inform the client what caused the failure? Maybe an enum describing which request failed and the output the configuration change was applied to.

I'm leaning towards string. Enum could be annoying, and if we want to include e.g. "leaves gaps" which is allowed by the protocol, but might be imposed by the compositor, it gets ugly.

What's the consensus on the copyright? Some descriptions are from the core protocol, the KDE protocol and xdg-output. I assume I need to add the copyright holders from those protocols as well?

As always: IANAL

Copyright is a mess. You didn't base this on the core, you just re-used necessary parts, afaik no need to consider that.
On the KDE side, did you base it on theirs? Otherwise adding them, without them ever seeing this is iffy as well IMO. In the long run we should probably get together with them either way, so this shouldn't be a huge problem.

@emersion
Copy link
Member

I think we should try to get this used by KDE as well, might be nicer to have it as optional output attribute for those that want to support it for that purpose (and in general)

They can just use "name" for this.

@Ongy
Copy link

Ongy commented Jul 13, 2018

Or rather description, yes. They didn't have this field before, and I'd bind the name to xdg-output name, as mentioned before

@ammen99
Copy link
Member

ammen99 commented Jul 14, 2018

@VincentVanlaer Why did you use "transformation" and not "transform" throughout the protocol? The latter is used in wl_output so to me this seems an inconsistency.

<description summary="create a new output configuration object">
Create a new output configuration object.
</description>
<arg name="id" type="new_id" interface="zwlr_output_device_v1"/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zwlr_output_configuration_v1

</request>
</interface>

<interface name="zwlr_output_configuration_v1" version="1">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you set the scale?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ceil(size/mode)

But that needs an addition that enforces that the same result with both width and height.
And some tolerance for floats :/
I had a discussion with Pekka on #wayland recently, and the result was that we should probably add a non-integer sizing hint, and just use scale for non-HiDPI-aware clients, so I wonder if we should just drop the fractional scale concept in protocols.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I mean there's no set_scale request in this interface.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added size. Similar to xdg-output's logical_size event. Allows for fractional scaling.

It is computable from this (provided I understood the intended usecase correctly)
But I wonder if it's a good idea to have this in the long run

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows to read the scale, not to set it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, must have forgotten to add the set_size event. I don't think we should drop fractional scaling in this protocol, since it is used for configuration instead of rendering. I used this on X on my old laptop to scale from 1600x900 (built in screen resolution) to 1920x1080 for certain external displays when giving presentations.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure a set_size request would work well: what happens if the compositor doesn't support fractional scaling? What happens if the x-axis ratio is different from the y-axis ratio?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The compositor would reject the change in that case.

@@ -0,0 +1,350 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="wlr_output_manager_v1">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be wlr_output_manager_unstable_v1 (or maybe management?)

<arg name="refresh" type="int" summary="vertical refresh rate in mHz"/>
</event>

<event name="active_mode">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Refresh" doesn't always make sense, some outputs might have variable refresh rates (such as virtual outputs)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the compositor could send zero if it doesn't apply?

<arg name="refresh" type="int" summary="vertical refresh rate in mHz"/>
</event>

<event name="transformation">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these events don't make sense if the output is disabled. What then? Should the compositor not send them?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that would be the cleanest approach.

summary="height in global compositor space"/>
</event>

<event name="position">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it makes sense to have these events at all. These events only make sense if the output is enabled. In this case this data can be obtained from wl_output and xdg-output as normal.

The only added value provided by output_device is that the object exists even if the output is disabled. So I wonder if it's necessary to add these at all.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only two events that we would be able to drop are transformation and position. The others are different from the wl_output and xdg_output interfaces. It doesn't feel right to to reference only those two.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Same for "size")

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(And "active_mode")

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size is different from the xdg_output logical_size in the current description.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, if xdg_output.logical_size would be exactly the same, I'd rather have them separate too. That would solve #23 (comment) .

This is handled by wl_registry.global_remove
transform is consistent with wl_output
Fix for copy-paste mistake.
Add references to xdg-output
Add unstable
manager -> management: seem sto be more consistent with the protocols in
wayland-protocols.
@agx
Copy link
Contributor

agx commented Jul 15, 2018

Great this is moving forward! Two things I'm wondering about: where would we put output cloning (one display showing the same as another)? Should this be a part of this protocol?

How would I map a {wl,xdg}_output to an output_device ?

@VincentVanlaer
Copy link
Author

Great this is moving forward! Two things I'm wondering about: where would we put output cloning (one display showing the same as another)? Should this be a part of this protocol?

I think that output cloning is to complex for the first version, see swaywm/sway#1666 . However, it would make sense for compositors to check whether size and position are the same, and clone in that case.

How would I map a {wl,xdg}_output to an output_device ?

It's being discussed in #23 (comment) , but gihub is being annoying and has marked everything outdated.

@VincentVanlaer
Copy link
Author

event once for every supported mode.

If the concept of a specific refresh rate does not apply to the mode,
the refresh argument shpuld be zero. An example of this is a monitor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo

summary="y position within the global compositor space"/>
</event>

<enum name="enablement">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not used anymore

@emersion
Copy link
Member

Additional prior art: https://lists.freedesktop.org/archives/wayland-devel/2014-February/013481.html

Reading through the discussion and why it hasn't been merged might be interesting.

@ddevault
Copy link
Contributor

I would prefer to refactor this into a design similar to xdg-output, where the client explicitly maps wl_outputs to zwlr_output_device_v1, for consistnecy and so that we don't have to duplicate the information provided by xdg_output.

@VincentVanlaer
Copy link
Author

@emersion Unless I missed something, it just stops at v4 without any comments. The discussion might be interesting, I'll give it a read.

@SirCmpwn Aye, I agree that duplication is not optimal, but we still want to represent disabled outputs. Should we have a global for each disabled output? So one either has a wl_output or a wl_disabled_output for each output that is connected. It makes the configuration interface messy though since it needs to accept either type of output.

@ddevault
Copy link
Contributor

Right, I forgot about disabled outputs. Bleh.

@emersion
Copy link
Member

One issue this protocol doesn't address is frame-perfect output configuration on hotplug.

When the logic to configure outputs is in the compositor, it's easy to apply it on hotplug and get the desired configuration on first modeset. When the logic is in a client like this, we don't know if the client will attempt to change it on hotplug so there will be two modesets: one done by the compositor after hotplug, and another one done by the client to apply the new configuration.

For instance if I have configured an output to be disabled in my client config, plugging it will first enable it and then disable it. Same if I've configured a different mode.

Maybe this could be solved with a configure event similar to xdg-shell.

@Ongy
Copy link

Ongy commented Sep 16, 2018

Calling this "frame perfect" is funny with the time some outputs take to modeset :)

The interesting challenge here is to provide a mechanism that will work without an application and can be driven with one modeset from the an application.

One simple way would be to mandate compositors don't automatically change related settings while any application has an object of this protocol.
Though I'd think a kind of capability field that tells the compositor what the client wants to do (e.g. re-position outputs when another is removed, manage freshly hotpluged etc.) so we don't have to have all features in every client.

@emersion
Copy link
Member

Additional prior art: GNOME https://wiki.gnome.org/Initiatives/Wayland/Gaps/DisplayConfig

@ddevault
Copy link
Contributor

Calling this "frame perfect" is funny with the time some outputs take to modeset :)

We should design this protocol under the assumption that 10 years from now it'll be used to modeset outputs which can change modes within a single frame

@agx
Copy link
Contributor

agx commented Nov 30, 2018

One issue this protocol doesn't address is frame-perfect output configuration on hotplug.

When the logic to configure outputs is in the compositor, it's easy to apply it on hotplug and get the desired configuration on first modeset. When the logic is in a client like this, we don't know if the client will attempt to change it on hotplug so there will be two modesets: one done by the compositor after hotplug, and another one done by the client to apply the new configuration.

For instance if I have configured an output to be disabled in my client config, plugging it will first enable it and then disable it. Same if I've configured a different mode.

Maybe this could be solved with a configure event similar to xdg-shell.

For hotplugged outputs (when the compositor is already running) we can keep them off and then only apply the configuration once the compositor sees the "apply" request, no? It's more cumbersome when the compositor starts up and applies a default configuraton and the client isn't happy with that which would introduce screen flickering.

@emersion
Copy link
Member

For hotplugged outputs (when the compositor is already running) we can keep them off and then only apply the configuration once the compositor sees the "apply" request, no?

Yes, but there are issues with output changes not seen as atomic. So we should probably have an event saying "I've sent all newly plugged outputs and removed all newly unplugged outputs, now please send a configuration" and an event saying "you asked me to configure all outputs, please apply this state atomically". This will help in cases where there are less CRTCs than connected outputs.

@emersion
Copy link
Member

emersion commented Mar 7, 2019

Here is a new proposal: #38

@ddevault ddevault closed this Mar 10, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants