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