Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwaylandeglwindow.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#
include
"qwaylandeglwindow_p.h"
5
6
#
include
<
QtWaylandClient
/
private
/
qwaylandscreen_p
.
h
>
7
#
include
<
QtWaylandClient
/
private
/
qwaylandsurface_p
.
h
>
8
#
include
"qwaylandglcontext_p.h"
9
10
#
include
<
QtGui
/
private
/
qeglconvenience_p
.
h
>
11
12
#
include
<
QDebug
>
13
#
include
<
QtGui
/
QWindow
>
14
#
include
<
qpa
/
qwindowsysteminterface
.
h
>
15
#
include
<
QOpenGLFramebufferObject
>
16
#
include
<
QOpenGLContext
>
17
18
QT_BEGIN_NAMESPACE
19
20
namespace
QtWaylandClient
{
21
22
QWaylandEglWindow
::
QWaylandEglWindow
(
QWindow
*
window
,
QWaylandDisplay
*
display
)
23
:
QWaylandWindow
(
window
,
display
)
24
,
m_clientBufferIntegration
(
static_cast
<
QWaylandEglClientBufferIntegration
*>(
mDisplay
->
clientBufferIntegration
()))
25
{
26
connect
(
display
, &
QWaylandDisplay
::
connected
,
this
, [
this
] {
27
m_clientBufferIntegration
=
static_cast
<
QWaylandEglClientBufferIntegration
*>(
28
mDisplay
->
clientBufferIntegration
());
29
});
30
ensureSize
();
31
}
32
33
QWaylandEglWindow
::~
QWaylandEglWindow
()
34
{
35
if
(
m_eglSurface
) {
36
eglDestroySurface
(
m_clientBufferIntegration
->
eglDisplay
(),
m_eglSurface
);
37
m_eglSurface
= 0;
38
}
39
40
if
(
m_waylandEglWindow
)
41
wl_egl_window_destroy
(
m_waylandEglWindow
);
42
43
delete
m_contentFBO
;
44
}
45
46
QWaylandWindow
::
WindowType
QWaylandEglWindow
::
windowType
()
const
47
{
48
return
QWaylandWindow
::
Egl
;
49
}
50
51
void
QWaylandEglWindow
::
ensureSize
()
52
{
53
// this is always called on the main thread
54
QRect
rect
=
geometry
();
55
QMargins
margins
=
clientSideMargins
();
56
QSize
sizeWithMargins
= (
rect
.
size
() +
QSize
(
margins
.
left
() +
margins
.
right
(),
margins
.
top
() +
margins
.
bottom
())) *
scale
();
57
{
58
QWriteLocker
lock
(&
m_bufferSizeLock
);
59
m_bufferSize
=
sizeWithMargins
;
60
}
61
62
QMutexLocker
lock
(&
m_eglSurfaceLock
);
63
updateSurface
(
false
);
64
}
65
66
void
QWaylandEglWindow
::
updateSurface
(
bool
create
)
67
{
68
// eglSurfaceLock should be locked before calling this method
69
70
QSize
sizeWithMargins
;
71
{
72
QReadLocker
lock
(&
m_bufferSizeLock
);
73
sizeWithMargins
=
m_bufferSize
;
74
}
75
76
// wl_egl_windows must have both width and height > 0
77
// mesa's egl returns NULL if we try to create a, invalid wl_egl_window, however not all EGL
78
// implementations may do that, so check the size ourself. Besides, we must deal with resizing
79
// a valid window to 0x0, which would make it invalid. Hence, destroy it.
80
if
(
sizeWithMargins
.
isEmpty
()) {
81
if
(
m_eglSurface
) {
82
eglDestroySurface
(
m_clientBufferIntegration
->
eglDisplay
(),
m_eglSurface
);
83
m_eglSurface
= 0;
84
}
85
if
(
m_waylandEglWindow
) {
86
wl_egl_window_destroy
(
m_waylandEglWindow
);
87
m_waylandEglWindow
= 0;
88
}
89
mOffset
=
QPoint
();
90
}
else
{
91
QReadLocker
locker
(&
mSurfaceLock
);
92
if
(
m_waylandEglWindow
) {
93
int
current_width
= 0;
94
int
current_height
= 0;
95
static
bool
disableResizeCheck
=
qgetenv
(
"QT_WAYLAND_DISABLE_RESIZECHECK"
).
toInt
();
96
97
if
(!
disableResizeCheck
) {
98
wl_egl_window_get_attached_size
(
m_waylandEglWindow
, &
current_width
, &
current_height
);
99
}
100
if
(
disableResizeCheck
|| (
current_width
!=
sizeWithMargins
.
width
() ||
current_height
!=
sizeWithMargins
.
height
()) ||
m_requestedSize
!=
sizeWithMargins
) {
101
wl_egl_window_resize
(
m_waylandEglWindow
,
sizeWithMargins
.
width
(),
sizeWithMargins
.
height
(),
mOffset
.
x
(),
mOffset
.
y
());
102
m_requestedSize
=
sizeWithMargins
;
103
mOffset
=
QPoint
();
104
105
m_resize
=
true
;
106
}
107
}
else
if
(
create
&&
mSurface
) {
108
wl_egl_window
*
eglWindow
=
wl_egl_window_create
(
mSurface
->
object
(),
sizeWithMargins
.
width
(),
sizeWithMargins
.
height
());
109
if
(
Q_UNLIKELY
(!
eglWindow
)) {
110
qCWarning
(
lcQpaWayland
,
"Could not create wl_egl_window with size %dx%d\n"
,
sizeWithMargins
.
width
(),
sizeWithMargins
.
height
());
111
return
;
112
}
113
114
QSurfaceFormat
fmt
=
window
()->
requestedFormat
();
115
if
(
mDisplay
->
supportsWindowDecoration
())
116
fmt
.
setAlphaBufferSize
(8);
117
EGLConfig
eglConfig
=
q_configFromGLFormat
(
m_clientBufferIntegration
->
eglDisplay
(),
fmt
);
118
setFormat
(
q_glFormatFromConfig
(
m_clientBufferIntegration
->
eglDisplay
(),
eglConfig
,
fmt
));
119
120
EGLSurface
eglSurface
=
eglCreateWindowSurface
(
m_clientBufferIntegration
->
eglDisplay
(),
eglConfig
, (
EGLNativeWindowType
)
eglWindow
, 0);
121
if
(
Q_UNLIKELY
(
eglSurface
==
EGL_NO_SURFACE
)) {
122
qCWarning
(
lcQpaWayland
,
"Could not create EGL surface (EGL error 0x%x)\n"
,
eglGetError
());
123
wl_egl_window_destroy
(
eglWindow
);
124
return
;
125
}
126
127
m_waylandEglWindow
=
eglWindow
;
128
m_eglSurface
=
eglSurface
;
129
m_requestedSize
=
sizeWithMargins
;
130
}
131
}
132
}
133
134
QRect
QWaylandEglWindow
::
contentsRect
()
const
135
{
136
QRect
r
=
geometry
();
137
QMargins
m
=
clientSideMargins
();
138
return
QRect
(
m
.
left
(),
m
.
bottom
(),
r
.
width
(),
r
.
height
());
139
}
140
141
void
QWaylandEglWindow
::
invalidateSurface
()
142
{
143
QMutexLocker
lock
(&
m_eglSurfaceLock
);
144
145
if
(
m_eglSurface
) {
146
eglDestroySurface
(
m_clientBufferIntegration
->
eglDisplay
(),
m_eglSurface
);
147
m_eglSurface
= 0;
148
}
149
if
(
m_waylandEglWindow
) {
150
wl_egl_window_destroy
(
m_waylandEglWindow
);
151
m_waylandEglWindow
=
nullptr
;
152
}
153
delete
m_contentFBO
;
154
m_contentFBO
=
nullptr
;
155
}
156
157
EGLSurface
QWaylandEglWindow
::
eglSurface
()
const
158
{
159
return
m_eglSurface
;
160
}
161
162
QMutex
*
QWaylandEglWindow
::
eglSurfaceLock
()
163
{
164
return
&
m_eglSurfaceLock
;
165
}
166
167
GLuint
QWaylandEglWindow
::
contentFBO
()
const
168
{
169
if
(!
decoration
())
170
return
0;
171
172
if
(
m_resize
|| !
m_contentFBO
) {
173
QOpenGLFramebufferObject
*
old
=
m_contentFBO
;
174
QSize
fboSize
=
geometry
().
size
() *
scale
();
175
m_contentFBO
=
new
QOpenGLFramebufferObject
(
fboSize
.
width
(),
fboSize
.
height
(),
QOpenGLFramebufferObject
::
CombinedDepthStencil
);
176
177
delete
old
;
178
m_resize
=
false
;
179
}
180
181
return
m_contentFBO
->
handle
();
182
}
183
184
GLuint
QWaylandEglWindow
::
contentTexture
()
const
185
{
186
return
m_contentFBO
->
texture
();
187
}
188
189
void
QWaylandEglWindow
::
bindContentFBO
()
190
{
191
if
(
decoration
()) {
192
contentFBO
();
193
m_contentFBO
->
bind
();
194
}
195
}
196
197
}
198
199
QT_END_NAMESPACE
200
201
#
include
"moc_qwaylandeglwindow_p.cpp"
QPlatformGraphicsBufferHelper
\inmodule QtGui
QtWaylandClient
Definition
qwaylandclientextension.h:15
qtbase
src
plugins
platforms
wayland
plugins
hardwareintegration
wayland-egl
qwaylandeglwindow.cpp
Generated on
for Qt by
1.14.0