QtWayland client distorted on Raspberry Pi 4 - qt

I'm trying to create a very simple wayland compositor using the examples found here, like this:
import QtQuick 2.12
import QtQuick.Window 2.2
import QtWayland.Compositor 1.3
WaylandCompositor {
id: wlcompositor
WaylandOutput {
compositor: wlcompositor
window: Window {
width: 800
height: 480
visible: true
title: wlcompositor.socketName
Grid {
anchors.fill: parent
anchors.margins: 100
columns: 2
Repeater {
model: shellSurfaces
ShellSurfaceItem {
id: shellSurfaceItem
autoCreatePopupItems: true
shellSurface: modelData
onSurfaceDestroyed: shellSurfaces.remove(index)
}
}
}
}
}
ListModel { id: shellSurfaces }
XdgShell {
onToplevelCreated: shellSurfaces.append({shellSurface: xdgSurface})
}
}
And then I'm creating a separate client app that just creates a couple Rectangles as a test.
import QtQuick 2.12
import QtQuick.Window 2.12
Window
{
id: window
visible: true
width: 200
height: 200
Rectangle
{
anchors.fill: parent
color: "green"
Rectangle
{
x: 10
y: 10
width: 100
height: 100
color: "blue"
}
}
}
Everything seems simple and straightforward. But when I run it on my Pi4 (using the -platform wayland flags), the client gets crazy distortion, like this:
I'm testing it with Boot2Qt, which is a yocto linux image. I've tried Qt versions 5.14.2 and the newest 5.15.0 with the same results. There are no errors on the console. Nothing that indicates anything is wrong except that it looks awful.
I did notice that if I use weston as my compositor instead of QtWayland, then the app looks perfect. So that makes me think there's something wrong with WaylandCompositor. But my search of google found nobody else complaining of the same thing.
I don't even know what to try. Does anybody have any ideas?

I had similar effects using qt 5.15.1 and qt 5.15.2 with qt wayland on the pi 4. I managed to get QT Wayland working with no distortion by compiling the mesa driver 20.3.3 and 20.3.4, using the following options:
-Dplatforms=x11,wayland -Dvulkan-drivers=broadcom -Ddri-drivers= -Dgallium-drivers=kmsro,v3d,vc4 -Dbuildtype=release -Dprefix=/usr -Degl=true
After installing the drivers i updated the sysroot on my host and cross-compiled the QT Lib.
That made it finally working. Good luck.

I've encountered this very same issue from Qt 5.12 to 5.15, and Qt 6.2.0 RC.
The solution to avoid distortion is to enable dma-buf in QtWayland, and set hardware integration from the compositor side:
export QT_WAYLAND_CLIENT_BUFFER_INTEGRATION=linux-dmabuf-unstable-v1
export QT_WAYLAND_SERVER_BUFFER_INTEGRATION=dmabuf-server
Note that in order to enable dma-buf it required me to tweak .pro and configure.json files (I'm doing native build on the Pi4), as the libdrm-dev header couldn't be detected by qmake or cmake correctly.
Add INCLUDEPATH += /usr/include/libdrm/ to the following two:
./src/plugins/hardwareintegration/client/dmabuf-server/dmabuf-server.pro
./src/plugins/hardwareintegration/compositor/dmabuf-server/dmabuf-server.pro
And add libdrm/ before drm headers in following files:
./src/client/configure.json
./src/compositor/configure.json
A re-configure & rebuild should work. Tested on Pi4 + Qt 5.15.2 with both armhf and arm64 image, using dtoverlay=vc4-kms-v3d-pi4 overlay.

If memory serves me correctly, the closed-source graphics driver are a real pain when it comes to wayland support. You may have some luck by enabling the broadcom backend (which I think it's what appropriate for rpis) for qt wayland by setting QT_WAYLAND_CLIENT_BUFFER_INTEGRATION=brcm before starting the compositor.
There is some info about this env var in this readme: https://code.qt.io/cgit/qt/qtwayland.git/tree/README
But if practically possible, I would think the mesa open-source drivers will give you a lot less pain, as it's much more widely used and support is likely much better.

Related

Qt QML Settings are not saved/applied

I have simply copied this example from the docs, adjusting the import version number to the newest ones (but I tried with both for same result).
import QtQuick.Window 2.12
import Qt.labs.settings 1.1
Window {
id: window
width: 800
height: 600
Settings {
property alias x: window.x
property alias y: window.y
property alias width: window.width
property alias height: window.height
}
}
As opposed to advertised, the window geometry was not saved after I closed and reopened the window. In fact, it now doesn't show the window at all? (I tried re-running qmake and cleaning all)
I also get this warning every time I run the project in Qt Creator, regardless of whether I use Settings or not:
17:01:02: Starting C:...debug\untitled.exe...
QML debugging is enabled. Only use this in a safe environment.
qrc:/main.qml:10:5: QML Settings: Failed to initialize QSettings instance. Status code is: 1
qrc:/main.qml:10:5: QML Settings: The following application identifiers have not been set: QVector("organizationName", "organizationDomain")
1) Is the warning related to the issue?
2) How do I remove the warning?
3) How do I get the settings to be applied as advertised?
...Turns out I had to keep reading the docs to the end.
1) Warning is related to the issue.
2) Per the docs, add this at the beginning of the main in main.cpp
app.setOrganizationName("Some Company");
app.setOrganizationDomain("somecompany.com");
app.setApplicationName("Amazing Application");
3) Now works as advertised.

What is qmltestrunner?

I have gone through the documentation provided by Qt on TestCase, Qt Quick Test Reference Documentation, Ubuntu QML unit testing, Testing with qmltestrunner part 1 & 2, Writing and running qml testcases, How to create a Qt-Quick Test
All that I have found about it is:
Qmltestrunner is a tool used for unit testing. This tool allows to execute QML files as test cases. These files should contain test_functions. Qmltestrunner is an open-source project and its source code can be found from the github.
But there are few questions for which I'm looking out for answers:
qmltestrunner documentation? where can I find it? (Could not find wiki page for it)
Is qmltestrunner part of qt quick test framework?
What all dependencies are there for qmltestrunner?
Is there any proper example where I can find complete explanation about QML unit testing? qt quick test framework explains running-tests which I couldn't understand.
Thank you
Unfortunately there's no documentation for qmltestrunner (I cannot one). If you only want to know how to use it, qmltestrunner.exe -h may help you. Most options are described in Qt Test Overview.
Yes. Qt Quick Test Reference Documentation - Running Tests says you need a .cpp file that contains QUICK_TEST_MAIN(xxx) and a .pro file that contains CONFIG += qmltestcase, and build this project to run your QML unit tests. The output binary file of this project is (almost the same as) qmltestrunner.
To run qmltestrunner (in Windows with Qt 5.7, for example), you need at least the following modules: Qt5Core.dll, Qt5Gui.dll, Qt5Network.dll, Qt5Qml.dll, Qt5Quick.dll, Qt5QuickTest.dll, Qt5Test.dll, Qt5Widget.dll. And some extra modules for your QML files if needed (ex. QtQuick Controls 2)
TestCase describes how to write a unit tests in QML. To run the file, simply run qmltestrunner.exe -input C:\My\Testing\File\Path\tst_myComponentTest.qml in command line.
Here's simple step-by-step example about how to write a QML component with unit tests. For example, assume that we have a ExpandButton that expands when it is clicked:
//ExpandButton.qml
import QtQuick 2.7
import QtQuick.Controls 1.2
Button {
width: 50; height: 50
onClicked: { width = 100; }
}
To test this behavior, write a tst_ExpandButton.qml:
import QtQuick 2.7
import QtTest 1.0
Item {
width: 800; height: 600
ExpandButton {
id: expandButton
anchors.centerIn: parent
}
TestCase {
name: "ExpandButton"; when: windowShown
function test_clickToExpand() {
var widthBeforeClick = expandButton.width;
mouseClick(expandButton);
var widthAfterClick = expandButton.width;
verify(widthBeforeClick < widthAfterClick);
}
}
}
Now we have two QML files, ExpandButton.qml and tst_ExpandButton.qml. Run the unit test with qmltestrunner.exe -input D:\aaa\bbb\tst_ExpandButton.qml and you can see the result:
********* Start testing of qmltestrunner *********
Config: Using QtTest library 5.7.0, Qt 5.7.0 (i386-little_endian-ilp32 shared (dynamic) release build; by MSVC 2015)
PASS : qmltestrunner::ExpandButton::initTestCase()
PASS : qmltestrunner::ExpandButton::test_clickToExpand()
PASS : qmltestrunner::ExpandButton::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 13ms
********* Finished testing of qmltestrunner *********
http://doc.qt.io/qt-5/qtquick-qtquicktest.html This will help in understanding qmltest runner
http://doc.qt.io/qt-5/qml-qttest-signalspy.html This will help in understanding signal spy which is used to catch signals
http://doc.qt.io/qt-5/qml-qttest-testcase.html This will help in writing each test case

QML Object Type is not a type error in QTCreator

Hi Everyone i am new to QT and i am having trouble loading one qml through another qml
Basically i have created a qml MyTabView(MyTabView.qml)
import QtQuick 2.3
import QtQuick.Controls 1.2
TabView {
width: 360
height: 360
Component.onCompleted: {
addTab("Tab 1", tab1)
addTab("Tab 2", tab2)
}
Component {
id: tab1
Rectangle {color: "red"}
}
Component {
id: tab2
Rectangle {color: "blue"}
}
}
and i am trying to show it through another qml(main.qml) which is in the same directory
import QtQuick 2.3
import QtQuick.Controls 1.2
import "."
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Main")
MyTabView {}
}
but when i try to run my project i get this error
QQmlApplicationEngine failed to load component
qrc:/qml/main.qml:11 TabView is not a type
Please note that i have M Caps in MyTabView.qml and that MyTabView.qml and main.qml are in the same directory.
Can someone point me what mistake i am doing ?
One thing i want to point is that when i replace all the code of MyTabView.qml instead of MyTabView {} inside main.qml,the program does not give any error and runs correctly.
Thanks in advance
Have you added the file to your Resources ?
Adding your MyTabView.qml to your project in the same directory of main.qml is not sufficient.
You have to put your QML file in the Resources (probably main.qrc/qml/) in order to have it deployed.
The editor of Qt Creator does not need this inclusion in order to find your type, therefore it displays no error.
I had a similar problem.
qrc:AGview.qml:8:15: AGraph is not a type
I solved it:
my original code (in my main.cpp):
view.setSource(QUrl("qrc:AGview.qml"));
the working one:
view.setSource(QUrl("qrc:/AGview.qml"));
I think without the slash it don't search in the actual folder.
You should rename your "TabView.qml" to something like "MyTabView.qml".
Because of that import
import "."
you have conflict of TabView from "QtQuick.Controls 1.2" and local folder "."
This error can also be caused by a component's having an error. For instance, I had this sequence of errors:
QQmlApplicationEngine failed to load component
qrc:/main.qml:6 Type MainView unavailable
qrc:/MainView.qml:27 Type ApplicationLocked unavailable
qrc:/ApplicationLocked.qml:4 MetaStateChart is not a type
It's not very clear, bu the error in MainView is caused by a problem in ApplicationLocked. When I fixed that error, everything else worked.
So contrary to the conventional wisdom of starting with the first compiler error, it may be necessary to start with the last one!
I have the same thing as you, there are 2 solutions, Frist is to lower the qt version below 6, the second is to use cmake to compile, it will be successful
Ok I have had this problem recently with QT 6.2 and QML. Using both CMake and QMake as the build systems.
The solution is to add the QML file e.g. MyTabView.qml to the resources file and make sure it is added to the CMakeLists.txt or the project file (should be done automatically for you).
Then in the top of your main.qml or wherever you are using this custom component import qrc:/. Assuming the custom qml file was added under the prefix / and therefore its resource path will be qrc:/MyTabView.qml.

QML interactive console widget

Is there a QML widget which behaves like an interactive console? (Or have I to build it manually somehow)
I want to built such console into my qml application - it should behave simmilar to standard unix terminals.
There is indeed! Check out https://github.com/Swordfish90/qmltermwidget/ or https://github.com/jorgen/yat.
Here's a short example of how to use QMLTermWidget:
QMLTermWidget {
id: terminal
font.family: "Monospace"
font.pointSize: 12
colorScheme: "cool-retro-term"
session: QMLTermSession {
id: mainsession
initialWorkingDirectory: "$HOME"
}
Component.onCompleted: mainsession.startShellProgram();
}
We're using QMLTermWidget in the Terminal app for Papyros if you're looking for an larger/more complete example of how to use it.

Javafx 2d text rendering speed up

I am a little surprised that JavaFX do consume my CPU by showing simple floating text on a screen.
My question is there any option tweaks to turn on hardware acceleration for nodes like Text? To Use GPU and not CPU when rendering 2D primitives?
Here is the simple example that consume up to 40% cpu on my 2.53Mhz core 2 duo + Nvidia 9600M GT. OS: Mac Os X. JavaFX 1.2; JRE 1.5
Edit: I put animation in the example to just simulate text scrolling. You can try and achieve the same CPU consuming by scrolling ListBox or some picture with no stopping.
package text2dacceleration;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.transform.Transform;
import javafx.scene.text.Text;
import javafx.animation.*;
def longLine = for (i in [1..45]) "{i}";
def textNodes = for (i in [1..64]) Text{content: "{longLine} line number {i}"};
var yoffset = 0.0;
Timeline {
repeatCount: Timeline.INDEFINITE
autoReverse: true
keyFrames: [
KeyFrame { time: 0s values: [yoffset => 0.0]}
KeyFrame { time: 1s values: [yoffset => 10.0]}]
}.play();
Stage {
title: "Text nodes"
width: 800
height: 600
resizable: false
scene: Scene {
content: [
VBox {
content: textNodes
transforms: bind Transform.translate(0, yoffset);
}]}}
Have you played with Timeline's framerate variable? Lowering that might help.
(The framerate description: The maximum framerate at which this animation will run, in frames per second.)
Probably won't have an impact but KeyFrame has a "canSkip" option.
Sun did a lot of work on this starting at 1.5 and through 6 but I don't know how much of it filtered through to Apple's JRE implementation. For comparison is it possible for you to update to a newer JRE such as 1.6? If you can't run the latest version of OSX and therefore can't do you have a Windows machine available on boot camp or whatever it might be worth trying one of the later Sun reference ones to see how you get on.
It might also be worth a post to the JavaFX forum - http://forums.sun.com/forum.jspa?forumID=932
Sun are usually pretty good at responding to these.
VBox {
cache: true
content: textNodes
transforms: bind Transform.translate(0, yoffset);
...
--
cache: A performance hint to the system to indicate that this Node should be cached as a bitmap.

Resources