Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
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
// Qt-Security score:significant reason:default
4
5
#
include
"vsp2hardwarelayerintegration.h"
6
7
extern
"C"
{
8
#
define
private
priv
9
#
include
<
wayland
-
kms
.
h
>
10
#
undef
private
11
}
12
13
#
include
<
private
/
qwaylandquickhardwarelayer_p
.
h
>
14
#
include
<
private
/
qwaylandquickitem_p
.
h
>
15
#
include
<
private
/
qwaylandview_p
.
h
>
16
#
include
<
QWaylandQuickOutput
>
17
#
include
<
QQuickWindow
>
18
19
#
include
<
qpa
/
qlatformscreen_p
.
h
>
20
21
using
namespace
QNativeInterface::
Private
;
22
23
QT_BEGIN_NAMESPACE
24
25
Vsp2Buffer::Vsp2Buffer(wl_kms_buffer *kmsBuffer)
26
: dmabufFd(kmsBuffer->fd)
27
, bytesPerLine(kmsBuffer->stride)
28
, drmPixelFormat(kmsBuffer->format)
29
, size(kmsBuffer->width, kmsBuffer->height)
30
{
31
}
32
33
Vsp2Layer
::Vsp2Layer(QWaylandQuickHardwareLayer *hwLayer,
Vsp2HardwareLayerIntegration
*integration)
34
: m_hwLayer(hwLayer)
35
{
36
auto
*wlItem = m_hwLayer->waylandItem();
37
m_screen =
dynamic_cast
<QVsp2Screen*>(wlItem->window()->screen()->handle());
38
Q_ASSERT(m_screen);
39
40
connect(hwLayer, &QWaylandQuickHardwareLayer::stackingLevelChanged,
this
, [integration](){
41
integration->recreateVspLayers();
42
});
43
connect(hwLayer->waylandItem(), &QWaylandQuickItem::surfaceChanged,
this
, &
Vsp2Layer
::
handleSurfaceChanged
);
44
connect(hwLayer->waylandItem(), &QQuickItem::opacityChanged,
this
, &
Vsp2Layer
::
updateOpacity
);
45
connect(hwLayer->waylandItem()->window(), &QQuickWindow::afterSynchronizing,
this
, &
Vsp2Layer
::
updatePosition
);
46
hwLayer->setSceneGraphPainting(
false
);
47
QWaylandViewPrivate::get(hwLayer->waylandItem()->view())->independentFrameCallback =
true
;
48
handleSurfaceChanged
(
)
;
49
}
50
51
void
Vsp2Layer
::
enableVspLayer
()
52
{
53
auto
*kmsBuffer = nextKmsBuffer();
54
55
if
(!kmsBuffer)
56
return
;
57
58
m_buffer = Vsp2Buffer(kmsBuffer);
59
updatePosition
(
)
;
60
61
m_layerIndex = m_screen->addLayer(m_buffer.dmabufFd, m_buffer.size, m_position, m_buffer.drmPixelFormat, m_buffer.bytesPerLine);
62
63
auto
*wlItem = m_hwLayer->waylandItem();
64
wlItem->surface()->frameStarted();
65
updateOpacity
(
)
;
66
}
67
68
void
Vsp2Layer
::
disableVspLayer
()
69
{
70
m_screen->removeLayer(m_layerIndex);
71
m_layerIndex = -1;
72
m_screen =
nullptr
;
73
}
74
75
void
Vsp2Layer
::handleBufferCommitted()
76
{
77
if
(!
isEnabled
(
)
) {
78
enableVspLayer
(
)
;
79
return
;
80
}
81
82
auto
*kmsBuffer = nextKmsBuffer();
83
84
Vsp2Buffer
newBuffer
(
kmsBuffer
)
;
85
if
(m_buffer.dmabufFd != -1) {
86
bool
formatChanged =
false
;
87
formatChanged |= newBuffer.bytesPerLine != m_buffer.bytesPerLine;
88
formatChanged |= newBuffer.size != m_buffer.size;
89
formatChanged |= newBuffer.drmPixelFormat != m_buffer.drmPixelFormat;
90
if
(formatChanged) {
91
qWarning() <<
"The VSP2 Wayland hardware layer integration doesn't support changing"
92
<<
"surface formats, this will most likely fail"
;
93
}
94
}
95
96
m_buffer = newBuffer;
97
m_screen->setLayerBuffer(m_layerIndex, m_buffer.dmabufFd);
98
99
auto
*wlItem = m_hwLayer->waylandItem();
100
wlItem->surface()->frameStarted();
101
}
102
103
void
Vsp2Layer
::
handleSurfaceChanged
()
104
{
105
auto
newSurface = m_hwLayer->waylandItem()->surface();
106
107
if
(Q_UNLIKELY(newSurface == m_surface))
108
return
;
109
110
if
(
this
->m_surface)
111
disconnect(
this
->m_surface, &QWaylandSurface::redraw,
this
, &Vsp2Layer::handleBufferCommitted);
112
if
(newSurface)
113
connect(newSurface, &QWaylandSurface::redraw,
this
, &Vsp2Layer::handleBufferCommitted, Qt::DirectConnection);
114
115
this
->m_surface = newSurface;
116
}
117
118
void
Vsp2Layer
::
updatePosition
()
119
{
120
QWaylandQuickItem *wlItem = m_hwLayer->waylandItem();
121
QRectF localGeometry(0, 0, wlItem->width(), wlItem->height());
122
auto
lastMatrix = QWaylandQuickItemPrivate::get(wlItem)->lastMatrix;
123
auto
globalGeometry = lastMatrix.mapRect(localGeometry);
124
125
if
(m_buffer.size != globalGeometry.size().toSize()) {
126
qWarning() <<
"wl_buffer size != WaylandQuickItem size and scaling has not been"
127
<<
"implemented for the vsp2 hardware layer integration"
;
128
}
129
130
m_position = globalGeometry.topLeft().toPoint();
131
if
(isEnabled())
132
m_screen->setLayerPosition(m_layerIndex, m_position);
133
}
134
135
void
Vsp2Layer
::
updateOpacity
()
136
{
137
if
(
isEnabled
(
)
) {
138
qreal opacity = m_hwLayer->waylandItem()->opacity();
139
m_screen->setLayerAlpha(m_layerIndex, opacity);
140
}
141
}
142
143
wl_kms_buffer *
Vsp2Layer
::nextKmsBuffer()
144
{
145
Q_ASSERT(m_hwLayer && m_hwLayer->waylandItem());
146
QWaylandQuickItem *wlItem = m_hwLayer->waylandItem();
147
auto
view = wlItem->view();
148
Q_ASSERT(view);
149
150
view->advance();
151
auto
wlBuffer = view->currentBuffer().wl_buffer();
152
153
if
(!wlBuffer)
154
return
nullptr
;
155
156
struct
wl_kms_buffer *kmsBuffer = wayland_kms_buffer_get(wlBuffer);
157
158
if
(!kmsBuffer)
159
qWarning() <<
"Failed to get wl_kms_buffer for wl_buffer:"
<< wl_resource_get_id(wlBuffer);
160
161
return
kmsBuffer;
162
}
163
164
void
Vsp2HardwareLayerIntegration
::enableVspLayers()
165
{
166
for
(
auto
&layer : std::as_const(m_layers)) {
167
Q_ASSERT(!layer->isEnabled());
168
layer->enableVspLayer();
169
}
170
}
171
172
void
Vsp2HardwareLayerIntegration
::disableVspLayers()
173
{
174
for
(
auto
it = m_layers.rbegin(); it != m_layers.rend(); ++it) {
175
if
((*it)->isEnabled())
176
(*it)->disableVspLayer();
177
}
178
}
179
180
void
Vsp2HardwareLayerIntegration
::sortLayersByDepth()
181
{
182
std::sort(m_layers.begin(), m_layers.end(), [](
auto
&l1,
auto
&l2){
183
return
l1->hwLayer()->stackingLevel() < l2->hwLayer()->stackingLevel();
184
});
185
}
186
187
void
Vsp2HardwareLayerIntegration
::recreateVspLayers() {
188
disableVspLayers();
189
sortLayersByDepth();
190
enableVspLayers();
191
}
192
193
Vsp2HardwareLayerIntegration
::Vsp2HardwareLayerIntegration()
194
{
195
if
(QGuiApplication::platformName() !=
"eglfs"
) {
196
qWarning() <<
"Vsp2 layers are currently only supported on the eglfs platform plugin"
197
<<
"with the eglfs_kms_vsp2 device integration.\n"
198
<<
"You need to set QT_QPA_PLATFORM=eglfs and QT_QPA_EGLFS_INTEGRATION=eglfs_kms_vsp2"
;
199
}
200
static
Vsp2HardwareLayerIntegration
*s_instance =
this
;
201
auto
screen =
dynamic_cast
<QVsp2Screen*>(QGuiApplication::primaryScreen()->handle());
202
screen->addBlendListener([](){
203
s_instance
->
sendFrameCallbacks
(
)
;
204
});
205
}
206
207
void
Vsp2HardwareLayerIntegration
::
add
(QWaylandQuickHardwareLayer *hwLayer)
208
{
209
disableVspLayers();
210
m_layers.append(QSharedPointer<Vsp2Layer>(
new
Vsp2Layer(hwLayer,
this
)));
211
sortLayersByDepth();
212
enableVspLayers();
213
}
214
215
void
Vsp2HardwareLayerIntegration
::
remove
(QWaylandQuickHardwareLayer *hwLayer)
216
{
217
disableVspLayers();
218
for
(
auto
it = m_layers.begin(); it != m_layers.end(); ++it) {
219
if
((*it)->hwLayer() == hwLayer) {
220
m_layers.erase(it);
221
break
;
222
}
223
}
224
enableVspLayers();
225
}
226
227
void
Vsp2HardwareLayerIntegration
::
sendFrameCallbacks
()
228
{
229
for
(
auto
&layer : std::as_const(m_layers)) {
230
if
(
auto
*surface = layer->hwLayer()->waylandItem()->surface())
231
surface->sendFrameCallbacks();
232
}
233
}
234
235
QT_END_NAMESPACE
Vsp2HardwareLayerIntegration
Definition
vsp2hardwarelayerintegration.h:29
Vsp2HardwareLayerIntegration::sendFrameCallbacks
void sendFrameCallbacks()
Definition
vsp2hardwarelayerintegration.cpp:227
Vsp2HardwareLayerIntegration::add
void add(QWaylandQuickHardwareLayer *layer) override
Definition
vsp2hardwarelayerintegration.cpp:207
Vsp2HardwareLayerIntegration::remove
void remove(QWaylandQuickHardwareLayer *layer) override
Definition
vsp2hardwarelayerintegration.cpp:215
Vsp2Layer
Definition
vsp2hardwarelayerintegration.h:59
Vsp2Layer::updateOpacity
void updateOpacity()
Definition
vsp2hardwarelayerintegration.cpp:135
Vsp2Layer::updatePosition
void updatePosition()
Definition
vsp2hardwarelayerintegration.cpp:118
Vsp2Layer::disableVspLayer
void disableVspLayer()
Definition
vsp2hardwarelayerintegration.cpp:68
Vsp2Layer::handleSurfaceChanged
void handleSurfaceChanged()
Definition
vsp2hardwarelayerintegration.cpp:103
Vsp2Layer::isEnabled
bool isEnabled()
Definition
vsp2hardwarelayerintegration.h:65
Vsp2Layer::enableVspLayer
void enableVspLayer()
Definition
vsp2hardwarelayerintegration.cpp:51
QNativeInterface
Definition
qnativeinterface.h:51
Vsp2Buffer
Definition
vsp2hardwarelayerintegration.h:48
Vsp2Buffer::Vsp2Buffer
Vsp2Buffer(wl_kms_buffer *kmsBuffer)
Definition
vsp2hardwarelayerintegration.cpp:25
qtwayland
src
hardwareintegration
compositor
hardwarelayer
vsp2
vsp2hardwarelayerintegration.cpp
Generated on
for Qt by
1.18.0