swaywm / wlroots

A modular Wayland compositor library
https://gitlab.freedesktop.org/wlroots/wlroots/
MIT License
2.15k stars 343 forks source link

Hardware output rotation #1058

Open emersion opened 6 years ago

emersion commented 6 years ago

Some GPU drivers support rotating the screen right after scanout, instead of doing software rotation like we do right now.

The Wayland backend would also support this.


wlroots has migrated to gitlab.freedesktop.org. This issue has been moved to:

https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/1058

ascent12 commented 6 years ago

Yeah, this is something I've been aware of for quite a while. As far as I can tell, it's still pretty uncommon in DRM devices. Out of the DRM devices I have, the only supported hardware rotation is a 180 degree rotation (no 90 or 270 or reflections) on an Intel iGPU.

emersion commented 5 years ago

https://lists.freedesktop.org/archives/wayland-devel/2018-November/039646.html

ascent12 commented 5 years ago

Here's a particularly interesting conversation from #dri-devel about this:

[21:45:54] <jadahl> hey. using the intel KMS driver, any ideas why setting a "rotate-270" transform on the primary plane of CRTC would fail even if it's availability is advertised? it fails with EINVAL
[21:48:41] <ickle> the reasons are many and varied; most likely you didn't supply a y-tiled fb
[22:27:18] <jadahl> ickle: what do I do first? change mode and pass a y-tiled fb, or set the property?
[22:32:36] <ickle> under atomic, you do it all in one go; for legacy, the foolproof way is to disable the crtc, set rotation, then set mode
[22:33:12] <jadahl> i see, thanks
[22:52:33] <jadahl> ickle: does that mean that e.g. if the same fb needs to be shareable to e.g. nouveau, rotations wont work?
[22:52:58] <ickle> not trivially
[22:53:58] <ickle> (for sharing, it pretty much always boils down to buffering at some point :(
[23:01:53] <jadahl> currently we create linear fb, thats sharable and flippable
[23:02:07] <jadahl> but I assume that wont be work with rotation then
[23:17:41] <danvet> jadahl, yeah for sharing you generally need a copy somewhere
[23:18:08] <danvet> because the tiled formats aren't compatible, and for most fancy things you need tiled formats
[23:18:23] <danvet> (linear is impossible to scan out 90/270° rotated)
[23:18:45] <danvet> arm is somewhat successfully solving this with afbc, but that's not used by everyone (for obvious reasons)
[23:27:22] <jadahl> danvet: but 180° would work with linear?
[23:28:20] <danvet> usually
[23:28:40] <danvet> memory controllers are generally ok if you read stuff backwards
[23:28:50] <danvet> they totally hate you if you read column-wise
[23:28:54] <jadahl> how can I know if it would? (atomic I assume I can "dry-run", but with legacy)
[23:29:02] <danvet> try
[23:29:08] <danvet> there's no other way with legacy
[23:29:12] <jadahl> ok
[23:29:15] <jadahl> :|
[23:29:17] <jadahl> oh well
[23:29:20] <jadahl> thanks
[23:29:22] <danvet> well there's a reason we have atomic :-)
[23:29:27] <jadahl> yea :)
[23:29:34] <jadahl> just need to keep legacy working too :P
[23:29:56] <danvet> yeah there's some older hw where we're likely never going to turn on atomic
[23:30:06] <danvet> too much work
[23:30:12] <jadahl> such as?
[23:30:15] <jadahl> (what hw)
[23:30:21] <danvet> radeon.ko isn't atomic
[23:30:39] <danvet> intel pre-gen6 iirc (too lazy to check the exact check)
[23:30:46] <danvet> nouveau per-nv50
[23:30:53] <danvet> those are the big ones
[23:31:22] <danvet> welp, nouveau atomic is still not on by default :-(
[23:31:23] <jadahl> alright. well enough reason to keep things working
[23:31:28] <danvet> so all of nouveau :-/
[23:31:32] <danvet> skeggsb, ^^ any plans?
[23:31:36] <jadahl> even more reason then :P
[23:31:57] <danvet> plus random assortment of smaller old drivers
[23:32:05] <danvet> e.g. gma500 (but I hope no one cares about that)
[23:34:37] <jadahl> i still have a gma500 in a drawer in another country I might need to use to ssh into my workstation one day
[23:38:02] <Adrinael> danvet, gen < 5 is the current check
[23:38:47] <daniels> jadahl, danvet: just don't try to do rotated scanout if you have a high resolution or anything, because then Y-tiling will blow your FIFO
[23:39:08] <jadahl> daniels: define high resolution
[23:40:06] <daniels> depends, especially e.g. atom has far lower thresholds
[23:40:22] <daniels> (or at least the APL I had certainly had lower available space than SKL)
[23:41:18] <danvet> jadahl, 90/270 is really hard on your memory controller, in general it's better to rotate and scan that out
[23:41:25] <jadahl> another "try and fallback to shadow buffer" case?
[23:41:28] <danvet> except if you update with a new rendered frame every frame
[23:41:33] <danvet> well yeah
[23:41:50] <danvet> i.e. if the frame doesn't change, then rotate it using gl and show that
[23:41:57] <danvet> will burn down much less power on idle
[23:42:05] <danvet> should be a general rule, not just on i915
[23:42:08] <jadahl> well, in general frames change, otherwise we wouldn't flip
[23:42:41] <jadahl> you're saying even when we don't hand over new fbs, it's better to rotate in gl than using plane rotation?
[23:43:07] <danvet> the cost of doing the gl rotation every frame is bigger than scanning out rotated
[23:43:27] <danvet> but if your content becomes static, then doing the gl rotation and scanning out unrotated is much better
[23:43:39] <danvet> and with atomic you can flip between the two like with a pageflip
[23:44:00] <jadahl> with static you mean no more page flips
[23:44:07] <danvet> static screen contents
[23:44:08] <jadahl> "for a while"
[23:44:26] <danvet> in case you have a compositor that does frontbuffer rendering (pls don't do that)
[23:44:35] <danvet> yeah, for a while > 1 frame :-)
[23:45:10] <danvet> or at least that's what I'd do
[23:45:35] <danvet> i.e. on the first frame where nothing changed, just bake it all in and do one more flip
[23:45:43] <jadahl> you mean if I'd flip a buffer that didn't change since last time, or if I stop flipping new frames?
[23:45:52] <danvet> both
[23:46:10] <danvet> it's the same for the hw
[23:47:31] <danvet> and you need the "rotate in gl" path anyway, so might as well use it for some good
[23:48:04] <jadahl> its used pretty much always now because we see the rotation EINVAL and blacklist
[23:48:38] <danvet> blacklist on EINVAL with atomic is kinda not a good idea
[23:48:58] <danvet> there's lots of dynamic reasons why something doesn't work just now
[23:49:12] <danvet> stuff like "I can only rotate if you're aligned to even borders"
[23:49:22] <danvet> so move your window, and it works again
[23:49:27] <jadahl> we blacklist with legacy API returning EINVAL
[23:49:34] <danvet> ah yes
[23:49:46] <danvet> legacy is lost cause anyway
[23:49:54] <jadahl> but seems like we shouldn't as we don't unset the CRTC mode before setting the rotation
[23:50:04] <danvet> I wouldn't even bother using anything beyond basic setcrtc and pageflip with legacy
[23:50:34] <danvet> use atomic?
[23:50:38] <jadahl> plan to
[23:50:49] <jadahl> thats partly why i'm here asking questions :P
[23:50:56] <danvet> all that "oops can't rotate with this not-rotated mode" troubles go away ...
emersion commented 4 years ago

GNOME uses CRTC transforms for flipping, but blacklists rotations.

https://gitlab.gnome.org/GNOME/mutter/blob/1206879a20b8ee70fe69f5b57c7708cadc20dd7a/src/backends/native/meta-kms-plane.c#L103

emersion commented 4 years ago

https://gitlab.freedesktop.org/wayland/wayland-protocols/merge_requests/7