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