[RFC] New effect plugin - projector (keystone) correction
Needs ReviewPublic

Authored by nowicki on Mar 29 2017, 6:58 PM.

Details

Reviewers
graesslin
Group Reviewers
Plasma
Summary

I have been using my laptop to display content on a projector and sometimes I have encountered some cheap/broken device that either cannot be set-up properly or it is fixed to the wall with no way of doing any adjustments. This led me to the idea to do this transformation in software. I have found that KWin - due to its nice architecture - is a good place to hook up into.

I am aware that at least on X (not sure about Wayland - never been there yet) it is possible to configure a transform matrix with a specific output using XRandr. Unfortunately this seems to be rarely used and thus broken on all drivers I have attempted to use it (nVidia proprietary, amdgpu, qemu/qxl).

This patch is a working concept, which I am aware has some shortcomings. Window frames are rendered with ugly aliasing and interaction with other effects can sometimes lead to funny results. Nevertheless if you consider that it will be mostly used to display a full-screen window with a presentation, it does the job quite nicely.

The configuration is very basic ATM - a DBus interface is exposed to set the target rectangle on a given output. This is because I am not exactly sure where the configuration of this effect should be done. From KWin architecture POV it should receive its own config window. However from UX POV it might be better to hook it up with the KScreen KCM, so that the correction can be adjusted per display and optionally be stored along with the KScreen configuration.

Diff Detail

Repository
R108 KWin
Lint
Lint Skipped
Unit
Unit Tests Skipped
nowicki created this revision.Mar 29 2017, 6:58 PM
Restricted Application edited projects, added Plasma; removed KWin. · View Herald TranscriptMar 29 2017, 6:58 PM
Restricted Application added a subscriber: KWin. · View Herald Transcript
graesslin edited edge metadata.Mar 29 2017, 7:44 PM

I think the effect system is the wrong place for it - at least if we want to add it to KWin directly. The transformation should be done directly in the Scene.

effects/projector/projector.cpp
101–126

This is something which we should not do. That has major impact on the performance of the overall system. Cursors are on an own layer and thus cursor movement does not require a repaint.

Also on X11 we are not able to perfectly track the cursor. On Wayland, though we have full control over it.

261–263

unrelated to the fact that I think we shouldn't do cursor manipulation: we do have access to the cursor image in the effects API.

I think the effect system is the wrong place for it - at least if we want to add it to KWin directly. The transformation should be done directly in the Scene.

I have done it this way initially in order for it to be as little intrusive as possible. If the idea as a whole makes sense, I'll definitely have a look at doing this at a scene level as you suggested.

effects/projector/projector.cpp
101–126

The reason for taking over cursor drawing is that when transformation is applied the pointer pixmap doesn't match the point where the cursor actually hits the windows below it. Since there is no way to apply translation to the HW cursor position drawing a SW cursor is the only way to make the mouse usable with tranformation applied.

ftr, not sure about --transform correctnes, but metamodes ViewportIn/ViewportOut work flawless on at least the nvidia blob.

The idea that I have in mind ATM is to redirect drawing the whole screen into a FBO and then draw it screen by screen applying transformation where necessary. This should be fairly easy thanks to the render target stack in KWin. Doing it this way would get rid of the ugly artifacts at window edges. The downside is that it introduces a requirement for maximum texture size to be at least the size of the virtual desktop (already imposed by the blur and backgroundcontrast effects). I'm planning to run this on an old Intel Pineview and I hope it would have enough juice to handle this.

The idea that I have in mind ATM is to redirect drawing the whole screen into a FBO and then draw it screen by screen applying transformation where necessary. This should be fairly easy thanks to the render target stack in KWin. Doing it this way would get rid of the ugly artifacts at window edges. The downside is that it introduces a requirement for maximum texture size to be at least the size of the virtual desktop (already imposed by the blur and backgroundcontrast effects). I'm planning to run this on an old Intel Pineview and I hope it would have enough juice to handle this.

Out from past experience with that: using a full screen fbo and redirect the complete rendering to it results in about half the frame rate. Though the architecture through framebuffer blit improved.

nalvarez added inline comments.
effects/projector/projector.cpp
101–126

I think it would be acceptable if the cursor is drawn just like it is now, on its own layer, even if drawing it without the transformation would make it slightly deformed visually.

You just have to ensure mouse events are properly inverse-transformed so that they go to the right place in the window. Isn't this already done for some effects? Isn't it possible to scale a window and keep interacting with it?

graesslin added inline comments.Apr 12 2017, 5:12 AM
effects/projector/projector.cpp
101–126

You just have to ensure mouse events are properly inverse-transformed so that they go to the right place in the window. Isn't this already done for some effects?

no that is not done anywhere as X doesn't support it.