Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqnxeglwindow.cpp
Go to the documentation of this file.
1// Copyright (C) 2013 - 2014 BlackBerry Limited. All rights reserved.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
5#include "qqnxeglwindow.h"
6#include "qqnxscreen.h"
7#include "qqnxglcontext.h"
8
9#include <QDebug>
10
11#include <errno.h>
12
13#if defined(QQNXEGLWINDOW_DEBUG)
14#define qEglWindowDebug qDebug
15#else
16#define qEglWindowDebug QT_NO_QDEBUG_MACRO
17#endif
18
20
21QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow) :
22 QQnxWindow(window, context, needRootWindow),
23 m_newSurfaceRequested(true),
24 m_eglDisplay(EGL_NO_DISPLAY),
25 m_eglSurface(EGL_NO_SURFACE)
26{
27 initWindow();
28
29 m_requestedBufferSize = shouldMakeFullScreen() ? screen()->geometry().size() : window->geometry().size();
30}
31
33{
34 // Cleanup EGL surface if it exists
35 destroyEGLSurface();
36}
37
39{
40 return m_eglSurface != EGL_NO_SURFACE;
41}
42
44{
45 if (m_newSurfaceRequested.testAndSetOrdered(true, false)) {
46 const QMutexLocker locker(&m_mutex); // Set geometry must not reset the requestedBufferSize till
47 // the surface is created
48
49 if (m_requestedBufferSize != bufferSize() || m_eglSurface == EGL_NO_SURFACE) {
50 if (m_eglSurface != EGL_NO_SURFACE) {
51 context->doneCurrent();
52 destroyEGLSurface();
53 }
54 createEGLSurface(context);
55 } else {
56 // Must've been a sequence of unprocessed changes returning us to the original size.
58 }
59 }
60}
61
62void QQnxEglWindow::createEGLSurface(QQnxGLContext *context)
63{
64 if (context->format().renderableType() != QSurfaceFormat::OpenGLES) {
65 qFatal("QQnxEglWindow: renderable type is not OpenGLES");
66 return;
67 }
68
69 // Set window usage
70 int usage = SCREEN_USAGE_OPENGL_ES2;
71#if _SCREEN_VERSION >= _SCREEN_MAKE_VERSION(1, 0, 0)
72 if (context->format().majorVersion() == 3)
73 usage |= SCREEN_USAGE_OPENGL_ES3;
74#endif
75
76 const int result = screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_USAGE, &usage);
77 if (Q_UNLIKELY(result != 0))
78 qFatal("QQnxEglWindow: failed to set window usage, errno=%d", errno);
79
80 if (!m_requestedBufferSize.isValid()) {
81 qWarning("QQNX: Trying to create 0 size EGL surface. "
82 "Please set a valid window size before calling QOpenGLContext::makeCurrent()");
83 return;
84 }
85
86 m_eglDisplay = context->eglDisplay();
87 m_eglConfig = context->eglConfig();
88 m_format = context->format();
89
90 // update the window's buffers before we create the EGL surface
91 setBufferSize(m_requestedBufferSize);
92
93 const EGLint eglSurfaceAttrs[] =
94 {
95 EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
96 EGL_NONE
97 };
98
99 qEglWindowDebug() << "Creating EGL surface from" << this << context
100 << window()->surfaceType() << window()->type();
101
102 // Create EGL surface
103 EGLSurface eglSurface = eglCreateWindowSurface(
104 m_eglDisplay,
105 m_eglConfig,
106 (EGLNativeWindowType) nativeHandle(),
107 eglSurfaceAttrs);
108
109 if (eglSurface == EGL_NO_SURFACE)
110 qWarning("QQNX: failed to create EGL surface, err=%d", eglGetError());
111
112 m_eglSurface = eglSurface;
113}
114
115void QQnxEglWindow::destroyEGLSurface()
116{
117 // Destroy EGL surface if it exists
118 if (m_eglSurface != EGL_NO_SURFACE) {
119 EGLBoolean eglResult = eglDestroySurface(m_eglDisplay, m_eglSurface);
120 if (Q_UNLIKELY(eglResult != EGL_TRUE))
121 qFatal("QQNX: failed to destroy EGL surface, err=%d", eglGetError());
122 }
123
124 m_eglSurface = EGL_NO_SURFACE;
125}
126
128{
129 return m_eglSurface;
130}
131
133{
134 //If this is the root window, it has to be shown fullscreen
135 const QRect &newGeometry = shouldMakeFullScreen() ? screen()->geometry() : rect;
136
137 //We need to request that the GL context updates
138 // the EGLsurface on which it is rendering.
139 {
140 // We want the setting of the atomic bool in the GL context to be atomic with
141 // setting m_requestedBufferSize and therefore extended the scope to include
142 // that test.
143 const QMutexLocker locker(&m_mutex);
144 m_requestedBufferSize = newGeometry.size();
145 if (isInitialized() && bufferSize() != newGeometry.size())
146 m_newSurfaceRequested.testAndSetRelease(false, true);
147 }
148 QQnxWindow::setGeometry(newGeometry);
149}
150
152{
153 // Extract size of color channels from window format
154 const int redSize = m_format.redBufferSize();
155 if (Q_UNLIKELY(redSize == -1))
156 qFatal("QQnxWindow: red size not defined");
157
158 const int greenSize = m_format.greenBufferSize();
159 if (Q_UNLIKELY(greenSize == -1))
160 qFatal("QQnxWindow: green size not defined");
161
162 const int blueSize = m_format.blueBufferSize();
163 if (Q_UNLIKELY(blueSize == -1))
164 qFatal("QQnxWindow: blue size not defined");
165
166 // select matching native format
167 if (redSize == 5 && greenSize == 6 && blueSize == 5)
168 return SCREEN_FORMAT_RGB565;
169 else if (redSize == 8 && greenSize == 8 && blueSize == 8)
170 return SCREEN_FORMAT_RGBA8888;
171
172 qFatal("QQnxWindow: unsupported pixel format");
173}
174
176{
177 m_requestedBufferSize = QSize();
178}
179
bool testAndSetOrdered(T expectedValue, T newValue) noexcept
bool testAndSetRelease(T expectedValue, T newValue) noexcept
\inmodule QtCore
Definition qmutex.h:317
virtual QRect geometry() const =0
Reimplement in subclass to return the pixel geometry of the screen.
QWindow * window() const
Returns the window which belongs to the QPlatformWindow.
bool isInitialized() const
void resetBuffers() override
int pixelFormat() const override
EGLSurface surface() const
void ensureInitialized(QQnxGLContext *context)
QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow)
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
The QQnxWindow is the base class of the various classes used as instances of QPlatformWindow in the Q...
Definition qqnxwindow.h:28
bool shouldMakeFullScreen() const
void initWindow()
screen_window_t nativeHandle() const
Definition qqnxwindow.h:42
void setBufferSize(const QSize &size)
QPlatformScreen * screen() const override
Returns the platform screen handle corresponding to this platform window, or null if the window is no...
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
QSize bufferSize() const
Definition qqnxwindow.h:45
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:241
\inmodule QtCore
Definition qsize.h:25
constexpr bool isValid() const noexcept
Returns true if both the width and height is equal to or greater than 0; otherwise returns false.
Definition qsize.h:126
int blueBufferSize() const
Get the size in bits of the blue channel of the color buffer.
int redBufferSize() const
Get the size in bits of the red channel of the color buffer.
int greenBufferSize() const
Get the size in bits of the green channel of the color buffer.
\inmodule QtGui
Definition qwindow.h:63
SurfaceType surfaceType() const override
Returns the surface type of the window.
Definition qwindow.cpp:628
rect
[4]
Combined button and popup list for selecting options.
static void * context
#define Q_UNLIKELY(x)
typedef EGLBoolean(EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC)(EGLint max_devices
typedef EGLSurface(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay dpy
#define qWarning
Definition qlogging.h:162
#define qFatal
Definition qlogging.h:164
GLuint64EXT * result
[6]
GLsizeiptr const void GLenum usage
Definition qopenglext.h:543
#define qEglWindowDebug
aWidget window() -> setWindowTitle("New Window Title")
[2]