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