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
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
14
15Q_LOGGING_CATEGORY(lcQpaWindowEgl, "qt.qpa.window.egl");
16
17QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow) :
18 QQnxWindow(window, context, needRootWindow),
19 m_newSurfaceRequested(true),
20 m_eglDisplay(EGL_NO_DISPLAY),
21 m_eglSurface(EGL_NO_SURFACE)
22{
23 initWindow();
24
25 m_requestedBufferSize = shouldMakeFullScreen() ? screen()->geometry().size() : window->geometry().size();
26}
27
29{
30 // Cleanup EGL surface if it exists
31 destroyEGLSurface();
32}
33
35{
36 return m_eglSurface != EGL_NO_SURFACE;
37}
38
40{
41 if (m_newSurfaceRequested.testAndSetOrdered(true, false)) {
42 const QMutexLocker locker(&m_mutex); // Set geometry must not reset the requestedBufferSize till
43 // the surface is created
44
45 if (m_requestedBufferSize != bufferSize() || m_eglSurface == EGL_NO_SURFACE) {
46 if (m_eglSurface != EGL_NO_SURFACE) {
47 context->doneCurrent();
48 destroyEGLSurface();
49 }
50 createEGLSurface(context);
51 } else {
52 // Must've been a sequence of unprocessed changes returning us to the original size.
54 }
55 }
56}
57
58void QQnxEglWindow::createEGLSurface(QQnxGLContext *context)
59{
60 if (context->format().renderableType() != QSurfaceFormat::OpenGLES) {
61 qFatal("QQnxEglWindow: renderable type is not OpenGLES");
62 return;
63 }
64
65 // Set window usage
66 int usage = SCREEN_USAGE_OPENGL_ES2;
67#if _SCREEN_VERSION >= _SCREEN_MAKE_VERSION(1, 0, 0)
68 if (context->format().majorVersion() == 3)
69 usage |= SCREEN_USAGE_OPENGL_ES3;
70#endif
71
72 const int result = screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_USAGE, &usage);
73 if (Q_UNLIKELY(result != 0))
74 qFatal("QQnxEglWindow: failed to set window usage, errno=%d", errno);
75
76 if (!m_requestedBufferSize.isValid()) {
77 qWarning("QQNX: Trying to create 0 size EGL surface. "
78 "Please set a valid window size before calling QOpenGLContext::makeCurrent()");
79 return;
80 }
81
82 m_eglDisplay = context->eglDisplay();
83 m_eglConfig = context->eglConfig();
84 m_format = context->format();
85
86 // update the window's buffers before we create the EGL surface
87 setBufferSize(m_requestedBufferSize);
88
89 const EGLint eglSurfaceAttrs[] =
90 {
91 EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
92 EGL_NONE
93 };
94
95 qCDebug(lcQpaWindowEgl) << "Creating EGL surface from" << this << context
96 << window()->surfaceType() << window()->type();
97
98 // Create EGL surface
99 EGLSurface eglSurface = eglCreateWindowSurface(
100 m_eglDisplay,
101 m_eglConfig,
102 (EGLNativeWindowType) nativeHandle(),
103 eglSurfaceAttrs);
104
105 if (eglSurface == EGL_NO_SURFACE)
106 qWarning("QQNX: failed to create EGL surface, err=%d", eglGetError());
107
108 m_eglSurface = eglSurface;
109}
110
111void QQnxEglWindow::destroyEGLSurface()
112{
113 // Destroy EGL surface if it exists
114 if (m_eglSurface != EGL_NO_SURFACE) {
115 EGLBoolean eglResult = eglDestroySurface(m_eglDisplay, m_eglSurface);
116 if (Q_UNLIKELY(eglResult != EGL_TRUE))
117 qFatal("QQNX: failed to destroy EGL surface, err=%d", eglGetError());
118 }
119
120 m_eglSurface = EGL_NO_SURFACE;
121}
122
124{
125 return m_eglSurface;
126}
127
129{
130 //If this is the root window, it has to be shown fullscreen
131 const QRect &newGeometry = shouldMakeFullScreen() ? screen()->geometry() : rect;
132
133 //We need to request that the GL context updates
134 // the EGLsurface on which it is rendering.
135 {
136 // We want the setting of the atomic bool in the GL context to be atomic with
137 // setting m_requestedBufferSize and therefore extended the scope to include
138 // that test.
139 const QMutexLocker locker(&m_mutex);
140 m_requestedBufferSize = newGeometry.size();
141 if (isInitialized() && bufferSize() != newGeometry.size())
142 m_newSurfaceRequested.testAndSetRelease(false, true);
143 }
144 QQnxWindow::setGeometry(newGeometry);
145}
146
148{
149 // Extract size of color channels from window format
150 const int redSize = m_format.redBufferSize();
151 if (Q_UNLIKELY(redSize == -1))
152 qFatal("QQnxWindow: red size not defined");
153
154 const int greenSize = m_format.greenBufferSize();
155 if (Q_UNLIKELY(greenSize == -1))
156 qFatal("QQnxWindow: green size not defined");
157
158 const int blueSize = m_format.blueBufferSize();
159 if (Q_UNLIKELY(blueSize == -1))
160 qFatal("QQnxWindow: blue size not defined");
161
162 // select matching native format
163 if (redSize == 5 && greenSize == 6 && blueSize == 5)
164 return SCREEN_FORMAT_RGB565;
165 else if (redSize == 8 && greenSize == 8 && blueSize == 8)
166 return SCREEN_FORMAT_RGBA8888;
167
168 qFatal("QQnxWindow: unsupported pixel format");
169}
170
172{
173 m_requestedBufferSize = QSize();
174}
175
bool testAndSetOrdered(T expectedValue, T newValue) noexcept
bool testAndSetRelease(T expectedValue, T newValue) noexcept
\inmodule QtCore
Definition qmutex.h:313
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
QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow)
int pixelFormat() const override
EGLSurface surface() const
void ensureInitialized(QQnxGLContext *context)
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:31
bool shouldMakeFullScreen() const
void initWindow()
screen_window_t nativeHandle() const
Definition qqnxwindow.h:45
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:48
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:242
\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:127
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:665
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:166
#define qFatal
Definition qlogging.h:168
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLuint64EXT * result
[6]
GLsizeiptr const void GLenum usage
Definition qopenglext.h:543
aWidget window() -> setWindowTitle("New Window Title")
[2]