Qt 6.x
The Qt SDK
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:
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)
33 , m_display(display)
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 = {
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 {
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
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
110{
111 destroyEglSurfaces();
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
137{
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
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
NSData * m_data
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 qrect.h:30
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
\inmodule QtCore
Definition qsize.h:25
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
SwapBehavior swapBehavior() const
Returns the configured swap behaviour.
\inmodule QtGui
Definition qwindow.h:63
QSurfaceFormat format() const override
Returns the actual format of this window.
Definition qwindow.cpp:888
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)
PFNEGLCREATEGLOBALIMAGEBRCMPROC eglCreateGlobalImageBRCM
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
QWaylandBrcmEglWindow(QWindow *window, QWaylandDisplay *display)
QSurfaceFormat format() const override
Returns the actual surface format of the window.
struct wl_display * wl_display() const
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
rect
[4]
struct wl_display * display
Definition linuxdmabuf.h:41
Combined button and popup list for selecting options.
QSurfaceFormat brcmFixFormat(const QSurfaceFormat &f)
static void * context
EGLConfig q_configFromGLFormat(EGLDisplay display, const QSurfaceFormat &format, bool highestPixelFormat, int surfaceType)
QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config, const QSurfaceFormat &referenceFormat)
static struct AttrInfo attrs[]
#define qFatal
Definition qlogging.h:164
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLenum GLuint buffer
GLint GLsizei width
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei GLsizei GLenum format
#define Q_UNUSED(x)
aWidget window() -> setWindowTitle("New Window Title")
[2]