Reimagine output cloning
Open, NormalPublic

Description

Output cloning is a way to show the same content on several outputs in a multi-display arrangement. Other notions for this use case are: Duplication, mirroring and unification of outputs.

Motivation

With D22468 the output unification functionality through a single button will be removed from KScreen. That's because the old system had several issues:

  • Either all outputs or none of them could be unified.
  • System did not distinguish outputs only being able to run in cloned mode by sharing the same CRTC and ones being cloned deliberately.
  • The properties of unified outputs were immutable although for example refresh rate of an output is clearly independent of unification.
  • Basically the system just moved the outputs on top of each other and picked outputs resolutions that matched the primary/first one as best as possible. A better approach would be to do project the view port independently of set resolution and position.
  • After unification closing and opening the KCM again just showed the outputs on top of each other instead of as "unified", because it didn't remember that in config files. This hid outputs to users. It could only be discovered when dragging the top output aside.

Proposed solution

Backend
  • Set master and slave output relations through libkscreen explicitly instead of positioning outputs on top of each other and changing their resolutions. X11 already does this somewhat with the clones list. Do the same in libkscreen's Wayland backend. Make KWin/KWayland understand receiving such relations. As a list as well?
  • Unify independently of chosen resolution. This can be done:
    • On X11 through XRender transformations (see xrandr tool).
    • On Wayland internally by the Wayland compositor itself through changes in logical space.
  • The position of the unified outputs is determined by the master output.

Frontend

  • In the overview only show non-slave outputs relative to each other.
  • Clone per drag and drop of one output on top of a certain area inside another output in the overview.
  • Show slave outputs attached to the master output in the overview. Idea: show them as a symbolized list inside the output. Adding more clones then adds to this symbolized list.
  • Break cloning by pulling a symbolized output out of the master output's list again via drag and drop.
  • Allow edit of clone slave outputs properties by clicking on the symbols in the master output view.
romangg created this task.Jul 15 2019, 10:43 AM
romangg triaged this task as Normal priority.
ngraham added a subscriber: VDG.Jul 17 2019, 4:14 PM
More technical info:

Outputs may be in a cloned view because they share the same CRTC. Such outputs can only be driven in a cloned mode, here meaning same resolution and frame rate.

RandR on X11 provides information about such limitations through a symmetrical clone list on cloned outputs. In libkscreen XRandR backend queries this list but then the concepts get mixed up afterwards in KCM code.

What we want instead is querying this list, show that to users, but also provide facilities to duplicate/mirror arbitrary outputs (through positioning, scaling and stretching or using black bars).

On Wayland we don't query information about "cloned" outputs at all at the moment, always assume instead that outputs are driven independently by separate CRTCs. In most cases this might be true. I could imagine it could be different for daisy chaining, but I'm not sure on that. Somebody has more information about that use case? Or has some old or extic hardware actually only being able to drive some of the connectors in a cloned mode?

In any case even if it's only a corner case, we should try to expose the information on Wayland as well through our output-device protocols.

My proposal would be:

  1. In general split the concepts and use different names to signify that split.
  2. Extend our output-device protocol with an event clone_group providing an uint value to identify all outputs being clones of each other.
  3. Extend the output-device protocol family with event and request mirror always having as payload the output-device object acting as the master/source of the mirrored image.
  4. In libkscreen's KWayland backend integrate that and add a new KScreen::Output property for accessing the mirror master KScreen::Output.
  5. In libkscreen's RandR backend only read the clones list from XCB as it was meant to be. For mirroring don't try to manipulate the clones list and don't change resolution. Instead set a mirror to the mirror source geometry by setting position, using XRender transforms to scale the image accordingly and RandR borders for black bars.
  6. In Ui show clones of an output in the same icon list as its mirrors but the clone icons in a disabled state indicating that they are immutable objects in regards to this output.

After some feedback from @davidedmundson I am trying to remodel my first approach a bit: Instead of sending the replication source to KWin, just send the logical size. In KScreen remember the replication source though by hash in the control files I introduced some time ago for the retention data. This will also improve the X11 situation where we currently can only heuristically guess if outputs are replicating other ones (per position and size).