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