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
qwaylandbrcmeglwindow.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
6
7#include <QtWaylandClient/private/qwaylandbuffer_p.h>
8#include <QtWaylandClient/private/qwaylandscreen_p.h>
10
11#include <QtGui/private/qeglconvenience_p.h>
12
13#include <QtGui/QWindow>
14#include <qpa/qwindowsysteminterface.h>
15
16#include <EGL/eglext_brcm.h>
17
18#include "wayland-brcm-client-protocol.h"
19
21
22namespace QtWaylandClient {
23
25{
26public:
27 QWaylandBrcmBuffer(QWaylandDisplay *display,
28 struct qt_brcm *brcm,
29 const QSize &size,
30 EGLint *data,
31 int count,
32 struct wl_event_queue *eventQueue)
33 : m_size(size)
35 , m_eventQueue(eventQueue)
36 {
37 wl_array_init(&m_array);
38 m_data = static_cast<EGLint *>(wl_array_add(&m_array, count * sizeof(EGLint)));
39
40 for (int i = 0; i < count; ++i)
41 m_data[i] = data[i];
42
43 mBuffer = qt_brcm_create_buffer(brcm, size.width(), size.height(), &m_array);
44 wl_proxy_set_queue(reinterpret_cast<struct wl_proxy*>(mBuffer), m_eventQueue);
45
46 static const struct wl_buffer_listener buffer_listener = {
47 QWaylandBrcmBuffer::buffer_release
48 };
49
50 wl_buffer_add_listener(mBuffer, &buffer_listener, this);
51 }
52
54 {
55 wl_array_release(&m_array);
56 wl_buffer_destroy(mBuffer);
57 mBuffer = nullptr;
58 }
59
60 QSize size() const { return m_size; }
61
62 void bind()
63 {
64 m_released = false;
65 }
66
68 {
69 if (m_released)
70 return;
71 while (!m_released) {
72 wl_display_dispatch_queue(m_display->wl_display(), m_eventQueue);
73 }
74 }
75
76 static void buffer_release(void *data, wl_buffer *buffer)
77 {
78 Q_UNUSED(buffer);
79 static_cast<QWaylandBrcmBuffer *>(data)->m_released = true;
80 }
81
82private:
83
84 QSize m_size;
85 bool m_released = true;
86 wl_array m_array;
87 EGLint *m_data = nullptr;
88 QWaylandDisplay *m_display = nullptr;
89 struct wl_event_queue *m_eventQueue = nullptr;
90};
91
92QWaylandBrcmEglWindow::QWaylandBrcmEglWindow(QWindow *window, QWaylandDisplay *display)
93 : QWaylandWindow(window, display)
94 , m_eglIntegration(static_cast<QWaylandBrcmEglIntegration *>(mDisplay->clientBufferIntegration()))
95 , m_format(window->format())
96 , m_eventQueue(wl_display_create_queue(mDisplay->wl_display()))
97{
98}
99
101{
102 destroyEglSurfaces();
103}
104
106{
107 return QWaylandWindow::Egl;
108}
109
110void QWaylandBrcmEglWindow::setGeometry(const QRect &rect)
111{
112 destroyEglSurfaces();
113 QWaylandWindow::setGeometry(rect);
114}
115
117{
118 return m_format;
119}
120
121void QWaylandBrcmEglWindow::destroyEglSurfaces()
122{
123 for (int i = 0; i < m_count; ++i) {
124 if (m_eglSurfaces[i]) {
125 eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurfaces[i]);
126 m_eglSurfaces[i] = 0;
127 // the server does this
128 //m_eglIntegration->eglDestroyGlobalImageBRCM(&m_globalImages[5*i]);
129 delete m_buffers[i];
130 }
131 }
132
133 m_count = 0;
134 m_current = 0;
135}
136
137QSurfaceFormat brcmFixFormat(const QSurfaceFormat &f)
138{
139 QSurfaceFormat format = f;
140 format.setRedBufferSize(8);
141 format.setGreenBufferSize(8);
142 format.setBlueBufferSize(8);
143 format.setAlphaBufferSize(8);
144 return format;
145}
146
147void QWaylandBrcmEglWindow::createEglSurfaces()
148{
149 QSize size(geometry().size());
150
151 m_count = window()->format().swapBehavior() == QSurfaceFormat::TripleBuffer ? 3 : 2;
152
153 EGLConfig eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), brcmFixFormat(window()->format()), true, EGL_PIXMAP_BIT);
154
155 m_format = q_glFormatFromConfig(m_eglIntegration->eglDisplay(), eglConfig);
156
157 EGLint pixel_format = EGL_PIXEL_FORMAT_ARGB_8888_BRCM;
158
159 EGLint rt;
160 eglGetConfigAttrib(m_eglIntegration->eglDisplay(), eglConfig, EGL_RENDERABLE_TYPE, &rt);
161
162 if (rt & EGL_OPENGL_ES_BIT) {
163 pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES_BRCM;
164 pixel_format |= EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM;
165 }
166
167 if (rt & EGL_OPENGL_ES2_BIT) {
168 pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM;
169 pixel_format |= EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM;
170 }
171
172 if (rt & EGL_OPENVG_BIT) {
173 pixel_format |= EGL_PIXEL_FORMAT_RENDER_VG_BRCM;
174 pixel_format |= EGL_PIXEL_FORMAT_VG_IMAGE_BRCM;
175 }
176
177 if (rt & EGL_OPENGL_BIT) {
178 pixel_format |= EGL_PIXEL_FORMAT_RENDER_GL_BRCM;
179 }
180
181 memset(m_globalImages, 0, 5 * m_count * sizeof(EGLint));
182 for (int i = 0; i < m_count; ++i) {
183 m_eglIntegration->eglCreateGlobalImageBRCM(size.width(), size.height(), pixel_format,
184 0, size.width() * 4, &m_globalImages[5*i]);
185
186 m_globalImages[5*i+2] = size.width();
187 m_globalImages[5*i+3] = size.height();
188 m_globalImages[5*i+4] = pixel_format;
189
190 EGLint attrs[] = {
191 EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB,
192 EGL_VG_ALPHA_FORMAT, pixel_format & EGL_PIXEL_FORMAT_ARGB_8888_PRE_BRCM ? EGL_VG_ALPHA_FORMAT_PRE : EGL_VG_ALPHA_FORMAT_NONPRE,
193 EGL_NONE
194 };
195
196 m_eglSurfaces[i] = eglCreatePixmapSurface(m_eglIntegration->eglDisplay(), eglConfig, (EGLNativePixmapType)&m_globalImages[5*i], attrs);
197 if (m_eglSurfaces[i] == EGL_NO_SURFACE)
198 qFatal("eglCreatePixmapSurface failed: %x, global image id: %d %d\n", eglGetError(), m_globalImages[5*i], m_globalImages[5*i+1]);
199 m_buffers[i] = new QWaylandBrcmBuffer(mDisplay, m_eglIntegration->waylandBrcm(), size, &m_globalImages[5*i], 5, m_eventQueue);
200 }
201}
202
204{
205 if (m_eglIntegration->eglFlushBRCM) {
206 m_eglIntegration->eglFlushBRCM();
207 } else {
208 glFlush();
209 glFinish();
210 }
211
212 if (!m_count)
213 return;
214
215 m_buffers[m_current]->bind();
216 commit(m_buffers[m_current], QRegion(0, 0, geometry().size().width(), geometry().size().height()));
217
218 m_current = (m_current + 1) % m_count;
219 m_buffers[m_current]->waitForRelease();
220}
221
222bool QWaylandBrcmEglWindow::makeCurrent(EGLContext context)
223{
224 if (!m_count)
225 const_cast<QWaylandBrcmEglWindow *>(this)->createEglSurfaces();
226 return eglMakeCurrent(m_eglIntegration->eglDisplay(), m_eglSurfaces[m_current], m_eglSurfaces[m_current], context);
227}
228
229}
230
231QT_END_NAMESPACE
QWaylandBrcmBuffer(QWaylandDisplay *display, struct qt_brcm *brcm, const QSize &size, EGLint *data, int count, struct wl_event_queue *eventQueue)
static void buffer_release(void *data, wl_buffer *buffer)
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.
Combined button and popup list for selecting options.
QSurfaceFormat brcmFixFormat(const QSurfaceFormat &f)