EGLFS and rotation of QT5 application under Linux - linux

On behalf of my colleague I'd like to ask if it is possible to rotate the whole QT5 (QT 5.6.1-1) application window. We are using EGLFS as a backend on Sitara TI AM335X platform running Linux framebuffer.
The current situation is like this: we have some application which normally is rotated 90 degrees from end user point of view. As a temporary solution my colleague (the developer of this application) is rotating every element in this window to achieve proper visual effect. Unfortunately this rotation takes a lot of time of CPU.
My question is - is it possible to turn the whole window clockwise? I mean is it possible to do it on EGLFS or QT5 level without rotating every single element in the window?
I tried to exchange x-y dimensions (800x480) of the screen but without success. I have also taken a look into a linux kernel driver sources and I see no possibility to rotate the whole screen. I was thinking about creating some another buffer in memory from which I could copy data with rotation to target memory, but I'm not sure if it is good idea.
Any ideas?

Set the QT_QPA_EGLFS_ROTATION environment variable to 90 or -90. See the documentation.

Rotation on EGLFS platform was afflicted by a bug QTBUG-39959 until version 5.7.x and so the rotation variable was ignored.
The bug is fixed from version 5.8.

Related

Changing Resolution of Linux Framebuffer

I am writing a high performance video application in linux and C++ (but language shouldn't matter for this question)
I currently have my application such that I can display images to the Framebuffer. When my computer boots, the resolution of the display connected seems to be set permanently. I would like to be able to change the resolution output on the computer dynamically. I have tried fbset but it did not work. I am not using X11 because I assumed that there would be a performance decrease.
Is directly writing to the framebuffer the best way to be doing my
rendering for performance?
If I use X11 I see that I can get commands
to change the resolution. Should this be something I investigate?
Is there another way to change resolution?

Get screenshot of EGL DRM/KMS application

How to get screenshot of graphical application programmatically? Application draw its window using EGL API via DRM/KMS.
I use Ubuntu Server 16.04.3 and graphical application written using Qt 5.9.2 with EGLFS QPA backend. It started from first virtual terminal (if matters), then it switch display to output in full HD graphical mode.
When I use utilities (e.g. fb2png) which operates on /dev/fb?, then only textmode contents of first virtual terminal (Ctrl+Alt+F1) are saved as screenshot.
It is hardly, that there are EGL API to get contents of any buffer from context of another process (it would be insecure), but maybe there are some mechanism (and library) to get access to final output of GPU?
One way would be to get a screenshot from within your application, reading the contents of the back buffer with glReadPixels(). Or use QQuickWindow::grabWindow(), which internally uses glReadPixels() in the correct way. This seems to be not an option for you, as you need to take a screenshot when the Qt app is frozen.
The other way would be to use the DRM API to map the framebuffer and then memcpy the mapped pixels. This is implemented in Chromium OS with Python and can be translated to C easily, see https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/367611. The DRM API can also be used by another process than the Qt UI process that does the rendering.
This is a very interesting question, and I have fought this problem from several angles.
The problem is quite complex and dependant on platform, you seem to be running on EGL, which means embedded, and there you have few options unless your platform offers them.
The options you have are:
glTexSubImage2D
glTexSubImage2D can copy several kinds of buffers from OpenGL textures to CPU memory. Unfortunatly it is not supported in GLES 2/3, but your embedded provider might support it via an extension. This is nice because you can either render to FBO or get the pixels from the specific texture you need. It also needs minimal code intervertion.
glReadPixels
glReadPixels is the most common way to download all or part of the GPU pixels which are already rendered. Albeit slow, it works on GLES and Desktop. On Desktop with a decent GPU is bearable up to interactive framerates, but beware on embedded it might be really slow as it stops your render thread to get the data (horrible framedrops ensured). You can save code as it can be made to work with minimal code modifications.
Pixel Buffer Objects (PBO's)
Once you start doing real research PBO's appear here and there because they can be made to work asynchronously. They are also generally not supported in embedded but can work really well on desktop even on mediocre GPU's. Also a bit tricky to setup and require specific render modifications.
Framebuffer
On embedded, sometimes you already render to the framebuffer, so go there and fetch the pixels. Also works on desktop. You can enven mmap() the buffer to a file and get partial contents easily. But beware in many embedded systems EGL does not work on the framebuffer but on a different 'overlay' so you might be snapshotting the background of it. Also to note some multimedia applications are run with UI's on the EGL and media players on the framebuffer. So if you only need to capture the video players this might work for you. In other cases there is EGL targeting a texture which is copied to the framebuffer, and it will also work just fine.
As far as I know render to texture and stream to a framebuffer is the way they made the sweet Qt UI you see on the Ableton Push 2
More exotic Dispmanx/OpenWF
On some embedded systems (notably the Raspberry Pi and most Broadcom Videocore's) you have DispmanX. Whichs is really interesting:
This is fun:
The lowest level of accessing the GPU seems to be by an API called Dispmanx[...]
It continues...
Just to give you total lack of encouragement from using Dispmanx there are hardly any examples and no serious documentation.
Basically DispmanX is very near to baremetal. So it is even deeper down than the framebuffer or EGL. Really interesting stuff because you can use vc_dispmanx_snapshot() and really get a snapshot of everything really fast. And by fast I mean I got 30FPS RGBA32 screen capture with no noticeable stutter on screen and about 4~6% of extra CPU overhead on a Rasberry Pi. Night and day because glReadPixels got was producing very noticeable framedrops even for 1x1 pixel capture.
That's pretty much what I've found.

ncurses good practices: clear screen with windows

ncurses app checks if terminal has been resized. If the size is less than 80x25, then blank the screen and show error message.
If the app has N windows, should all of them be removed with delwin(), or calling clear() would be enough? On the other hand, can already existing windows be later reused after clear() - to refresh and display contents if terminal size became satisfactory - or they should be recreated?
Clearing the windows sounds like the application's behavior rather than ncurses as such. The ncurses library (see resizeterm) will clear areas if the windows increase in size.
The best policy when resizing really depends on what you have inside the windows. ncurses is making reasonably safe changes, but since it has no information about your intention in making some things close on the screen, and others separated, all it can do is to attempt to resize windows so that their contents are preserved. The application can still clear them and start over again — as well as moving windows around on the screen.
It's your decision whether it is simpler to recreate the windows or reuse them.
As long as all of the rebuilding is done before the next repainting of the screen (e.g., with wrefresh), ncurses will make the updates with as little activity as it can.

linux qt change monitor refresh frequency

i am using openGL to improve the performance on the target.
i would like to know if there is a way to change monitor refresh frequency (from qt or linux) to match the application.
Qt does not wrap that functionality. You would need to access X directly, via XCB (or Xlib, but XCB is to be preferred) and the XRandR extension.
However, these days refresh rate is typically limited by the output device, as LCD screens often only operate in the 60Hz-75Hz range.

Is kernel or userspace responsible for rotating framebuffer to match screen

I'm working on embedded device with screen rotated 90 degrees clockwise: screen controller reports 800x600 screen, while device's screen is 600x800 portrait.
What do you think, whose responsibility it is to compensate for this: should kernel rotate framebuffer to provide 800x600 screen as expected by upper-level software or applications (X server, bootsplash) should adapt and draw to rotated screen?
Every part of stack is free software, so there are no non-technical problems for modification, the question is more about logical soundness.
It makes most sense for the screen driver to do it - the kernel after all is supposed to provide an abstraction of the device for the userspace applications to work with. If the screen is a 600x800 portrait oriented device, then that's what applications should see from the kernel.
yes,I agree, The display driver should update the display accordingly and keep the control
Not sure exactly how standard your embedded device is, if it is running a regular linux kernel, you might check in the kernel configurator (make xconfig, when compiling a new kernel) , one of the options for kernel 2.6.37.6 in the device, video card section, is to enable rotation of the kernel messages display so it scrolls 90 degrees left or right while booting up.
I think it also makes your consoles be rotated correctly after login too.
This was not available in kernels even 6-8 months ago, at least not available in kernel that slackware64 13.37 came with about that time.
Note that the bios messages are still rotated on a PC motherboard,
but that is hard-coded in the bios, which may not apply to the embedded system you are working with.
If this kernel feature is not useful to you for whatever reason, how they did it in the linux kernel might be good example of where and how to go about it. Once you get the exact name of the option from "make xconfig", it should be pretty easy to search where ever they log the kernel traffic for that name and dig up some info about it.
Hmmm. I just recompiled my kernel today, and I may have been wrong about how new this option is. Looks like it was available with some kernel versions before the included-with-Slackware64 versions that I referenced. Sorry!

Resources