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
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
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{
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.
void setRedBufferSize(int size)
Set the desired size in bits of the red channel of the color buffer.
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:946
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:168
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLenum GLuint buffer
GLint GLsizei width
GLint GLsizei GLsizei GLenum format
#define Q_UNUSED(x)
aWidget window() -> setWindowTitle("New Window Title")
[2]