Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsurfaceformat.cpp
Go to the documentation of this file.
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
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
26
28{
29public:
48
68
81 int major;
82 int minor;
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*/
208QSurfaceFormat::QSurfaceFormat() : d(new QSurfaceFormatPrivate)
209{
210}
211
212/*!
213 Constructs a QSurfaceFormat with the given format \a options.
214*/
215QSurfaceFormat::QSurfaceFormat(QSurfaceFormat::FormatOptions options) :
216 d(new QSurfaceFormatPrivate(options))
217{
218}
219
220/*!
221 \internal
222*/
223void QSurfaceFormat::detach()
224{
225 if (d->ref.loadRelaxed() != 1) {
226 QSurfaceFormatPrivate *newd = new QSurfaceFormatPrivate(d);
227 if (!d->ref.deref())
228 delete d;
229 d = newd;
230 }
231}
232
233/*!
234 Constructs a copy of \a other.
235*/
236QSurfaceFormat::QSurfaceFormat(const QSurfaceFormat &other)
237{
238 d = other.d;
239 d->ref.ref();
240}
241
242/*!
243 Assigns \a other to this object.
244*/
245QSurfaceFormat &QSurfaceFormat::operator=(const QSurfaceFormat &other)
246{
247 if (d != other.d) {
248 other.d->ref.ref();
249 if (!d->ref.deref())
250 delete d;
251 d = other.d;
252 }
253 return *this;
254}
255
256/*!
257 Destroys the QSurfaceFormat.
258*/
259QSurfaceFormat::~QSurfaceFormat()
260{
261 if (!d->ref.deref())
262 delete d;
263}
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*/
285void QSurfaceFormat::setStereo(bool enable)
286{
287 QSurfaceFormat::FormatOptions newOptions = d->opts;
288 newOptions.setFlag(QSurfaceFormat::StereoBuffers, enable);
289
290 if (int(newOptions) != int(d->opts)) {
291 detach();
292 d->opts = newOptions;
293 }
294}
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*/
303int QSurfaceFormat::samples() const
304{
305 return d->numSamples;
306}
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*/
314void QSurfaceFormat::setSamples(int numSamples)
315{
316 if (d->numSamples != numSamples) {
317 detach();
318 d->numSamples = numSamples;
319 }
320}
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*/
332void QSurfaceFormat::setOptions(QSurfaceFormat::FormatOptions options)
333{
334 if (int(d->opts) != int(options)) {
335 detach();
336 d->opts = options;
337 }
338}
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*/
350void QSurfaceFormat::setOption(QSurfaceFormat::FormatOption option, bool on)
351{
352 if (testOption(option) == on)
353 return;
354 detach();
355 if (on)
356 d->opts |= option;
357 else
358 d->opts &= ~option;
359}
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*/
368bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOption option) const
369{
370 return d->opts & option;
371}
372
373/*!
374 \since 5.3
375
376 Returns the currently set format options.
377
378 \sa setOption(), setOptions(), testOption()
379*/
380QSurfaceFormat::FormatOptions QSurfaceFormat::options() const
381{
382 return d->opts;
383}
384
385/*!
386 Set the minimum depth buffer size to \a size.
387
388 \sa depthBufferSize()
389*/
390void QSurfaceFormat::setDepthBufferSize(int size)
391{
392 if (d->depthSize != size) {
393 detach();
394 d->depthSize = size;
395 }
396}
397
398/*!
399 Returns the depth buffer size.
400
401 \sa setDepthBufferSize()
402*/
403int QSurfaceFormat::depthBufferSize() const
404{
405 return d->depthSize;
406}
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*/
415void QSurfaceFormat::setSwapBehavior(SwapBehavior behavior)
416{
417 if (d->swapBehavior != behavior) {
418 detach();
419 d->swapBehavior = behavior;
420 }
421}
422
423/*!
424 Returns the configured swap behaviour.
425
426 \sa setSwapBehavior()
427*/
428QSurfaceFormat::SwapBehavior QSurfaceFormat::swapBehavior() const
429{
430 return d->swapBehavior;
431}
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*/
439bool QSurfaceFormat::hasAlpha() const
440{
441 return d->alphaBufferSize > 0;
442}
443
444/*!
445 Set the preferred stencil buffer size to \a size bits.
446
447 \sa stencilBufferSize()
448*/
449void QSurfaceFormat::setStencilBufferSize(int size)
450{
451 if (d->stencilSize != size) {
452 detach();
453 d->stencilSize = size;
454 }
455}
456
457/*!
458 Returns the stencil buffer size in bits.
459
460 \sa setStencilBufferSize()
461*/
462int QSurfaceFormat::stencilBufferSize() const
463{
464 return d->stencilSize;
465}
466
467/*!
468 Get the size in bits of the red channel of the color buffer.
469*/
470int QSurfaceFormat::redBufferSize() const
471{
472 return d->redBufferSize;
473}
474
475/*!
476 Get the size in bits of the green channel of the color buffer.
477*/
478int QSurfaceFormat::greenBufferSize() const
479{
480 return d->greenBufferSize;
481}
482
483/*!
484 Get the size in bits of the blue channel of the color buffer.
485*/
486int QSurfaceFormat::blueBufferSize() const
487{
488 return d->blueBufferSize;
489}
490
491/*!
492 Get the size in bits of the alpha channel of the color buffer.
493*/
494int QSurfaceFormat::alphaBufferSize() const
495{
496 return d->alphaBufferSize;
497}
498
499/*!
500 Set the desired \a size in bits of the red channel of the color buffer.
501*/
502void QSurfaceFormat::setRedBufferSize(int size)
503{
504 if (d->redBufferSize != size) {
505 detach();
506 d->redBufferSize = size;
507 }
508}
509
510/*!
511 Set the desired \a size in bits of the green channel of the color buffer.
512*/
513void QSurfaceFormat::setGreenBufferSize(int size)
514{
515 if (d->greenBufferSize != size) {
516 detach();
517 d->greenBufferSize = size;
518 }
519}
520
521/*!
522 Set the desired \a size in bits of the blue channel of the color buffer.
523*/
524void QSurfaceFormat::setBlueBufferSize(int size)
525{
526 if (d->blueBufferSize != size) {
527 detach();
528 d->blueBufferSize = size;
529 }
530}
531
532/*!
533 Set the desired \a size in bits of the alpha channel of the color buffer.
534*/
535void QSurfaceFormat::setAlphaBufferSize(int size)
536{
537 if (d->alphaBufferSize != size) {
538 detach();
539 d->alphaBufferSize = size;
540 }
541}
542
543/*!
544 Sets the desired renderable \a type.
545
546 Chooses between desktop OpenGL, OpenGL ES, and OpenVG.
547*/
548void QSurfaceFormat::setRenderableType(RenderableType type)
549{
550 if (d->renderableType != type) {
551 detach();
552 d->renderableType = type;
553 }
554}
555
556/*!
557 Gets the renderable type.
558
559 Chooses between desktop OpenGL, OpenGL ES, and OpenVG.
560*/
561QSurfaceFormat::RenderableType QSurfaceFormat::renderableType() const
562{
563 return d->renderableType;
564}
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*/
572void QSurfaceFormat::setProfile(OpenGLContextProfile profile)
573{
574 if (d->profile != profile) {
575 detach();
576 d->profile = profile;
577 }
578}
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*/
586QSurfaceFormat::OpenGLContextProfile QSurfaceFormat::profile() const
587{
588 return d->profile;
589}
590
591/*!
592 Sets the desired \a major OpenGL version.
593*/
594void QSurfaceFormat::setMajorVersion(int major)
595{
596 if (d->major != major) {
597 detach();
598 d->major = major;
599 }
600}
601
602/*!
603 Returns the major OpenGL version.
604
605 The default version is 2.0.
606*/
607int QSurfaceFormat::majorVersion() const
608{
609 return d->major;
610}
611
612/*!
613 Sets the desired \a minor OpenGL version.
614
615 The default version is 2.0.
616*/
617void QSurfaceFormat::setMinorVersion(int minor)
618{
619 if (d->minor != minor) {
620 detach();
621 d->minor = minor;
622 }
623}
624
625/*!
626 Returns the minor OpenGL version.
627*/
628int QSurfaceFormat::minorVersion() const
629{
630 return d->minor;
631}
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*/
638std::pair<int, int> QSurfaceFormat::version() const
639{
640 return std::pair(d->major, d->minor);
641}
642
643/*!
644 Sets the desired \a major and \a minor OpenGL versions.
645
646 The default version is 2.0.
647*/
648void QSurfaceFormat::setVersion(int major, int minor)
649{
650 if (d->minor != minor || d->major != major) {
651 detach();
652 d->minor = minor;
653 d->major = major;
654 }
655}
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 */
677void QSurfaceFormat::setSwapInterval(int interval)
678{
679 if (d->swapInterval != interval) {
680 detach();
681 d->swapInterval = interval;
682 }
683}
684
685/*!
686 Returns the swap interval.
687
688 \since 5.3
689
690 \sa setSwapInterval()
691*/
692int QSurfaceFormat::swapInterval() const
693{
694 return d->swapInterval;
695}
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 */
718void QSurfaceFormat::setColorSpace(const QColorSpace &colorSpace)
719{
720 if (d->colorSpace != colorSpace) {
721 detach();
722 d->colorSpace = colorSpace;
723 }
724}
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 */
737void QSurfaceFormat::setColorSpace(ColorSpace colorSpace)
738{
739 switch (colorSpace) {
740 case DefaultColorSpace:
741 setColorSpace(QColorSpace());
742 break;
743 case sRGBColorSpace:
744 setColorSpace(QColorSpace::SRgb);
745 break;
746 }
747}
748#endif // QT_DEPRECATED_SINCE(6, 0)
749
750/*!
751 \return the color space.
752
753 \since 5.10
754
755 \sa setColorSpace()
756*/
757const QColorSpace &QSurfaceFormat::colorSpace() const
758{
759 return d->colorSpace;
760}
761
762Q_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 */
781void QSurfaceFormat::setDefaultFormat(const QSurfaceFormat &format)
782{
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 *qt_default_surface_format() = format;
794}
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 */
804QSurfaceFormat QSurfaceFormat::defaultFormat()
805{
806 return *qt_default_surface_format();
807}
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*/
826bool QSurfaceFormat::equals(const QSurfaceFormat& other) const noexcept
827{
828 return (d == other.d) || ((int) d->opts == (int) other.d->opts
829 && d->stencilSize == other.d->stencilSize
830 && d->redBufferSize == other.d->redBufferSize
831 && d->greenBufferSize == other.d->greenBufferSize
832 && d->blueBufferSize == other.d->blueBufferSize
833 && d->alphaBufferSize == other.d->alphaBufferSize
834 && d->depthSize == other.d->depthSize
835 && d->numSamples == other.d->numSamples
836 && d->swapBehavior == other.d->swapBehavior
837 && d->profile == other.d->profile
838 && d->major == other.d->major
839 && d->minor == other.d->minor
840 && d->swapInterval == other.d->swapInterval);
841}
842
843#ifndef QT_NO_DEBUG_STREAM
844QDebug operator<<(QDebug dbg, const QSurfaceFormat &f)
845{
846 const QSurfaceFormatPrivate * const d = f.d;
847 QDebugStateSaver saver(dbg);
848
849 dbg.nospace() << "QSurfaceFormat("
850 << "version " << d->major << '.' << d->minor
851 << ", options " << d->opts
852 << ", depthBufferSize " << d->depthSize
853 << ", redBufferSize " << d->redBufferSize
854 << ", greenBufferSize " << d->greenBufferSize
855 << ", blueBufferSize " << d->blueBufferSize
856 << ", alphaBufferSize " << d->alphaBufferSize
857 << ", stencilBufferSize " << d->stencilSize
858 << ", samples " << d->numSamples
859 << ", swapBehavior " << d->swapBehavior
860 << ", swapInterval " << d->swapInterval
861 << ", colorSpace " << d->colorSpace
862 << ", profile " << d->profile
863 << ')';
864
865 return dbg;
866}
867#endif
868
869QT_END_NAMESPACE
870
871#include "moc_qsurfaceformat.cpp"
QSurfaceFormatPrivate(QSurfaceFormat::FormatOptions _opts={ })
QSurfaceFormatPrivate(const QSurfaceFormatPrivate *other)
Combined button and popup list for selecting options.
Q_GLOBAL_STATIC(DefaultRoleNames, qDefaultRoleNames, { { Qt::DisplayRole, "display" }, { Qt::DecorationRole, "decoration" }, { Qt::EditRole, "edit" }, { Qt::ToolTipRole, "toolTip" }, { Qt::StatusTipRole, "statusTip" }, { Qt::WhatsThisRole, "whatsThis" }, }) const QHash< int
QDebug operator<<(QDebug dbg, const QFileInfo &fi)