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