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: |
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 | |
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 | */ |
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(flag: QSurfaceFormat::StereoBuffers, on: 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 | #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 | */ |
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 | */ |
381 | 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 | */ |
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 | */ |
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 | */ |
427 | 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 | */ |
439 | 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 | */ |
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 | */ |
462 | 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 | */ |
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 | */ |
487 | 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 | */ |
498 | 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 | */ |
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 | */ |
521 | 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 | */ |
529 | 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 | */ |
537 | 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 | */ |
545 | 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 | */ |
553 | 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 | */ |
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 | */ |
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 | */ |
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 | */ |
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 | */ |
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 | */ |
620 | 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 | */ |
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 | */ |
645 | QSurfaceFormat::OpenGLContextProfile QSurfaceFormat::profile() const |
646 | { |
647 | return d->profile; |
648 | } |
649 | |
650 | /*! |
651 | Sets the desired \a major OpenGL version. |
652 | */ |
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 | */ |
666 | 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 | */ |
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 | */ |
687 | 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 | */ |
697 | QPair<int, int> QSurfaceFormat::version() const |
698 | { |
699 | return qMakePair(x: d->major, y: 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 | */ |
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 | */ |
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 | */ |
751 | 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 | */ |
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 | */ |
792 | QSurfaceFormat::ColorSpace QSurfaceFormat::colorSpace() const |
793 | { |
794 | return d->colorSpace; |
795 | } |
796 | |
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(msg: "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 | */ |
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 | */ |
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 | */ |
879 | bool operator!=(const QSurfaceFormat& a, const QSurfaceFormat& b) |
880 | { |
881 | return !(a == b); |
882 | } |
883 | |
884 | #ifndef QT_NO_DEBUG_STREAM |
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 | |