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
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
5
6#include <QtWaylandClient/private/qwaylandscreen_p.h>
7#include <QtWaylandClient/private/qwaylandsurface_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
19
20namespace QtWaylandClient {
21
24 , m_clientBufferIntegration(static_cast<QWaylandEglClientBufferIntegration *>(mDisplay->clientBufferIntegration()))
25 , m_format(window->requestedFormat())
26{
28 m_clientBufferIntegration = static_cast<QWaylandEglClientBufferIntegration *>(
30 });
31}
32
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
50
55
57{
59 // If the surface was invalidated through invalidateSurface() and
60 // we're now getting a resize we don't want to create it again.
61 // Just resize the wl_egl_window, the EGLSurface will be created
62 // the next time makeCurrent is called.
63 updateSurface(false);
64}
65
67{
68 QMargins margins = clientSideMargins();
70 QSize sizeWithMargins = (rect.size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom())) * scale();
71
72 // wl_egl_windows must have both width and height > 0
73 // mesa's egl returns NULL if we try to create a, invalid wl_egl_window, however not all EGL
74 // implementations may do that, so check the size ourself. Besides, we must deal with resizing
75 // a valid window to 0x0, which would make it invalid. Hence, destroy it.
76 if (sizeWithMargins.isEmpty()) {
77 if (m_eglSurface) {
78 eglDestroySurface(m_clientBufferIntegration->eglDisplay(), m_eglSurface);
79 m_eglSurface = 0;
80 }
81 if (m_waylandEglWindow) {
82 wl_egl_window_destroy(m_waylandEglWindow);
83 m_waylandEglWindow = 0;
84 }
85 mOffset = QPoint();
86 } else {
88 if (m_waylandEglWindow) {
89 int current_width, current_height;
90 static bool disableResizeCheck = qgetenv("QT_WAYLAND_DISABLE_RESIZECHECK").toInt();
91
92 if (!disableResizeCheck) {
93 wl_egl_window_get_attached_size(m_waylandEglWindow, &current_width, &current_height);
94 }
95 if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height()) || m_requestedSize != sizeWithMargins) {
96 wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y());
97 m_requestedSize = sizeWithMargins;
98 mOffset = QPoint();
99
100 m_resize = true;
101 }
102 } else if (create && mSurface) {
103 m_waylandEglWindow = wl_egl_window_create(mSurface->object(), sizeWithMargins.width(), sizeWithMargins.height());
104 m_requestedSize = sizeWithMargins;
105 }
106
107 if (!m_eglSurface && m_waylandEglWindow && create) {
108 EGLNativeWindowType eglw = (EGLNativeWindowType) m_waylandEglWindow;
109 QSurfaceFormat fmt = window()->requestedFormat();
112 EGLConfig eglConfig = q_configFromGLFormat(m_clientBufferIntegration->eglDisplay(), fmt);
113 m_format = q_glFormatFromConfig(m_clientBufferIntegration->eglDisplay(), eglConfig, fmt);
114 m_eglSurface = eglCreateWindowSurface(m_clientBufferIntegration->eglDisplay(), eglConfig, eglw, 0);
115 if (Q_UNLIKELY(m_eglSurface == EGL_NO_SURFACE))
116 qCWarning(lcQpaWayland, "Could not create EGL surface (EGL error 0x%x)\n", eglGetError());
117 }
118 }
119}
120
122{
123 QRect r = geometry();
125 return QRect(m.left(), m.bottom(), r.width(), r.height());
126}
127
129{
130 return m_format;
131}
132
134{
135 if (m_eglSurface) {
136 eglDestroySurface(m_clientBufferIntegration->eglDisplay(), m_eglSurface);
137 m_eglSurface = 0;
138 }
139 if (m_waylandEglWindow) {
140 wl_egl_window_destroy(m_waylandEglWindow);
141 m_waylandEglWindow = nullptr;
142 }
143 delete m_contentFBO;
144 m_contentFBO = nullptr;
145}
146
148{
149 return m_eglSurface;
150}
151
153{
154 if (!decoration())
155 return 0;
156
157 if (m_resize || !m_contentFBO) {
158 QOpenGLFramebufferObject *old = m_contentFBO;
159 QSize fboSize = geometry().size() * scale();
160 m_contentFBO = new QOpenGLFramebufferObject(fboSize.width(), fboSize.height(), QOpenGLFramebufferObject::CombinedDepthStencil);
161
162 delete old;
163 m_resize = false;
164 }
165
166 return m_contentFBO->handle();
167}
168
170{
171 return m_contentFBO->texture();
172}
173
175{
176 if (decoration()) {
177 contentFBO();
178 m_contentFBO->bind();
179 }
180}
181
182}
183
185
186#include "moc_qwaylandeglwindow_p.cpp"
\inmodule QtCore
Definition qmargins.h:24
constexpr int bottom() const noexcept
Returns the bottom margin.
Definition qmargins.h:115
constexpr int left() const noexcept
Returns the left margin.
Definition qmargins.h:106
constexpr int right() const noexcept
Returns the right margin.
Definition qmargins.h:112
constexpr int top() const noexcept
Returns the top margin.
Definition qmargins.h:109
The QOpenGLFramebufferObject class encapsulates an OpenGL framebuffer object.
GLuint handle() const
Returns the OpenGL framebuffer object handle for this framebuffer object (returned by the {glGenFrame...
GLuint texture() const
Returns the texture id for the texture attached as the default rendering target in this framebuffer o...
bool bind()
Switches rendering from the default, windowing system provided framebuffer to this framebuffer object...
QWindow * window() const
Returns the window which belongs to the QPlatformWindow.
virtual QRect geometry() const
Returns the current geometry of a window.
\inmodule QtCore\reentrant
Definition qpoint.h:25
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:130
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:135
\inmodule QtCore
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore
Definition qsize.h:25
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
void setAlphaBufferSize(int size)
Set the desired size in bits of the alpha channel of the color buffer.
\inmodule QtGui
Definition qwindow.h:63
QWaylandClientBufferIntegration * clientBufferIntegration() const
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
QSurfaceFormat format() const override
Returns the actual surface format of the window.
WindowType windowType() const override
void invalidateSurface() override
Invalidates the window's surface by releasing its surface buffers.
QWaylandEglWindow(QWindow *window, QWaylandDisplay *display)
QWaylandAbstractDecoration * decoration() const
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
QScopedPointer< QWaylandSurface > mSurface
rect
[4]
struct wl_display * display
Definition linuxdmabuf.h:41
Combined button and popup list for selecting options.
#define Q_UNLIKELY(x)
EGLConfig q_configFromGLFormat(EGLDisplay display, const QSurfaceFormat &format, bool highestPixelFormat, int surfaceType)
QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config, const QSurfaceFormat &referenceFormat)
typedef EGLSurface(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay dpy
#define qCWarning(category,...)
const GLfloat * m
GLboolean r
[2]
#define GLuint
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QVideoFrameFormat::PixelFormat fmt
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
aWidget window() -> setWindowTitle("New Window Title")
[2]
view create()