/src/qtbase/src/gui/kernel/qsurfaceformat.cpp
Line | Count | Source |
1 | | // Copyright (C) 2016 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 | | // Qt-Security score:significant reason:default |
4 | | |
5 | | #include "qsurfaceformat.h" |
6 | | |
7 | | #include <QtCore/qatomic.h> |
8 | | #include <QtCore/QDebug> |
9 | | #include <QOpenGLContext> |
10 | | #include <QtGui/qcolorspace.h> |
11 | | #include <QtGui/qguiapplication.h> |
12 | | |
13 | | #ifndef QT_NO_OPENGL |
14 | | #include <QtGui/private/qopenglcontext_p.h> |
15 | | #endif |
16 | | |
17 | | #ifdef major |
18 | | #undef major |
19 | | #endif |
20 | | |
21 | | #ifdef minor |
22 | | #undef minor |
23 | | #endif |
24 | | |
25 | | QT_BEGIN_NAMESPACE |
26 | | |
27 | | class QSurfaceFormatPrivate |
28 | | { |
29 | | public: |
30 | | explicit QSurfaceFormatPrivate(QSurfaceFormat::FormatOptions _opts = { }) |
31 | 0 | : ref(1) |
32 | 0 | , opts(_opts) |
33 | 0 | , redBufferSize(-1) |
34 | 0 | , greenBufferSize(-1) |
35 | 0 | , blueBufferSize(-1) |
36 | 0 | , alphaBufferSize(-1) |
37 | 0 | , depthSize(-1) |
38 | 0 | , stencilSize(-1) |
39 | 0 | , swapBehavior(QSurfaceFormat::DefaultSwapBehavior) |
40 | 0 | , numSamples(-1) |
41 | 0 | , renderableType(QSurfaceFormat::DefaultRenderableType) |
42 | 0 | , profile(QSurfaceFormat::NoProfile) |
43 | 0 | , major(2) |
44 | 0 | , minor(0) |
45 | 0 | , swapInterval(1) // default to vsync |
46 | 0 | { |
47 | 0 | } |
48 | | |
49 | | QSurfaceFormatPrivate(const QSurfaceFormatPrivate *other) |
50 | 0 | : ref(1), |
51 | 0 | opts(other->opts), |
52 | 0 | redBufferSize(other->redBufferSize), |
53 | 0 | greenBufferSize(other->greenBufferSize), |
54 | 0 | blueBufferSize(other->blueBufferSize), |
55 | 0 | alphaBufferSize(other->alphaBufferSize), |
56 | 0 | depthSize(other->depthSize), |
57 | 0 | stencilSize(other->stencilSize), |
58 | 0 | swapBehavior(other->swapBehavior), |
59 | 0 | numSamples(other->numSamples), |
60 | 0 | renderableType(other->renderableType), |
61 | 0 | profile(other->profile), |
62 | 0 | major(other->major), |
63 | 0 | minor(other->minor), |
64 | 0 | swapInterval(other->swapInterval), |
65 | 0 | colorSpace(other->colorSpace) |
66 | 0 | { |
67 | 0 | } |
68 | | |
69 | | QAtomicInt ref; |
70 | | QSurfaceFormat::FormatOptions opts; |
71 | | int redBufferSize; |
72 | | int greenBufferSize; |
73 | | int blueBufferSize; |
74 | | int alphaBufferSize; |
75 | | int depthSize; |
76 | | int stencilSize; |
77 | | QSurfaceFormat::SwapBehavior swapBehavior; |
78 | | int numSamples; |
79 | | QSurfaceFormat::RenderableType renderableType; |
80 | | QSurfaceFormat::OpenGLContextProfile profile; |
81 | | int major; |
82 | | int minor; |
83 | | int swapInterval; |
84 | | QColorSpace colorSpace; |
85 | | }; |
86 | | |
87 | | /*! |
88 | | \class QSurfaceFormat |
89 | | \since 5.0 |
90 | | \brief The QSurfaceFormat class represents the format of a QSurface. |
91 | | \inmodule QtGui |
92 | | |
93 | | The format includes the size of the color buffers, red, green, and blue; |
94 | | the size of the alpha buffer; the size of the depth and stencil buffers; |
95 | | and number of samples per pixel for multisampling. In addition, the format |
96 | | contains surface configuration parameters such as OpenGL profile and |
97 | | version for rendering, whether or not to enable stereo buffers, and swap |
98 | | behaviour. |
99 | | |
100 | | \note When troubleshooting context or window format issues, it can be |
101 | | helpful to enable the logging category \c{qt.qpa.gl}. Depending on the |
102 | | platform, this may print useful debug information when it comes to OpenGL |
103 | | initialization and the native visual or framebuffer configurations which |
104 | | QSurfaceFormat gets mapped to. |
105 | | */ |
106 | | |
107 | | /*! |
108 | | \enum QSurfaceFormat::FormatOption |
109 | | |
110 | | This enum contains format options for use with QSurfaceFormat. |
111 | | |
112 | | \value StereoBuffers Used to request stereo buffers in the surface format. |
113 | | \value DebugContext Used to request a debug context with extra debugging information. |
114 | | \value DeprecatedFunctions Used to request that deprecated functions be included |
115 | | in the OpenGL context profile. If not specified, you should get a forward compatible context |
116 | | without support functionality marked as deprecated. This requires OpenGL version 3.0 or higher. |
117 | | \value ResetNotification Enables notifications about resets of the OpenGL context. The status is then |
118 | | queryable via the context's \l{QOpenGLContext::isValid()}{isValid()} function. Note that not setting |
119 | | this flag does not guarantee that context state loss never occurs. Additionally, some implementations |
120 | | may choose to report context loss regardless of this flag. Platforms that support dynamically enabling |
121 | | the monitoring of the loss of context, such as, Windows with WGL, or Linux/X11 (xcb) with GLX, will |
122 | | monitor the status in every call to \l{QOpenGLContext::makeCurrent()}{makeCurrent()}. See |
123 | | \l{QOpenGLContext::isValid()}{isValid()} for more information on this. |
124 | | \value ProtectedContent Enables access to protected content. This allows the GPU to operate on protected |
125 | | resources (surfaces, buffers, textures), for example DRM-protected video content. |
126 | | Currently only implemented for EGL. |
127 | | */ |
128 | | |
129 | | /*! |
130 | | \enum QSurfaceFormat::SwapBehavior |
131 | | |
132 | | This enum is used by QSurfaceFormat to specify the swap behaviour of a surface. The swap behaviour |
133 | | is mostly transparent to the application, but it affects factors such as rendering latency and |
134 | | throughput. |
135 | | |
136 | | \value DefaultSwapBehavior The default, unspecified swap behaviour of the platform. |
137 | | \value SingleBuffer Used to request single buffering, which might result in flickering |
138 | | when OpenGL rendering is done directly to screen without an intermediate offscreen |
139 | | buffer. |
140 | | \value DoubleBuffer This is typically the default swap behaviour on desktop platforms, |
141 | | consisting of one back buffer and one front buffer. Rendering is done to the back |
142 | | buffer, and then the back buffer and front buffer are swapped, or the contents of |
143 | | the back buffer are copied to the front buffer, depending on the implementation. |
144 | | \value TripleBuffer This swap behaviour is sometimes used in order to decrease the |
145 | | risk of skipping a frame when the rendering rate is just barely keeping up with |
146 | | the screen refresh rate. Depending on the platform it might also lead to slightly |
147 | | more efficient use of the GPU due to improved pipelining behaviour. Triple buffering |
148 | | comes at the cost of an extra frame of memory usage and latency, and might not be |
149 | | supported depending on the underlying platform. |
150 | | */ |
151 | | |
152 | | /*! |
153 | | \enum QSurfaceFormat::RenderableType |
154 | | |
155 | | This enum specifies the rendering backend for the surface. |
156 | | |
157 | | \value DefaultRenderableType The default, unspecified rendering method |
158 | | \value OpenGL Desktop OpenGL rendering |
159 | | \value OpenGLES OpenGL ES 2.0 rendering |
160 | | \value OpenVG Open Vector Graphics rendering |
161 | | */ |
162 | | |
163 | | /*! |
164 | | \enum QSurfaceFormat::OpenGLContextProfile |
165 | | |
166 | | This enum is used to specify the OpenGL context profile, in |
167 | | conjunction with QSurfaceFormat::setMajorVersion() and |
168 | | QSurfaceFormat::setMinorVersion(). |
169 | | |
170 | | Profiles are exposed in OpenGL 3.2 and above, and are used |
171 | | to choose between a restricted core profile, and a compatibility |
172 | | profile which might contain deprecated support functionality. |
173 | | |
174 | | Note that the core profile might still contain functionality that |
175 | | is deprecated and scheduled for removal in a higher version. To |
176 | | get access to the deprecated functionality for the core profile |
177 | | in the set OpenGL version you can use the QSurfaceFormat format option |
178 | | QSurfaceFormat::DeprecatedFunctions. |
179 | | |
180 | | \value NoProfile OpenGL version is lower than 3.2. For 3.2 and newer this is same as CoreProfile. |
181 | | \value CoreProfile Functionality deprecated in OpenGL version 3.0 is not available. |
182 | | \value CompatibilityProfile Functionality from earlier OpenGL versions is available. |
183 | | */ |
184 | | |
185 | | /*! |
186 | | \enum QSurfaceFormat::ColorSpace |
187 | | \deprecated [6.0] Use setColorSpace(QColorSpace) instead |
188 | | |
189 | | This enum is used to specify the preferred color space, controlling if the |
190 | | window's associated default framebuffer is able to do updates and blending |
191 | | in a given encoding instead of the standard linear operations. |
192 | | |
193 | | \value DefaultColorSpace The default, unspecified color space. |
194 | | |
195 | | \value sRGBColorSpace When \c{GL_ARB_framebuffer_sRGB} or |
196 | | \c{GL_EXT_framebuffer_sRGB} is supported by the platform and this value is |
197 | | set, the window will be created with an sRGB-capable default |
198 | | framebuffer. Note that some platforms may return windows with a sRGB-capable |
199 | | default framebuffer even when not requested explicitly. |
200 | | */ |
201 | | |
202 | | /*! |
203 | | Constructs a default initialized QSurfaceFormat. |
204 | | |
205 | | \note By default OpenGL 2.0 is requested since this provides the highest |
206 | | grade of portability between platforms and OpenGL implementations. |
207 | | */ |
208 | 0 | QSurfaceFormat::QSurfaceFormat() : d(new QSurfaceFormatPrivate) |
209 | 0 | { |
210 | 0 | } |
211 | | |
212 | | /*! |
213 | | Constructs a QSurfaceFormat with the given format \a options. |
214 | | */ |
215 | | QSurfaceFormat::QSurfaceFormat(QSurfaceFormat::FormatOptions options) : |
216 | 0 | d(new QSurfaceFormatPrivate(options)) |
217 | 0 | { |
218 | 0 | } |
219 | | |
220 | | /*! |
221 | | \internal |
222 | | */ |
223 | | void QSurfaceFormat::detach() |
224 | 0 | { |
225 | 0 | if (d->ref.loadRelaxed() != 1) { |
226 | 0 | QSurfaceFormatPrivate *newd = new QSurfaceFormatPrivate(d); |
227 | 0 | if (!d->ref.deref()) |
228 | 0 | delete d; |
229 | 0 | d = newd; |
230 | 0 | } |
231 | 0 | } |
232 | | |
233 | | /*! |
234 | | Constructs a copy of \a other. |
235 | | */ |
236 | | QSurfaceFormat::QSurfaceFormat(const QSurfaceFormat &other) |
237 | 0 | { |
238 | 0 | d = other.d; |
239 | 0 | d->ref.ref(); |
240 | 0 | } |
241 | | |
242 | | /*! |
243 | | Assigns \a other to this object. |
244 | | */ |
245 | | QSurfaceFormat &QSurfaceFormat::operator=(const QSurfaceFormat &other) |
246 | 0 | { |
247 | 0 | if (d != other.d) { |
248 | 0 | other.d->ref.ref(); |
249 | 0 | if (!d->ref.deref()) |
250 | 0 | delete d; |
251 | 0 | d = other.d; |
252 | 0 | } |
253 | 0 | return *this; |
254 | 0 | } |
255 | | |
256 | | /*! |
257 | | Destroys the QSurfaceFormat. |
258 | | */ |
259 | | QSurfaceFormat::~QSurfaceFormat() |
260 | 0 | { |
261 | 0 | if (!d->ref.deref()) |
262 | 0 | delete d; |
263 | 0 | } |
264 | | |
265 | | /*! |
266 | | \fn bool QSurfaceFormat::stereo() const |
267 | | |
268 | | Returns \c true if stereo buffering is enabled; otherwise returns |
269 | | false. Stereo buffering is disabled by default. |
270 | | |
271 | | \sa setStereo() |
272 | | */ |
273 | | |
274 | | /*! |
275 | | If \a enable is true enables stereo buffering; otherwise disables |
276 | | stereo buffering. |
277 | | |
278 | | Stereo buffering is disabled by default. |
279 | | |
280 | | Stereo buffering provides extra color buffers to generate left-eye |
281 | | and right-eye images. |
282 | | |
283 | | \sa stereo() |
284 | | */ |
285 | | void QSurfaceFormat::setStereo(bool enable) |
286 | 0 | { |
287 | 0 | QSurfaceFormat::FormatOptions newOptions = d->opts; |
288 | 0 | newOptions.setFlag(QSurfaceFormat::StereoBuffers, enable); |
289 | |
|
290 | 0 | if (int(newOptions) != int(d->opts)) { |
291 | 0 | detach(); |
292 | 0 | d->opts = newOptions; |
293 | 0 | } |
294 | 0 | } |
295 | | |
296 | | /*! |
297 | | Returns the number of samples per pixel when multisampling is |
298 | | enabled, or \c -1 when multisampling is disabled. The default |
299 | | return value is \c -1. |
300 | | |
301 | | \sa setSamples() |
302 | | */ |
303 | | int QSurfaceFormat::samples() const |
304 | 0 | { |
305 | 0 | return d->numSamples; |
306 | 0 | } |
307 | | |
308 | | /*! |
309 | | Set the preferred number of samples per pixel when multisampling |
310 | | is enabled to \a numSamples. By default, multisampling is disabled. |
311 | | |
312 | | \sa samples() |
313 | | */ |
314 | | void QSurfaceFormat::setSamples(int numSamples) |
315 | 0 | { |
316 | 0 | if (d->numSamples != numSamples) { |
317 | 0 | detach(); |
318 | 0 | d->numSamples = numSamples; |
319 | 0 | } |
320 | 0 | } |
321 | | |
322 | | /*! |
323 | | \since 5.3 |
324 | | |
325 | | Sets the format options to \a options. |
326 | | |
327 | | To verify that an option was respected, compare the actual format to the |
328 | | requested format after surface/context creation. |
329 | | |
330 | | \sa options(), testOption() |
331 | | */ |
332 | | void QSurfaceFormat::setOptions(QSurfaceFormat::FormatOptions options) |
333 | 0 | { |
334 | 0 | if (int(d->opts) != int(options)) { |
335 | 0 | detach(); |
336 | 0 | d->opts = options; |
337 | 0 | } |
338 | 0 | } |
339 | | |
340 | | /*! |
341 | | \since 5.3 |
342 | | |
343 | | Sets the format option \a option if \a on is true; otherwise, clears the option. |
344 | | |
345 | | To verify that an option was respected, compare the actual format to the |
346 | | requested format after surface/context creation. |
347 | | |
348 | | \sa setOptions(), options(), testOption() |
349 | | */ |
350 | | void QSurfaceFormat::setOption(QSurfaceFormat::FormatOption option, bool on) |
351 | 0 | { |
352 | 0 | if (testOption(option) == on) |
353 | 0 | return; |
354 | 0 | detach(); |
355 | 0 | if (on) |
356 | 0 | d->opts |= option; |
357 | 0 | else |
358 | 0 | d->opts &= ~option; |
359 | 0 | } |
360 | | |
361 | | /*! |
362 | | \since 5.3 |
363 | | |
364 | | Returns true if the format option \a option is set; otherwise returns false. |
365 | | |
366 | | \sa options() |
367 | | */ |
368 | | bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOption option) const |
369 | 0 | { |
370 | 0 | return d->opts & option; |
371 | 0 | } |
372 | | |
373 | | /*! |
374 | | \since 5.3 |
375 | | |
376 | | Returns the currently set format options. |
377 | | |
378 | | \sa setOption(), setOptions(), testOption() |
379 | | */ |
380 | | QSurfaceFormat::FormatOptions QSurfaceFormat::options() const |
381 | 0 | { |
382 | 0 | return d->opts; |
383 | 0 | } |
384 | | |
385 | | /*! |
386 | | Set the minimum depth buffer size to \a size. |
387 | | |
388 | | \sa depthBufferSize() |
389 | | */ |
390 | | void QSurfaceFormat::setDepthBufferSize(int size) |
391 | 0 | { |
392 | 0 | if (d->depthSize != size) { |
393 | 0 | detach(); |
394 | 0 | d->depthSize = size; |
395 | 0 | } |
396 | 0 | } |
397 | | |
398 | | /*! |
399 | | Returns the depth buffer size. |
400 | | |
401 | | \sa setDepthBufferSize() |
402 | | */ |
403 | | int QSurfaceFormat::depthBufferSize() const |
404 | 0 | { |
405 | 0 | return d->depthSize; |
406 | 0 | } |
407 | | |
408 | | /*! |
409 | | Set the swap \a behavior of the surface. |
410 | | |
411 | | The swap behavior specifies whether single, double, or triple |
412 | | buffering is desired. The default, DefaultSwapBehavior, |
413 | | gives the default swap behavior of the platform. |
414 | | */ |
415 | | void QSurfaceFormat::setSwapBehavior(SwapBehavior behavior) |
416 | 0 | { |
417 | 0 | if (d->swapBehavior != behavior) { |
418 | 0 | detach(); |
419 | 0 | d->swapBehavior = behavior; |
420 | 0 | } |
421 | 0 | } |
422 | | |
423 | | /*! |
424 | | Returns the configured swap behaviour. |
425 | | |
426 | | \sa setSwapBehavior() |
427 | | */ |
428 | | QSurfaceFormat::SwapBehavior QSurfaceFormat::swapBehavior() const |
429 | 0 | { |
430 | 0 | return d->swapBehavior; |
431 | 0 | } |
432 | | |
433 | | /*! |
434 | | Returns \c true if the alpha buffer size is greater than zero. |
435 | | |
436 | | This means that the surface might be used with per pixel |
437 | | translucency effects. |
438 | | */ |
439 | | bool QSurfaceFormat::hasAlpha() const |
440 | 0 | { |
441 | 0 | return d->alphaBufferSize > 0; |
442 | 0 | } |
443 | | |
444 | | /*! |
445 | | Set the preferred stencil buffer size to \a size bits. |
446 | | |
447 | | \sa stencilBufferSize() |
448 | | */ |
449 | | void QSurfaceFormat::setStencilBufferSize(int size) |
450 | 0 | { |
451 | 0 | if (d->stencilSize != size) { |
452 | 0 | detach(); |
453 | 0 | d->stencilSize = size; |
454 | 0 | } |
455 | 0 | } |
456 | | |
457 | | /*! |
458 | | Returns the stencil buffer size in bits. |
459 | | |
460 | | \sa setStencilBufferSize() |
461 | | */ |
462 | | int QSurfaceFormat::stencilBufferSize() const |
463 | 0 | { |
464 | 0 | return d->stencilSize; |
465 | 0 | } |
466 | | |
467 | | /*! |
468 | | Get the size in bits of the red channel of the color buffer. |
469 | | */ |
470 | | int QSurfaceFormat::redBufferSize() const |
471 | 0 | { |
472 | 0 | return d->redBufferSize; |
473 | 0 | } |
474 | | |
475 | | /*! |
476 | | Get the size in bits of the green channel of the color buffer. |
477 | | */ |
478 | | int QSurfaceFormat::greenBufferSize() const |
479 | 0 | { |
480 | 0 | return d->greenBufferSize; |
481 | 0 | } |
482 | | |
483 | | /*! |
484 | | Get the size in bits of the blue channel of the color buffer. |
485 | | */ |
486 | | int QSurfaceFormat::blueBufferSize() const |
487 | 0 | { |
488 | 0 | return d->blueBufferSize; |
489 | 0 | } |
490 | | |
491 | | /*! |
492 | | Get the size in bits of the alpha channel of the color buffer. |
493 | | */ |
494 | | int QSurfaceFormat::alphaBufferSize() const |
495 | 0 | { |
496 | 0 | return d->alphaBufferSize; |
497 | 0 | } |
498 | | |
499 | | /*! |
500 | | Set the desired \a size in bits of the red channel of the color buffer. |
501 | | */ |
502 | | void QSurfaceFormat::setRedBufferSize(int size) |
503 | 0 | { |
504 | 0 | if (d->redBufferSize != size) { |
505 | 0 | detach(); |
506 | 0 | d->redBufferSize = size; |
507 | 0 | } |
508 | 0 | } |
509 | | |
510 | | /*! |
511 | | Set the desired \a size in bits of the green channel of the color buffer. |
512 | | */ |
513 | | void QSurfaceFormat::setGreenBufferSize(int size) |
514 | 0 | { |
515 | 0 | if (d->greenBufferSize != size) { |
516 | 0 | detach(); |
517 | 0 | d->greenBufferSize = size; |
518 | 0 | } |
519 | 0 | } |
520 | | |
521 | | /*! |
522 | | Set the desired \a size in bits of the blue channel of the color buffer. |
523 | | */ |
524 | | void QSurfaceFormat::setBlueBufferSize(int size) |
525 | 0 | { |
526 | 0 | if (d->blueBufferSize != size) { |
527 | 0 | detach(); |
528 | 0 | d->blueBufferSize = size; |
529 | 0 | } |
530 | 0 | } |
531 | | |
532 | | /*! |
533 | | Set the desired \a size in bits of the alpha channel of the color buffer. |
534 | | */ |
535 | | void QSurfaceFormat::setAlphaBufferSize(int size) |
536 | 0 | { |
537 | 0 | if (d->alphaBufferSize != size) { |
538 | 0 | detach(); |
539 | 0 | d->alphaBufferSize = size; |
540 | 0 | } |
541 | 0 | } |
542 | | |
543 | | /*! |
544 | | Sets the desired renderable \a type. |
545 | | |
546 | | Chooses between desktop OpenGL, OpenGL ES, and OpenVG. |
547 | | */ |
548 | | void QSurfaceFormat::setRenderableType(RenderableType type) |
549 | 0 | { |
550 | 0 | if (d->renderableType != type) { |
551 | 0 | detach(); |
552 | 0 | d->renderableType = type; |
553 | 0 | } |
554 | 0 | } |
555 | | |
556 | | /*! |
557 | | Gets the renderable type. |
558 | | |
559 | | Chooses between desktop OpenGL, OpenGL ES, and OpenVG. |
560 | | */ |
561 | | QSurfaceFormat::RenderableType QSurfaceFormat::renderableType() const |
562 | 0 | { |
563 | 0 | return d->renderableType; |
564 | 0 | } |
565 | | |
566 | | /*! |
567 | | Sets the desired OpenGL context \a profile. |
568 | | |
569 | | This setting is ignored if the requested OpenGL version is |
570 | | less than 3.2. |
571 | | */ |
572 | | void QSurfaceFormat::setProfile(OpenGLContextProfile profile) |
573 | 0 | { |
574 | 0 | if (d->profile != profile) { |
575 | 0 | detach(); |
576 | 0 | d->profile = profile; |
577 | 0 | } |
578 | 0 | } |
579 | | |
580 | | /*! |
581 | | Get the configured OpenGL context profile. |
582 | | |
583 | | This setting is ignored if the requested OpenGL version is |
584 | | less than 3.2. |
585 | | */ |
586 | | QSurfaceFormat::OpenGLContextProfile QSurfaceFormat::profile() const |
587 | 0 | { |
588 | 0 | return d->profile; |
589 | 0 | } |
590 | | |
591 | | /*! |
592 | | Sets the desired \a major OpenGL version. |
593 | | */ |
594 | | void QSurfaceFormat::setMajorVersion(int major) |
595 | 0 | { |
596 | 0 | if (d->major != major) { |
597 | 0 | detach(); |
598 | 0 | d->major = major; |
599 | 0 | } |
600 | 0 | } |
601 | | |
602 | | /*! |
603 | | Returns the major OpenGL version. |
604 | | |
605 | | The default version is 2.0. |
606 | | */ |
607 | | int QSurfaceFormat::majorVersion() const |
608 | 0 | { |
609 | 0 | return d->major; |
610 | 0 | } |
611 | | |
612 | | /*! |
613 | | Sets the desired \a minor OpenGL version. |
614 | | |
615 | | The default version is 2.0. |
616 | | */ |
617 | | void QSurfaceFormat::setMinorVersion(int minor) |
618 | 0 | { |
619 | 0 | if (d->minor != minor) { |
620 | 0 | detach(); |
621 | 0 | d->minor = minor; |
622 | 0 | } |
623 | 0 | } |
624 | | |
625 | | /*! |
626 | | Returns the minor OpenGL version. |
627 | | */ |
628 | | int QSurfaceFormat::minorVersion() const |
629 | 0 | { |
630 | 0 | return d->minor; |
631 | 0 | } |
632 | | |
633 | | /*! |
634 | | Returns a std::pair<int, int> representing the OpenGL version. |
635 | | |
636 | | Useful for version checks, for example format.version() >= std::pair(3, 2) |
637 | | */ |
638 | | std::pair<int, int> QSurfaceFormat::version() const |
639 | 0 | { |
640 | 0 | return std::pair(d->major, d->minor); |
641 | 0 | } |
642 | | |
643 | | /*! |
644 | | Sets the desired \a major and \a minor OpenGL versions. |
645 | | |
646 | | The default version is 2.0. |
647 | | */ |
648 | | void QSurfaceFormat::setVersion(int major, int minor) |
649 | 0 | { |
650 | 0 | if (d->minor != minor || d->major != major) { |
651 | 0 | detach(); |
652 | 0 | d->minor = minor; |
653 | 0 | d->major = major; |
654 | 0 | } |
655 | 0 | } |
656 | | |
657 | | /*! |
658 | | Sets the preferred swap interval. The swap interval specifies the |
659 | | minimum number of video frames that are displayed before a buffer |
660 | | swap occurs. This can be used to sync the GL drawing into a window |
661 | | to the vertical refresh of the screen. |
662 | | |
663 | | Setting an \a interval value of 0 will turn the vertical refresh |
664 | | syncing off, any value higher than 0 will turn the vertical |
665 | | syncing on. Setting \a interval to a higher value, for example 10, |
666 | | results in having 10 vertical retraces between every buffer swap. |
667 | | |
668 | | The default interval is 1. |
669 | | |
670 | | Changing the swap interval may not be supported by the underlying |
671 | | platform. In this case, the request will be silently ignored. |
672 | | |
673 | | \since 5.3 |
674 | | |
675 | | \sa swapInterval() |
676 | | */ |
677 | | void QSurfaceFormat::setSwapInterval(int interval) |
678 | 0 | { |
679 | 0 | if (d->swapInterval != interval) { |
680 | 0 | detach(); |
681 | 0 | d->swapInterval = interval; |
682 | 0 | } |
683 | 0 | } |
684 | | |
685 | | /*! |
686 | | Returns the swap interval. |
687 | | |
688 | | \since 5.3 |
689 | | |
690 | | \sa setSwapInterval() |
691 | | */ |
692 | | int QSurfaceFormat::swapInterval() const |
693 | 0 | { |
694 | 0 | return d->swapInterval; |
695 | 0 | } |
696 | | |
697 | | /*! |
698 | | Sets the preferred \a colorSpace. |
699 | | |
700 | | For example, this allows requesting windows with default framebuffers that |
701 | | are sRGB-capable on platforms that support it. |
702 | | |
703 | | \note When the requested color space is not supported by the platform, the |
704 | | request is ignored. Query the QSurfaceFormat after window creation to verify |
705 | | if the color space request could be honored or not. |
706 | | |
707 | | \note This setting controls if the default framebuffer of the window is |
708 | | capable of updates and blending in a given color space. It does not change |
709 | | applications' output by itself. The applications' rendering code will still |
710 | | have to opt in via the appropriate OpenGL calls to enable updates and |
711 | | blending to be performed in the given color space instead of using the |
712 | | standard linear operations. |
713 | | |
714 | | \since 6.0 |
715 | | |
716 | | \sa colorSpace() |
717 | | */ |
718 | | void QSurfaceFormat::setColorSpace(const QColorSpace &colorSpace) |
719 | 0 | { |
720 | 0 | if (d->colorSpace != colorSpace) { |
721 | 0 | detach(); |
722 | 0 | d->colorSpace = colorSpace; |
723 | 0 | } |
724 | 0 | } |
725 | | |
726 | | #if QT_DEPRECATED_SINCE(6, 0) |
727 | | /*! |
728 | | \overload |
729 | | \deprecated [6.0] Use setColorSpace(QColorSpace) instead. |
730 | | |
731 | | Sets the colorspace to one of the predefined values. |
732 | | |
733 | | \since 5.10 |
734 | | |
735 | | \sa colorSpace() |
736 | | */ |
737 | | void QSurfaceFormat::setColorSpace(ColorSpace colorSpace) |
738 | 0 | { |
739 | 0 | switch (colorSpace) { |
740 | 0 | case DefaultColorSpace: |
741 | 0 | setColorSpace(QColorSpace()); |
742 | 0 | break; |
743 | 0 | case sRGBColorSpace: |
744 | 0 | setColorSpace(QColorSpace::SRgb); |
745 | 0 | break; |
746 | 0 | } |
747 | 0 | } |
748 | | #endif // QT_DEPRECATED_SINCE(6, 0) |
749 | | |
750 | | /*! |
751 | | \return the color space. |
752 | | |
753 | | \since 5.10 |
754 | | |
755 | | \sa setColorSpace() |
756 | | */ |
757 | | const QColorSpace &QSurfaceFormat::colorSpace() const |
758 | 0 | { |
759 | 0 | return d->colorSpace; |
760 | 0 | } |
761 | | |
762 | | Q_GLOBAL_STATIC(QSurfaceFormat, qt_default_surface_format) |
763 | | |
764 | | /*! |
765 | | Sets the global default surface \a format. |
766 | | |
767 | | This format is used by default in QOpenGLContext, QWindow, QOpenGLWidget and |
768 | | similar classes. |
769 | | |
770 | | It can always be overridden on a per-instance basis by using the class in |
771 | | question's own setFormat() function. However, it is often more convenient to |
772 | | set the format for all windows once at the start of the application. It also |
773 | | guarantees proper behavior in cases where shared contexts are required, |
774 | | because setting the format via this function guarantees that all contexts |
775 | | and surfaces, even the ones created internally by Qt, will use the same |
776 | | format. |
777 | | |
778 | | \since 5.4 |
779 | | \sa defaultFormat() |
780 | | */ |
781 | | void QSurfaceFormat::setDefaultFormat(const QSurfaceFormat &format) |
782 | 0 | { |
783 | | #ifndef QT_NO_OPENGL |
784 | | if (qApp) { |
785 | | QOpenGLContext *globalContext = qt_gl_global_share_context(); |
786 | | if (globalContext && globalContext->isValid()) { |
787 | | qWarning("Warning: Setting a new default format with a different version or profile " |
788 | | "after the global shared context is created may cause issues with context " |
789 | | "sharing."); |
790 | | } |
791 | | } |
792 | | #endif |
793 | 0 | *qt_default_surface_format() = format; |
794 | 0 | } |
795 | | |
796 | | /*! |
797 | | Returns the global default surface format. |
798 | | |
799 | | When setDefaultFormat() is not called, this is a default-constructed QSurfaceFormat. |
800 | | |
801 | | \since 5.4 |
802 | | \sa setDefaultFormat() |
803 | | */ |
804 | | QSurfaceFormat QSurfaceFormat::defaultFormat() |
805 | 0 | { |
806 | 0 | return *qt_default_surface_format(); |
807 | 0 | } |
808 | | |
809 | | /*! |
810 | | \fn bool QSurfaceFormat::operator==(const QSurfaceFormat& lhs, const QSurfaceFormat& rhs) |
811 | | |
812 | | Returns \c true if all the options of the two QSurfaceFormat objects |
813 | | \a lhs and \a rhs are equal. |
814 | | */ |
815 | | |
816 | | /*! |
817 | | \fn bool QSurfaceFormat::operator!=(const QSurfaceFormat& lhs, const QSurfaceFormat& rhs) |
818 | | |
819 | | Returns \c false if all the options of the two QSurfaceFormat objects |
820 | | \a lhs and \a rhs are equal; otherwise returns \c true. |
821 | | */ |
822 | | |
823 | | /*! |
824 | | \internal |
825 | | */ |
826 | | bool QSurfaceFormat::equals(const QSurfaceFormat& other) const noexcept |
827 | 0 | { |
828 | 0 | return (d == other.d) || ((int) d->opts == (int) other.d->opts |
829 | 0 | && d->stencilSize == other.d->stencilSize |
830 | 0 | && d->redBufferSize == other.d->redBufferSize |
831 | 0 | && d->greenBufferSize == other.d->greenBufferSize |
832 | 0 | && d->blueBufferSize == other.d->blueBufferSize |
833 | 0 | && d->alphaBufferSize == other.d->alphaBufferSize |
834 | 0 | && d->depthSize == other.d->depthSize |
835 | 0 | && d->numSamples == other.d->numSamples |
836 | 0 | && d->swapBehavior == other.d->swapBehavior |
837 | 0 | && d->profile == other.d->profile |
838 | 0 | && d->major == other.d->major |
839 | 0 | && d->minor == other.d->minor |
840 | 0 | && d->swapInterval == other.d->swapInterval); |
841 | 0 | } |
842 | | |
843 | | #ifndef QT_NO_DEBUG_STREAM |
844 | | QDebug operator<<(QDebug dbg, const QSurfaceFormat &f) |
845 | 0 | { |
846 | 0 | const QSurfaceFormatPrivate * const d = f.d; |
847 | 0 | QDebugStateSaver saver(dbg); |
848 | |
|
849 | 0 | dbg.nospace() << "QSurfaceFormat(" |
850 | 0 | << "version " << d->major << '.' << d->minor |
851 | 0 | << ", options " << d->opts |
852 | 0 | << ", depthBufferSize " << d->depthSize |
853 | 0 | << ", redBufferSize " << d->redBufferSize |
854 | 0 | << ", greenBufferSize " << d->greenBufferSize |
855 | 0 | << ", blueBufferSize " << d->blueBufferSize |
856 | 0 | << ", alphaBufferSize " << d->alphaBufferSize |
857 | 0 | << ", stencilBufferSize " << d->stencilSize |
858 | 0 | << ", samples " << d->numSamples |
859 | 0 | << ", swapBehavior " << d->swapBehavior |
860 | 0 | << ", swapInterval " << d->swapInterval |
861 | 0 | << ", colorSpace " << d->colorSpace |
862 | 0 | << ", profile " << d->profile |
863 | 0 | << ')'; |
864 | |
|
865 | 0 | return dbg; |
866 | 0 | } |
867 | | #endif |
868 | | |
869 | | QT_END_NAMESPACE |
870 | | |
871 | | #include "moc_qsurfaceformat.cpp" |