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
qquick3d.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3d.h"
5
6#if QT_CONFIG(opengl)
7# include <QtGui/qopenglcontext.h>
8#endif
9#include <QtQuick/qquickwindow.h>
10
11#include <QtCore/qloggingcategory.h>
12
13Q_LOGGING_CATEGORY(lcQuick3D, "qt.quick3d.general")
14
15
68#if QT_CONFIG(opengl)
69static QSurfaceFormat findIdealGLVersion(int samples)
70{
72 int defaultSamples = fmt.samples();
73 const bool multisampling = samples > 1;
75
76 // Proper case: Try 4.3 core (so we get compute shaders for instance)
77 fmt.setVersion(4, 3);
78 fmt.setSamples(multisampling ? samples : defaultSamples);
80 ctx.setFormat(fmt);
81 if (ctx.create() && ctx.format().version() >= qMakePair(4, 3)) {
82 qCDebug(lcQuick3D, "Requesting OpenGL 4.3 core context succeeded");
83 return ctx.format();
84 }
85 if (multisampling) {
86 // try without multisampling
87 fmt.setSamples(defaultSamples);
88 ctx.setFormat(fmt);
89 if (ctx.create() && ctx.format().version() >= qMakePair(4, 3)) {
90 qCDebug(lcQuick3D, "Requesting OpenGL 4.3 core context succeeded without multisampling");
91 return ctx.format();
92 }
93 }
94
95 // Fallback, but still good, case: Stick with 3.3 (the only thing we lose is compute for HDR mipmaps)
96 fmt.setVersion(3, 3);
97 fmt.setSamples(multisampling ? samples : defaultSamples);
98 ctx.setFormat(fmt);
99 if (ctx.create() && ctx.format().version() >= qMakePair(3, 3)) {
100 qCDebug(lcQuick3D, "Requesting OpenGL 3.3 core context succeeded");
101 return ctx.format();
102 }
103 if (multisampling) {
104 // try without multisampling
105 fmt.setSamples(defaultSamples);
106 ctx.setFormat(fmt);
107 if (ctx.create() && ctx.format().version() >= qMakePair(3, 3)) {
108 qCDebug(lcQuick3D, "Requesting OpenGL 3.3 core context succeeded without multisampling");
109 return ctx.format();
110 }
111 }
112
113 // If all else fails, try 3.0. This may have some issues but most things should work.
114 fmt.setVersion(3, 0);
115 // the modern core-compat. concept as we know it is only there since 3.2
116 fmt.setProfile(QSurfaceFormat::NoProfile);
117 fmt.setSamples(multisampling ? samples : defaultSamples);
118 ctx.setFormat(fmt);
119 if (ctx.create() && ctx.format().version() >= qMakePair(3, 0)) {
120 qCDebug(lcQuick3D, "Requesting OpenGL 3.0 context succeeded");
121 return ctx.format();
122 }
123 if (multisampling) {
124 fmt.setSamples(defaultSamples);
125 ctx.setFormat(fmt);
126 if (ctx.create() && ctx.format().version() >= qMakePair(3, 0)) {
127 qCDebug(lcQuick3D, "Requesting OpenGL 3.0 context succeeded without multisampling");
128 return ctx.format();
129 }
130 }
131
132 qCWarning(lcQuick3D, "Unable to find ideal GL version.");
133 return fmt;
134}
135
136static QSurfaceFormat findIdealGLESVersion(int samples)
137{
139 int defaultSamples = fmt.samples();
140 const bool multisampling = samples > 1;
141
142 // Proper case: Try 3.1 (so we get compute shaders)
143 fmt.setVersion(3, 1);
144 fmt.setRenderableType(QSurfaceFormat::OpenGLES);
145 fmt.setSamples(multisampling ? samples : defaultSamples);
147 ctx.setFormat(fmt);
148
149 // Now, it's important to check the format with the actual version (parsed
150 // back from GL_VERSION) since some implementations are broken and succeed
151 // the 3.1 context request even though they only support and return a 3.0
152 // context. This is against the spec since 3.0 is obviously not backwards
153 // compatible with 3.1, but hey...
154 qCDebug(lcQuick3D, "Testing OpenGL ES 3.1");
155 if (ctx.create() && ctx.format().version() >= qMakePair(3, 1)) {
156 qCDebug(lcQuick3D, "Requesting OpenGL ES 3.1 context succeeded");
157 return ctx.format();
158 }
159 if (multisampling) {
160 fmt.setSamples(defaultSamples);
161 ctx.setFormat(fmt);
162 if (ctx.create() && ctx.format().version() >= qMakePair(3, 1)) {
163 qCDebug(lcQuick3D, "Requesting OpenGL ES 3.1 context succeeded without multisampling");
164 return ctx.format();
165 }
166 }
167
168 // Fallback, but still good, case: OpenGL ES 3.0
169 fmt.setVersion(3, 0);
170 fmt.setSamples(multisampling ? samples : defaultSamples);
171 ctx.setFormat(fmt);
172 qCDebug(lcQuick3D, "Testing OpenGL ES 3.0");
173 if (ctx.create() && ctx.format().version() >= qMakePair(3, 0)) {
174 qCDebug(lcQuick3D, "Requesting OpenGL ES 3.0 context succeeded");
175 return ctx.format();
176 }
177 if (multisampling) {
178 fmt.setSamples(defaultSamples);
179 ctx.setFormat(fmt);
180 if (ctx.create() && ctx.format().version() >= qMakePair(3, 0)) {
181 qCDebug(lcQuick3D, "Requesting OpenGL ES 3.0 context succeeded without multisampling");
182 return ctx.format();
183 }
184 }
185
186 // If all else fails, try 2.0 but that's going to lose a bunch of features.
187 fmt.setVersion(2, 0);
188 fmt.setSamples(multisampling ? samples : defaultSamples);
189 ctx.setFormat(fmt);
190 qCDebug(lcQuick3D, "Testing OpenGL ES 2.0");
191 if (ctx.create()) {
192 qCDebug(lcQuick3D, "Requesting OpenGL ES 2.0 context succeeded");
193 return fmt;
194 }
195 if (multisampling) {
196 fmt.setSamples(defaultSamples);
197 ctx.setFormat(fmt);
198 if (ctx.create()) {
199 qCDebug(lcQuick3D, "Requesting OpenGL ES 2.0 context succeeded without multisampling");
200 return fmt;
201 }
202 }
203
204 qCWarning(lcQuick3D, "Unable to find ideal GLES version.");
205 return fmt;
206}
207#endif // #if QT_CONFIG(opengl)
212QSurfaceFormat QQuick3D::idealSurfaceFormat(int samples)
213{
214 if (QQuickWindow::graphicsApi() != QSGRendererInterface::OpenGLRhi) {
216 fmt.setSamples(samples);
217 return fmt;
218 }
219#if QT_CONFIG(opengl)
220 static const QSurfaceFormat f = [samples] {
222 if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { // works in dynamic gl builds too because there's a qguiapp already
223 fmt = findIdealGLVersion(samples);
224 } else {
225 fmt = findIdealGLESVersion(samples);
226 }
227 fmt.setDepthBufferSize(24);
228 fmt.setStencilBufferSize(8);
229 // Ignore MSAA here as that is a per-layer setting.
230 return fmt;
231 }();
232#else
233 // It really shouldn't be possible to get but if we do
234 // but at least return something if we do.
236#endif //#if QT_CONFIG(opengl)
237 return f;
238}
239
\inmodule QtGui
static OpenGLModuleType openGLModuleType()
Returns the underlying OpenGL implementation type.
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
int samples() const
Returns the number of samples per pixel when multisampling is enabled, or -1 when multisampling is di...
static QSurfaceFormat defaultFormat()
Returns the global default surface format.
EGLContext ctx
Combined button and popup list for selecting options.
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLsizei samples
GLfloat GLfloat f
QT_BEGIN_NAMESPACE constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
Definition qpair.h:19
QVideoFrameFormat::PixelFormat fmt