Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
vsp2hardwarelayerintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5
6extern "C" {
7#define private priv
8#include <wayland-kms.h>
9#undef private
10}
11
12#include <private/qwaylandquickhardwarelayer_p.h>
13#include <private/qwaylandquickitem_p.h>
14#include <private/qwaylandview_p.h>
15#include <QWaylandQuickOutput>
16#include <QQuickWindow>
17
18#include <qpa/qlatformscreen_p.h>
19
20using namespace QNativeInterface::Private;
21
23
24Vsp2Buffer::Vsp2Buffer(wl_kms_buffer *kmsBuffer)
25 : dmabufFd(kmsBuffer->fd)
26 , bytesPerLine(kmsBuffer->stride)
27 , drmPixelFormat(kmsBuffer->format)
28 , size(kmsBuffer->width, kmsBuffer->height)
29{
30}
31
33 : m_hwLayer(hwLayer)
34{
35 auto *wlItem = m_hwLayer->waylandItem();
36 m_screen = dynamic_cast<QVsp2Screen*>(wlItem->window()->screen()->handle());
37 Q_ASSERT(m_screen);
38
40 integration->recreateVspLayers();
41 });
44 connect(hwLayer->waylandItem()->window(), &QQuickWindow::afterSynchronizing, this, &Vsp2Layer::updatePosition);
46 QWaylandViewPrivate::get(hwLayer->waylandItem()->view())->independentFrameCallback = true;
48}
49
51{
52 auto *kmsBuffer = nextKmsBuffer();
53
54 if (!kmsBuffer)
55 return;
56
57 m_buffer = Vsp2Buffer(kmsBuffer);
59
60 m_layerIndex = m_screen->addLayer(m_buffer.dmabufFd, m_buffer.size, m_position, m_buffer.drmPixelFormat, m_buffer.bytesPerLine);
61
62 auto *wlItem = m_hwLayer->waylandItem();
63 wlItem->surface()->frameStarted();
65}
66
68{
69 m_screen->removeLayer(m_layerIndex);
70 m_layerIndex = -1;
71 m_screen = nullptr;
72}
73
75{
76 if (!isEnabled()) {
78 return;
79 }
80
81 auto *kmsBuffer = nextKmsBuffer();
82
83 Vsp2Buffer newBuffer(kmsBuffer);
84 if (m_buffer.dmabufFd != -1) {
85 bool formatChanged = false;
86 formatChanged |= newBuffer.bytesPerLine != m_buffer.bytesPerLine;
87 formatChanged |= newBuffer.size != m_buffer.size;
88 formatChanged |= newBuffer.drmPixelFormat != m_buffer.drmPixelFormat;
89 if (formatChanged) {
90 qWarning() << "The VSP2 Wayland hardware layer integration doesn't support changing"
91 << "surface formats, this will most likely fail";
92 }
93 }
94
95 m_buffer = newBuffer;
96 m_screen->setLayerBuffer(m_layerIndex, m_buffer.dmabufFd);
97
98 auto *wlItem = m_hwLayer->waylandItem();
99 wlItem->surface()->frameStarted();
100}
101
103{
104 auto newSurface = m_hwLayer->waylandItem()->surface();
105
106 if (Q_UNLIKELY(newSurface == m_surface))
107 return;
108
109 if (this->m_surface)
111 if (newSurface)
113
114 this->m_surface = newSurface;
115}
116
118{
119 QWaylandQuickItem *wlItem = m_hwLayer->waylandItem();
120 QRectF localGeometry(0, 0, wlItem->width(), wlItem->height());
121 auto lastMatrix = QWaylandQuickItemPrivate::get(wlItem)->lastMatrix;
122 auto globalGeometry = lastMatrix.mapRect(localGeometry);
123
124 if (m_buffer.size != globalGeometry.size().toSize()) {
125 qWarning() << "wl_buffer size != WaylandQuickItem size and scaling has not been"
126 << "implemented for the vsp2 hardware layer integration";
127 }
128
129 m_position = globalGeometry.topLeft().toPoint();
130 if (isEnabled())
131 m_screen->setLayerPosition(m_layerIndex, m_position);
132}
133
135{
136 if (isEnabled()) {
137 qreal opacity = m_hwLayer->waylandItem()->opacity();
138 m_screen->setLayerAlpha(m_layerIndex, opacity);
139 }
140}
141
142wl_kms_buffer *Vsp2Layer::nextKmsBuffer()
143{
144 Q_ASSERT(m_hwLayer && m_hwLayer->waylandItem());
145 QWaylandQuickItem *wlItem = m_hwLayer->waylandItem();
146 auto view = wlItem->view();
147 Q_ASSERT(view);
148
149 view->advance();
150 auto wlBuffer = view->currentBuffer().wl_buffer();
151
152 if (!wlBuffer)
153 return nullptr;
154
155 struct wl_kms_buffer *kmsBuffer = wayland_kms_buffer_get(wlBuffer);
156
157 if (!kmsBuffer)
158 qWarning() << "Failed to get wl_kms_buffer for wl_buffer:" << wl_resource_get_id(wlBuffer);
159
160 return kmsBuffer;
161}
162
163void Vsp2HardwareLayerIntegration::enableVspLayers()
164{
165 for (auto &layer : std::as_const(m_layers)) {
166 Q_ASSERT(!layer->isEnabled());
167 layer->enableVspLayer();
168 }
169}
170
171void Vsp2HardwareLayerIntegration::disableVspLayers()
172{
173 for (auto it = m_layers.rbegin(); it != m_layers.rend(); ++it) {
174 if ((*it)->isEnabled())
175 (*it)->disableVspLayer();
176 }
177}
178
179void Vsp2HardwareLayerIntegration::sortLayersByDepth()
180{
181 std::sort(m_layers.begin(), m_layers.end(), [](auto &l1, auto &l2){
182 return l1->hwLayer()->stackingLevel() < l2->hwLayer()->stackingLevel();
183 });
184}
185
186void Vsp2HardwareLayerIntegration::recreateVspLayers() {
187 disableVspLayers();
188 sortLayersByDepth();
189 enableVspLayers();
190}
191
193{
194 if (QGuiApplication::platformName() != "eglfs") {
195 qWarning() << "Vsp2 layers are currently only supported on the eglfs platform plugin"
196 << "with the eglfs_kms_vsp2 device integration.\n"
197 << "You need to set QT_QPA_PLATFORM=eglfs and QT_QPA_EGLFS_INTEGRATION=eglfs_kms_vsp2";
198 }
199 static Vsp2HardwareLayerIntegration *s_instance = this;
200 auto screen = dynamic_cast<QVsp2Screen*>(QGuiApplication::primaryScreen()->handle());
201 screen->addBlendListener([](){
202 s_instance->sendFrameCallbacks();
203 });
204}
205
207{
208 disableVspLayers();
209 m_layers.append(QSharedPointer<Vsp2Layer>(new Vsp2Layer(hwLayer, this)));
210 sortLayersByDepth();
211 enableVspLayers();
212}
213
215{
216 disableVspLayers();
217 for (auto it = m_layers.begin(); it != m_layers.end(); ++it) {
218 if ((*it)->hwLayer() == hwLayer) {
220 break;
221 }
222 }
223 enableVspLayers();
224}
225
227{
228 for (auto &layer : std::as_const(m_layers)) {
229 if (auto *surface = layer->hwLayer()->waylandItem()->surface())
230 surface->sendFrameCallbacks();
231 }
232}
233
QScreen * primaryScreen
the primary (or default) screen of the application.
QString platformName
The name of the underlying platform plugin.
iterator erase(const_iterator begin, const_iterator end)
Definition qlist.h:889
iterator end()
Definition qlist.h:626
reverse_iterator rend()
Definition qlist.h:635
iterator begin()
Definition qlist.h:625
reverse_iterator rbegin()
Definition qlist.h:634
void append(parameter_type t)
Definition qlist.h:458
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void opacityChanged()
QQuickWindow * window() const
Returns the window in which this item is rendered.
qreal opacity
\qmlproperty real QtQuick::Item::opacity
Definition qquickitem.h:78
\inmodule QtCore\reentrant
Definition qrect.h:484
QPlatformScreen * handle() const
Get the platform screen handle.
Definition qscreen.cpp:83
QWaylandQuickItem * waylandItem() const
static const QWaylandQuickItemPrivate * get(const QWaylandQuickItem *item)
\qmltype WaylandQuickItem \instantiates QWaylandQuickItem \inqmlmodule QtWayland.Compositor
QWaylandView * view() const
Returns the view rendered by this QWaylandQuickItem.
QWaylandSurface * surface
\qmlproperty WaylandSurface QtWayland.Compositor::WaylandQuickItem::surface
Q_INVOKABLE void frameStarted()
Prepares all frame callbacks for sending.
static QWaylandViewPrivate * get(QWaylandView *view)
void add(QWaylandQuickHardwareLayer *layer) override
void remove(QWaylandQuickHardwareLayer *layer) override
QList< QSharedPointer< Vsp2Layer > > m_layers
Vsp2Layer(QWaylandQuickHardwareLayer *m_hwLayer, Vsp2HardwareLayerIntegration *integration)
QWaylandQuickHardwareLayer * hwLayer() const
QSet< QString >::iterator it
Combined button and popup list for selecting options.
@ DirectConnection
#define Q_UNLIKELY(x)
EGLOutputLayerEXT layer
#define qWarning
Definition qlogging.h:166
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
const void GLsizei GLsizei stride
GLint GLsizei width
GLuint64 GLenum GLint fd
GLint GLsizei GLsizei GLenum format
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QScreen * screen
[1]
Definition main.cpp:29
double qreal
Definition qtypes.h:187
myObject disconnect()
[26]
QQuickView * view
[0]
Vsp2Buffer()=default