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/qguiapplication.h>
46 
47 #ifdef major
48 #undef major
49 #endif
50 
51 #ifdef minor
52 #undef minor
53 #endif
54 
55 QT_BEGIN_NAMESPACE
56 
57 class QSurfaceFormatPrivate
58 {
59 public:
QSurfaceFormatPrivate(QSurfaceFormat::FormatOptions _opts={ })60     explicit QSurfaceFormatPrivate(QSurfaceFormat::FormatOptions _opts = { })
61         : ref(1)
62         , opts(_opts)
63         , redBufferSize(-1)
64         , greenBufferSize(-1)
65         , blueBufferSize(-1)
66         , alphaBufferSize(-1)
67         , depthSize(-1)
68         , stencilSize(-1)
69         , swapBehavior(QSurfaceFormat::DefaultSwapBehavior)
70         , numSamples(-1)
71         , renderableType(QSurfaceFormat::DefaultRenderableType)
72         , profile(QSurfaceFormat::NoProfile)
73         , major(2)
74         , minor(0)
75         , swapInterval(1) // default to vsync
76         , colorSpace(QSurfaceFormat::DefaultColorSpace)
77     {
78     }
79 
QSurfaceFormatPrivate(const QSurfaceFormatPrivate * other)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     QSurfaceFormat::ColorSpace 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 */
QSurfaceFormat()235 QSurfaceFormat::QSurfaceFormat() : d(new QSurfaceFormatPrivate)
236 {
237 }
238 
239 /*!
240     Constructs a QSurfaceFormat with the given format \a options.
241 */
QSurfaceFormat(QSurfaceFormat::FormatOptions options)242 QSurfaceFormat::QSurfaceFormat(QSurfaceFormat::FormatOptions options) :
243     d(new QSurfaceFormatPrivate(options))
244 {
245 }
246 
247 /*!
248     \internal
249 */
detach()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 */
QSurfaceFormat(const QSurfaceFormat & other)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 */
operator =(const QSurfaceFormat & other)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 */
~QSurfaceFormat()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 */
setStereo(bool enable)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 */
samples() const330 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 */
setSamples(int numSamples)341 void QSurfaceFormat::setSamples(int numSamples)
342 {
343     if (d->numSamples != numSamples) {
344         detach();
345         d->numSamples = numSamples;
346     }
347 }
348 
349 #if QT_DEPRECATED_SINCE(5, 2)
350 /*!
351     \obsolete
352     \overload
353 
354     Use setOption(QSurfaceFormat::FormatOption, bool) or setOptions() instead.
355 
356     Sets the format options to the OR combination of \a opt and the
357     current format options.
358 
359     \sa options(), testOption()
360 */
setOption(QSurfaceFormat::FormatOptions opt)361 void QSurfaceFormat::setOption(QSurfaceFormat::FormatOptions opt)
362 {
363     const QSurfaceFormat::FormatOptions newOptions = d->opts | opt;
364     if (int(newOptions) != int(d->opts)) {
365         detach();
366         d->opts = newOptions;
367     }
368 }
369 
370 /*!
371     \obsolete
372     \overload
373 
374     Use testOption(QSurfaceFormat::FormatOption) instead.
375 
376     Returns \c true if any of the options in \a opt is currently set
377     on this object; otherwise returns false.
378 
379     \sa setOption()
380 */
testOption(QSurfaceFormat::FormatOptions opt) const381 bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOptions opt) const
382 {
383     return d->opts & opt;
384 }
385 #endif // QT_DEPRECATED_SINCE(5, 2)
386 
387 /*!
388     \since 5.3
389 
390     Sets the format options to \a options.
391 
392     \sa options(), testOption()
393 */
setOptions(QSurfaceFormat::FormatOptions options)394 void QSurfaceFormat::setOptions(QSurfaceFormat::FormatOptions options)
395 {
396     if (int(d->opts) != int(options)) {
397         detach();
398         d->opts = options;
399     }
400 }
401 
402 /*!
403     \since 5.3
404 
405     Sets the format option \a option if \a on is true; otherwise, clears the option.
406 
407     \sa setOptions(), options(), testOption()
408 */
setOption(QSurfaceFormat::FormatOption option,bool on)409 void QSurfaceFormat::setOption(QSurfaceFormat::FormatOption option, bool on)
410 {
411     if (testOption(option) == on)
412         return;
413     detach();
414     if (on)
415         d->opts |= option;
416     else
417         d->opts &= ~option;
418 }
419 
420 /*!
421     \since 5.3
422 
423     Returns true if the format option \a option is set; otherwise returns false.
424 
425     \sa options()
426 */
testOption(QSurfaceFormat::FormatOption option) const427 bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOption option) const
428 {
429     return d->opts & option;
430 }
431 
432 /*!
433     \since 5.3
434 
435     Returns the currently set format options.
436 
437     \sa setOption(), setOptions(), testOption()
438 */
options() const439 QSurfaceFormat::FormatOptions QSurfaceFormat::options() const
440 {
441     return d->opts;
442 }
443 
444 /*!
445     Set the minimum depth buffer size to \a size.
446 
447     \sa depthBufferSize()
448 */
setDepthBufferSize(int size)449 void QSurfaceFormat::setDepthBufferSize(int size)
450 {
451     if (d->depthSize != size) {
452         detach();
453         d->depthSize = size;
454     }
455 }
456 
457 /*!
458     Returns the depth buffer size.
459 
460     \sa setDepthBufferSize()
461 */
depthBufferSize() const462 int QSurfaceFormat::depthBufferSize() const
463 {
464    return d->depthSize;
465 }
466 
467 /*!
468     Set the swap \a behavior of the surface.
469 
470     The swap behavior specifies whether single, double, or triple
471     buffering is desired. The default, DefaultSwapBehavior,
472     gives the default swap behavior of the platform.
473 */
setSwapBehavior(SwapBehavior behavior)474 void QSurfaceFormat::setSwapBehavior(SwapBehavior behavior)
475 {
476     if (d->swapBehavior != behavior) {
477         detach();
478         d->swapBehavior = behavior;
479     }
480 }
481 
482 /*!
483     Returns the configured swap behaviour.
484 
485     \sa setSwapBehavior()
486 */
swapBehavior() const487 QSurfaceFormat::SwapBehavior QSurfaceFormat::swapBehavior() const
488 {
489     return d->swapBehavior;
490 }
491 
492 /*!
493     Returns \c true if the alpha buffer size is greater than zero.
494 
495     This means that the surface might be used with per pixel
496     translucency effects.
497 */
hasAlpha() const498 bool QSurfaceFormat::hasAlpha() const
499 {
500     return d->alphaBufferSize > 0;
501 }
502 
503 /*!
504     Set the preferred stencil buffer size to \a size bits.
505 
506     \sa stencilBufferSize()
507 */
setStencilBufferSize(int size)508 void QSurfaceFormat::setStencilBufferSize(int size)
509 {
510     if (d->stencilSize != size) {
511         detach();
512         d->stencilSize = size;
513     }
514 }
515 
516 /*!
517     Returns the stencil buffer size in bits.
518 
519     \sa setStencilBufferSize()
520 */
stencilBufferSize() const521 int QSurfaceFormat::stencilBufferSize() const
522 {
523    return d->stencilSize;
524 }
525 
526 /*!
527     Get the size in bits of the red channel of the color buffer.
528 */
redBufferSize() const529 int QSurfaceFormat::redBufferSize() const
530 {
531     return d->redBufferSize;
532 }
533 
534 /*!
535     Get the size in bits of the green channel of the color buffer.
536 */
greenBufferSize() const537 int QSurfaceFormat::greenBufferSize() const
538 {
539     return d->greenBufferSize;
540 }
541 
542 /*!
543     Get the size in bits of the blue channel of the color buffer.
544 */
blueBufferSize() const545 int QSurfaceFormat::blueBufferSize() const
546 {
547     return d->blueBufferSize;
548 }
549 
550 /*!
551     Get the size in bits of the alpha channel of the color buffer.
552 */
alphaBufferSize() const553 int QSurfaceFormat::alphaBufferSize() const
554 {
555     return d->alphaBufferSize;
556 }
557 
558 /*!
559     Set the desired \a size in bits of the red channel of the color buffer.
560 */
setRedBufferSize(int size)561 void QSurfaceFormat::setRedBufferSize(int size)
562 {
563     if (d->redBufferSize != size) {
564         detach();
565         d->redBufferSize = size;
566     }
567 }
568 
569 /*!
570     Set the desired \a size in bits of the green channel of the color buffer.
571 */
setGreenBufferSize(int size)572 void QSurfaceFormat::setGreenBufferSize(int size)
573 {
574     if (d->greenBufferSize != size) {
575         detach();
576         d->greenBufferSize = size;
577     }
578 }
579 
580 /*!
581     Set the desired \a size in bits of the blue channel of the color buffer.
582 */
setBlueBufferSize(int size)583 void QSurfaceFormat::setBlueBufferSize(int size)
584 {
585     if (d->blueBufferSize != size) {
586         detach();
587         d->blueBufferSize = size;
588     }
589 }
590 
591 /*!
592     Set the desired \a size in bits of the alpha channel of the color buffer.
593 */
setAlphaBufferSize(int size)594 void QSurfaceFormat::setAlphaBufferSize(int size)
595 {
596     if (d->alphaBufferSize != size) {
597         detach();
598         d->alphaBufferSize = size;
599     }
600 }
601 
602 /*!
603     Sets the desired renderable \a type.
604 
605     Chooses between desktop OpenGL, OpenGL ES, and OpenVG.
606 */
setRenderableType(RenderableType type)607 void QSurfaceFormat::setRenderableType(RenderableType type)
608 {
609     if (d->renderableType != type) {
610         detach();
611         d->renderableType = type;
612     }
613 }
614 
615 /*!
616     Gets the renderable type.
617 
618     Chooses between desktop OpenGL, OpenGL ES, and OpenVG.
619 */
renderableType() const620 QSurfaceFormat::RenderableType QSurfaceFormat::renderableType() const
621 {
622     return d->renderableType;
623 }
624 
625 /*!
626     Sets the desired OpenGL context \a profile.
627 
628     This setting is ignored if the requested OpenGL version is
629     less than 3.2.
630 */
setProfile(OpenGLContextProfile profile)631 void QSurfaceFormat::setProfile(OpenGLContextProfile profile)
632 {
633     if (d->profile != profile) {
634         detach();
635         d->profile = profile;
636     }
637 }
638 
639 /*!
640     Get the configured OpenGL context profile.
641 
642     This setting is ignored if the requested OpenGL version is
643     less than 3.2.
644 */
profile() const645 QSurfaceFormat::OpenGLContextProfile QSurfaceFormat::profile() const
646 {
647     return d->profile;
648 }
649 
650 /*!
651     Sets the desired \a major OpenGL version.
652 */
setMajorVersion(int major)653 void QSurfaceFormat::setMajorVersion(int major)
654 {
655     if (d->major != major) {
656         detach();
657         d->major = major;
658     }
659 }
660 
661 /*!
662     Returns the major OpenGL version.
663 
664     The default version is 2.0.
665 */
majorVersion() const666 int QSurfaceFormat::majorVersion() const
667 {
668     return d->major;
669 }
670 
671 /*!
672     Sets the desired \a minor OpenGL version.
673 
674     The default version is 2.0.
675 */
setMinorVersion(int minor)676 void QSurfaceFormat::setMinorVersion(int minor)
677 {
678     if (d->minor != minor) {
679         detach();
680         d->minor = minor;
681     }
682 }
683 
684 /*!
685     Returns the minor OpenGL version.
686 */
minorVersion() const687 int QSurfaceFormat::minorVersion() const
688 {
689     return d->minor;
690 }
691 
692 /*!
693     Returns a QPair<int, int> representing the OpenGL version.
694 
695     Useful for version checks, for example format.version() >= qMakePair(3, 2)
696 */
version() const697 QPair<int, int> QSurfaceFormat::version() const
698 {
699     return qMakePair(d->major, d->minor);
700 }
701 
702 /*!
703     Sets the desired \a major and \a minor OpenGL versions.
704 
705     The default version is 2.0.
706 */
setVersion(int major,int minor)707 void QSurfaceFormat::setVersion(int major, int minor)
708 {
709     if (d->minor != minor || d->major != major) {
710         detach();
711         d->minor = minor;
712         d->major = major;
713     }
714 }
715 
716 /*!
717     Sets the preferred swap interval. The swap interval specifies the
718     minimum number of video frames that are displayed before a buffer
719     swap occurs. This can be used to sync the GL drawing into a window
720     to the vertical refresh of the screen.
721 
722     Setting an \a interval value of 0 will turn the vertical refresh
723     syncing off, any value higher than 0 will turn the vertical
724     syncing on. Setting \a interval to a higher value, for example 10,
725     results in having 10 vertical retraces between every buffer swap.
726 
727     The default interval is 1.
728 
729     Changing the swap interval may not be supported by the underlying
730     platform. In this case, the request will be silently ignored.
731 
732     \since 5.3
733 
734     \sa swapInterval()
735  */
setSwapInterval(int interval)736 void QSurfaceFormat::setSwapInterval(int interval)
737 {
738     if (d->swapInterval != interval) {
739         detach();
740         d->swapInterval = interval;
741     }
742 }
743 
744 /*!
745     Returns the swap interval.
746 
747     \since 5.3
748 
749     \sa setSwapInterval()
750 */
swapInterval() const751 int QSurfaceFormat::swapInterval() const
752 {
753     return d->swapInterval;
754 }
755 
756 /*!
757     Sets the preferred \a colorSpace.
758 
759     For example, this allows requesting windows with default framebuffers that
760     are sRGB-capable on platforms that support it.
761 
762     \note When the requested color space is not supported by the platform, the
763     request is ignored. Query the QSurfaceFormat after window creation to verify
764     if the color space request could be honored or not.
765 
766     \note This setting controls if the default framebuffer of the window is
767     capable of updates and blending in a given color space. It does not change
768     applications' output by itself. The applications' rendering code will still
769     have to opt in via the appropriate OpenGL calls to enable updates and
770     blending to be performed in the given color space instead of using the
771     standard linear operations.
772 
773     \since 5.10
774 
775     \sa colorSpace()
776  */
setColorSpace(ColorSpace colorSpace)777 void QSurfaceFormat::setColorSpace(ColorSpace colorSpace)
778 {
779     if (d->colorSpace != colorSpace) {
780         detach();
781         d->colorSpace = colorSpace;
782     }
783 }
784 
785 /*!
786     \return the color space.
787 
788     \since 5.10
789 
790     \sa setColorSpace()
791 */
colorSpace() const792 QSurfaceFormat::ColorSpace QSurfaceFormat::colorSpace() const
793 {
794     return d->colorSpace;
795 }
796 
Q_GLOBAL_STATIC(QSurfaceFormat,qt_default_surface_format)797 Q_GLOBAL_STATIC(QSurfaceFormat, qt_default_surface_format)
798 
799 /*!
800     Sets the global default surface \a format.
801 
802     This format is used by default in QOpenGLContext, QWindow, QOpenGLWidget and
803     similar classes.
804 
805     It can always be overridden on a per-instance basis by using the class in
806     question's own setFormat() function. However, it is often more convenient to
807     set the format for all windows once at the start of the application. It also
808     guarantees proper behavior in cases where shared contexts are required,
809     because settings the format via this function guarantees that all contexts
810     and surfaces, even the ones created internally by Qt, will use the same
811     format.
812 
813     \note When setting Qt::AA_ShareOpenGLContexts, it is strongly recommended to
814     place the call to this function before the construction of the
815     QGuiApplication or QApplication. Otherwise \a format will not be applied to
816     the global share context and therefore issues may arise with context sharing
817     afterwards.
818 
819     \since 5.4
820     \sa defaultFormat()
821  */
822 void QSurfaceFormat::setDefaultFormat(const QSurfaceFormat &format)
823 {
824 #ifndef QT_NO_OPENGL
825     if (qApp) {
826         QOpenGLContext *globalContext = QOpenGLContext::globalShareContext();
827         if (globalContext && globalContext->isValid()) {
828             qWarning("Warning: Setting a new default format with a different version or profile "
829                      "after the global shared context is created may cause issues with context "
830                      "sharing.");
831         }
832     }
833 #endif
834     *qt_default_surface_format() = format;
835 }
836 
837 /*!
838     Returns the global default surface format.
839 
840     When setDefaultFormat() is not called, this is a default-constructed QSurfaceFormat.
841 
842     \since 5.4
843     \sa setDefaultFormat()
844  */
defaultFormat()845 QSurfaceFormat QSurfaceFormat::defaultFormat()
846 {
847     return *qt_default_surface_format();
848 }
849 
850 /*!
851     Returns \c true if all the options of the two QSurfaceFormat objects
852     \a a and \a b are equal.
853 
854     \relates QSurfaceFormat
855 */
operator ==(const QSurfaceFormat & a,const QSurfaceFormat & b)856 bool operator==(const QSurfaceFormat& a, const QSurfaceFormat& b)
857 {
858     return (a.d == b.d) || ((int) a.d->opts == (int) b.d->opts
859         && a.d->stencilSize == b.d->stencilSize
860         && a.d->redBufferSize == b.d->redBufferSize
861         && a.d->greenBufferSize == b.d->greenBufferSize
862         && a.d->blueBufferSize == b.d->blueBufferSize
863         && a.d->alphaBufferSize == b.d->alphaBufferSize
864         && a.d->depthSize == b.d->depthSize
865         && a.d->numSamples == b.d->numSamples
866         && a.d->swapBehavior == b.d->swapBehavior
867         && a.d->profile == b.d->profile
868         && a.d->major == b.d->major
869         && a.d->minor == b.d->minor
870         && a.d->swapInterval == b.d->swapInterval);
871 }
872 
873 /*!
874     Returns \c false if all the options of the two QSurfaceFormat objects
875     \a a and \a b are equal; otherwise returns \c true.
876 
877     \relates QSurfaceFormat
878 */
operator !=(const QSurfaceFormat & a,const QSurfaceFormat & b)879 bool operator!=(const QSurfaceFormat& a, const QSurfaceFormat& b)
880 {
881     return !(a == b);
882 }
883 
884 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug dbg,const QSurfaceFormat & f)885 QDebug operator<<(QDebug dbg, const QSurfaceFormat &f)
886 {
887     const QSurfaceFormatPrivate * const d = f.d;
888     QDebugStateSaver saver(dbg);
889 
890     dbg.nospace() << "QSurfaceFormat("
891                   << "version " << d->major << '.' << d->minor
892                   << ", options " << d->opts
893                   << ", depthBufferSize " << d->depthSize
894                   << ", redBufferSize " << d->redBufferSize
895                   << ", greenBufferSize " << d->greenBufferSize
896                   << ", blueBufferSize " << d->blueBufferSize
897                   << ", alphaBufferSize " << d->alphaBufferSize
898                   << ", stencilBufferSize " << d->stencilSize
899                   << ", samples " << d->numSamples
900                   << ", swapBehavior " << d->swapBehavior
901                   << ", swapInterval " << d->swapInterval
902                   << ", colorSpace " << d->colorSpace
903                   << ", profile  " << d->profile
904                   << ')';
905 
906     return dbg;
907 }
908 #endif
909 
910 QT_END_NAMESPACE
911