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
qohosegl.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 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
4#include "qohosegl.h"
5#include <QtCore/private/qohoscommon_p.h>
6#include <qohosjsenv_p.h>
7
8#include <QtCore/qmap.h>
9
11
12void QOhosEGLSurface::setNativeWindowSurface(
13 EGLNativeWindowType nativeWindow, const QOhosOptional<QSize> &optSurfaceSize)
14{
15 m_targetSurfaceSize = optSurfaceSize;
16 m_refTargetNativeWindow = nativeWindow;
17}
18
19void QOhosEGLSurface::tryCreateSurface(EGLDisplay display, EGLConfig config, SurfaceFlags surfaceFlags)
20{
21 bool canBuild = m_refTargetNativeWindow != nullptr;
22 if (!canBuild)
23 return;
24
25 EGLint surfaceAttribs[] = {
26 EGL_RENDER_BUFFER, EGL_BACK_BUFFER,
27 EGL_NONE
28 };
29
30 EGLNativeWindowType eglNativeWindow = m_refTargetNativeWindow;
31
32 EGLSurface surface = eglCreateWindowSurface(
33 display,
34 config,
35 eglNativeWindow,
36 surfaceAttribs);
37
38 std::string errMessage;
39 if (surface == EGL_NO_SURFACE) {
40 auto eglErrorCode = eglGetError();
41 switch (eglErrorCode) {
42 case EGL_BAD_MATCH: errMessage = "EGL_BAD_MATCH"; break;
43 case EGL_BAD_CONFIG: errMessage = "EGL_BAD_CONFIG"; break;
44 case EGL_BAD_NATIVE_WINDOW: errMessage = "EGL_BAD_NATIVE_WINDOW"; break;
45 case EGL_BAD_ALLOC: errMessage = "EGL_BAD_ALLOC"; break;
46 }
47 qOhosReportFatalErrorAndAbort(
48 "Failed to create surface with error: %d - %s",
49 eglErrorCode,
50 errMessage.c_str());
51 }
52
53 bool preserveBufOnSwapRequested = surfaceFlags.testFlag(
54 SurfaceFlagBits::PreserveBufferContentsOnSwap);
55 if (preserveBufOnSwapRequested
56 && eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED) == EGL_FALSE) {
57 qOhosReportFatalErrorAndAbort("Failed to set EGL_BUFFER_PRESERVED surface attrib");
58 }
59
60 m_ownEglSurface = surface;
61 m_refCurrentConfig = config;
62 m_refCurrentDisplay = display;
63 m_refCurrentNativeWindow = m_refTargetNativeWindow;
64 m_currentSurfaceFlags = surfaceFlags;
65}
66
67QOhosOptional<QSize> QOhosEGLSurface::currentSurfaceSize() const
68{
69 if (m_refCurrentDisplay == EGL_NO_DISPLAY || m_ownEglSurface == EGL_NO_SURFACE)
71
72 EGLint width;
73 if (eglQuerySurface(m_refCurrentDisplay, m_ownEglSurface, EGL_WIDTH, &width) != EGL_TRUE) {
74 qOhosPrintfWarning("%s - cannot get surface width, error: %d", Q_FUNC_INFO, eglGetError());
76 }
77
78 EGLint height;
79 if (eglQuerySurface(m_refCurrentDisplay, m_ownEglSurface, EGL_HEIGHT, &height) != EGL_TRUE) {
80 qOhosPrintfWarning("%s - cannot get surface height, error: %d", Q_FUNC_INFO, eglGetError());
82 }
83
84 return makeQOhosOptional(QSize(width, height));
85}
86
87EGLSurface QOhosEGLSurface::tryGetOrCreateEGLWindowSurface(
88 EGLDisplay display, EGLConfig config, bool swappingBuffers, SurfaceFlags surfaceFlags)
89{
90 if (swappingBuffers)
91 return m_ownEglSurface;
92
93 bool needsRebuild = m_ownEglSurface == EGL_NO_SURFACE
94 || m_refCurrentNativeWindow != m_refTargetNativeWindow
95 || m_refCurrentDisplay != display
96 || m_refCurrentConfig != config
97 || m_currentSurfaceFlags != surfaceFlags
98 || (m_targetSurfaceSize.has_value() && m_targetSurfaceSize != currentSurfaceSize());
99
100 if (!needsRebuild)
101 return m_ownEglSurface;
102
103 cleanup();
104 tryCreateSurface(display, config, surfaceFlags);
105
106 return m_ownEglSurface;
107}
108
109void QOhosEGLSurface::cleanup()
110{
111 if (m_refCurrentDisplay != EGL_NO_DISPLAY
112 && eglMakeCurrent(m_refCurrentDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_FALSE) {
113 qOhosPrintfWarning(
114 "%s: failed to unbind context from the current rendering thread, error: %d", Q_FUNC_INFO,
115 eglGetError());
116 }
117
118 if (m_ownEglSurface != EGL_NO_SURFACE && eglDestroySurface(m_refCurrentDisplay, m_ownEglSurface) == EGL_FALSE)
119 qOhosPrintfDebug("Failed to destroy surface");
120
121 m_refCurrentDisplay = EGL_NO_DISPLAY;
122 m_refCurrentConfig = nullptr;
123 m_refCurrentNativeWindow = nullptr;
124 m_ownEglSurface = EGL_NO_SURFACE;
125 m_currentSurfaceFlags = {};
126 m_targetSurfaceSize = makeEmptyQOhosOptional();
127}
128
129QOhosEGLSurface::~QOhosEGLSurface()
130{
131 cleanup();
132}
133
134QOhosEGLSurface::SurfaceFlags QOhosEGLSurface::currentSurfaceFlags() const
135{
136 return m_currentSurfaceFlags;
137}
138
139QT_END_NAMESPACE
Combined button and popup list for selecting options.
std::nullopt_t makeEmptyQOhosOptional()