Fixed missing way of choosing EGL renderable type with QSurfaceFormat.
[profile/ivi/qtbase.git] / src / gui / kernel / qsurfaceformat.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qsurfaceformat.h"
43
44 #include <QtCore/qatomic.h>
45 #include <QtCore/QDebug>
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 = 0)
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     {
76     }
77
78     QSurfaceFormatPrivate(const QSurfaceFormatPrivate *other)
79         : ref(1),
80           opts(other->opts),
81           redBufferSize(other->redBufferSize),
82           greenBufferSize(other->greenBufferSize),
83           blueBufferSize(other->blueBufferSize),
84           alphaBufferSize(other->alphaBufferSize),
85           depthSize(other->depthSize),
86           stencilSize(other->stencilSize),
87           swapBehavior(other->swapBehavior),
88           numSamples(other->numSamples),
89           renderableType(other->renderableType),
90           profile(other->profile),
91           major(other->major),
92           minor(other->minor)
93     {
94     }
95
96     QAtomicInt ref;
97     QSurfaceFormat::FormatOptions opts;
98     int redBufferSize;
99     int greenBufferSize;
100     int blueBufferSize;
101     int alphaBufferSize;
102     int depthSize;
103     int stencilSize;
104     QSurfaceFormat::SwapBehavior swapBehavior;
105     int numSamples;
106     QSurfaceFormat::RenderableType renderableType;
107     QSurfaceFormat::OpenGLContextProfile profile;
108     int major;
109     int minor;
110 };
111
112 /*!
113     \class QSurfaceFormat
114     \since 5.0
115     \brief The QSurfaceFormat class represents the format of a QSurface.
116
117     The format includes the size of the color buffers, red, green, and blue;
118     the size of the alpha buffer; the size of the depth and stencil buffers;
119     and number of samples per pixel for multisampling. In addition, the format
120     contains surface configuration parameters such as OpenGL profile and
121     version for rendering, whether or not enable stereo buffers, and swap
122     behaviour.
123 */
124
125 /*!
126     \enum QSurfaceFormat::FormatOption
127
128     This enum contains format options for use with QSurfaceFormat.
129
130     \value StereoBuffers Used to request stereo buffers in the surface format.
131     \value DebugContext Used to request a debug context with extra debugging information.
132         This requires OpenGL version 3.0 or higher.
133     \value DeprecatedFunctions Used to request that deprecated functions be included
134         in the OpenGL context profile. If not specified, you should get a forward compatible context
135         without support functionality marked as deprecated. This requires OpenGL version 3.0 or higher.
136 */
137
138 /*!
139     \enum QSurfaceFormat::SwapBehavior
140
141     This enum is used by QSurfaceFormat to specify the swap behaviour of a surface. The swap behaviour
142     is mostly transparent to the application, but it affects factors such as rendering latency and
143     throughput.
144
145     \value DefaultSwapBehavior The default, unspecified swap behaviour of the platform.
146     \value SingleBuffer Used to request single buffering, which might result in flickering
147         when OpenGL rendering is done directly to screen without an intermediate offscreen
148         buffer.
149     \value DoubleBuffer This is typically the default swap behaviour on desktop platforms,
150         consisting of one back buffer and one front buffer. Rendering is done to the back
151         buffer, and then the back buffer and front buffer are swapped, or the contents of
152         the back buffer are copied to the front buffer, depending on the implementation.
153     \value TripleBuffer This swap behaviour is sometimes used in order to decrease the
154         risk of skipping a frame when the rendering rate is just barely keeping up with
155         the screen refresh rate. Depending on the platform it might also lead to slightly
156         more efficient use of the GPU due to improved pipelining behaviour. Triple buffering
157         comes at the cost of an extra frame of memory usage and latency, and might not be
158         supported depending on the underlying platform.
159 */
160
161 /*!
162     \enum QSurfaceFormat::OpenGLContextProfile
163
164     This enum is used to specify the OpenGL context profile, in
165     conjunction with QSurfaceFormat::setMajorVersion() and
166     QSurfaceFormat::setMinorVersion().
167
168     Profiles are exposed in OpenGL 3.2 and above, and are used
169     to choose between a restricted core profile, and a compatibility
170     profile which might contain deprecated support functionality.
171
172     Note that the core profile might still contain functionality that
173     is deprecated and scheduled for removal in a higher version. To
174     get access to the deprecated functionality for the core profile
175     in the set OpenGL version you can use the QSurfaceFormat format option
176     QSurfaceFormat::DeprecatedFunctions.
177
178     \value NoProfile            OpenGL version is lower than 3.2.
179     \value CoreProfile          Functionality deprecated in OpenGL version 3.0 is not available.
180     \value CompatibilityProfile Functionality from earlier OpenGL versions is available.
181 */
182
183 /*!
184     Constructs a default initialized QSurfaceFormat.
185 */
186 QSurfaceFormat::QSurfaceFormat() : d(new QSurfaceFormatPrivate)
187 {
188 }
189
190 /*!
191     Constructs a QSurfaceFormat with the given format \a options.
192 */
193 QSurfaceFormat::QSurfaceFormat(QSurfaceFormat::FormatOptions options) :
194     d(new QSurfaceFormatPrivate(options))
195 {
196 }
197
198 /*!
199     \internal
200 */
201 void QSurfaceFormat::detach()
202 {
203     if (d->ref.load() != 1) {
204         QSurfaceFormatPrivate *newd = new QSurfaceFormatPrivate(d);
205         if (!d->ref.deref())
206             delete d;
207         d = newd;
208     }
209 }
210
211 /*!
212     Constructs a copy of \a other.
213 */
214 QSurfaceFormat::QSurfaceFormat(const QSurfaceFormat &other)
215 {
216     d = other.d;
217     d->ref.ref();
218 }
219
220 /*!
221     Assigns \a other to this object.
222 */
223 QSurfaceFormat &QSurfaceFormat::operator=(const QSurfaceFormat &other)
224 {
225     if (d != other.d) {
226         other.d->ref.ref();
227         if (!d->ref.deref())
228             delete d;
229         d = other.d;
230     }
231     return *this;
232 }
233
234 /*!
235     Destroys the QSurfaceFormat.
236 */
237 QSurfaceFormat::~QSurfaceFormat()
238 {
239     if (!d->ref.deref())
240         delete d;
241 }
242
243 /*!
244     \fn bool QSurfaceFormat::stereo() const
245
246     Returns true if stereo buffering is enabled; otherwise returns
247     false. Stereo buffering is disabled by default.
248
249     \sa setStereo()
250 */
251
252 /*!
253     If \a enable is true enables stereo buffering; otherwise disables
254     stereo buffering.
255
256     Stereo buffering is disabled by default.
257
258     Stereo buffering provides extra color buffers to generate left-eye
259     and right-eye images.
260
261     \sa stereo()
262 */
263 void QSurfaceFormat::setStereo(bool enable)
264 {
265     QSurfaceFormat::FormatOptions newOptions = d->opts;
266     if (enable) {
267         newOptions |= QSurfaceFormat::StereoBuffers;
268     } else {
269         newOptions &= ~QSurfaceFormat::StereoBuffers;
270     }
271     if (int(newOptions) != int(d->opts)) {
272         detach();
273         d->opts = newOptions;
274     }
275 }
276
277 /*!
278     Returns the number of samples per pixel when multisampling is
279     enabled. By default, multisampling is disabled.
280
281     \sa setSampleBuffers(), sampleBuffers(), setSamples()
282 */
283 int QSurfaceFormat::samples() const
284 {
285    return d->numSamples;
286 }
287
288 /*!
289     Set the preferred number of samples per pixel when multisampling
290     is enabled to \a numSamples. By default, multisampling is disabled.
291
292     \sa setSampleBuffers(), sampleBuffers(), samples()
293 */
294 void QSurfaceFormat::setSamples(int numSamples)
295 {
296     if (d->numSamples != numSamples) {
297         detach();
298         d->numSamples = numSamples;
299     }
300 }
301
302 /*!
303     Sets the format option to \a opt.
304
305     \sa testOption()
306 */
307 void QSurfaceFormat::setOption(QSurfaceFormat::FormatOptions opt)
308 {
309     const QSurfaceFormat::FormatOptions newOptions = d->opts | opt;
310     if (int(newOptions) != int(d->opts)) {
311         detach();
312         d->opts = newOptions;
313     }
314 }
315
316 /*!
317     Returns true if format option \a opt is set; otherwise returns false.
318
319     \sa setOption()
320 */
321 bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOptions opt) const
322 {
323     return d->opts & opt;
324 }
325
326 /*!
327     Set the minimum depth buffer size to \a size.
328
329     \sa depthBufferSize(), setDepth(), depth()
330 */
331 void QSurfaceFormat::setDepthBufferSize(int size)
332 {
333     if (d->depthSize != size) {
334         detach();
335         d->depthSize = size;
336     }
337 }
338
339 /*!
340     Returns the depth buffer size.
341
342     \sa depth(), setDepth(), setDepthBufferSize()
343 */
344 int QSurfaceFormat::depthBufferSize() const
345 {
346    return d->depthSize;
347 }
348
349 /*!
350     Set the swap behaviour of the surface.
351
352     The swap behaviour specifies whether single, double, or triple
353     buffering is desired. The default, SwapBehavior::DefaultSwapBehavior,
354     gives the default swap behavior of the platform.
355 */
356 void QSurfaceFormat::setSwapBehavior(SwapBehavior behavior)
357 {
358     if (d->swapBehavior != behavior) {
359         detach();
360         d->swapBehavior = behavior;
361     }
362 }
363
364 /*!
365     Returns the configured swap behaviour.
366
367     \sa setSwapBehavior()
368 */
369 QSurfaceFormat::SwapBehavior QSurfaceFormat::swapBehavior() const
370 {
371     return d->swapBehavior;
372 }
373
374 /*!
375     Returns true if the alpha buffer size is greater than zero.
376
377     This means that the surface might be used with per pixel
378     translucency effects.
379 */
380 bool QSurfaceFormat::hasAlpha() const
381 {
382     return d->alphaBufferSize > 0;
383 }
384
385 /*!
386     Set the preferred stencil buffer size to \a size bits.
387
388     \sa stencilBufferSize(), setStencil(), stencil()
389 */
390 void QSurfaceFormat::setStencilBufferSize(int size)
391 {
392     if (d->stencilSize != size) {
393         detach();
394         d->stencilSize = size;
395     }
396 }
397
398 /*!
399     Returns the stencil buffer size in bits.
400
401     \sa stencil(), setStencil(), setStencilBufferSize()
402 */
403 int QSurfaceFormat::stencilBufferSize() const
404 {
405    return d->stencilSize;
406 }
407
408 /*!
409     Get the size in bits of the red channel of the color buffer.
410 */
411 int QSurfaceFormat::redBufferSize() const
412 {
413     return d->redBufferSize;
414 }
415
416 /*!
417     Get the size in bits of the green channel of the color buffer.
418 */
419 int QSurfaceFormat::greenBufferSize() const
420 {
421     return d->greenBufferSize;
422 }
423
424 /*!
425     Get the size in bits of the blue channel of the color buffer.
426 */
427 int QSurfaceFormat::blueBufferSize() const
428 {
429     return d->blueBufferSize;
430 }
431
432 /*!
433     Get the size in bits of the alpha channel of the color buffer.
434 */
435 int QSurfaceFormat::alphaBufferSize() const
436 {
437     return d->alphaBufferSize;
438 }
439
440 /*!
441     Set the desired size in bits of the red channel of the color buffer.
442 */
443 void QSurfaceFormat::setRedBufferSize(int size)
444 {
445     if (d->redBufferSize != size) {
446         detach();
447         d->redBufferSize = size;
448     }
449 }
450
451 /*!
452     Set the desired size in bits of the green channel of the color buffer.
453 */
454 void QSurfaceFormat::setGreenBufferSize(int size)
455 {
456     if (d->greenBufferSize != size) {
457         detach();
458         d->greenBufferSize = size;
459     }
460 }
461
462 /*!
463     Set the desired size in bits of the blue channel of the color buffer.
464 */
465 void QSurfaceFormat::setBlueBufferSize(int size)
466 {
467     if (d->blueBufferSize != size) {
468         detach();
469         d->blueBufferSize = size;
470     }
471 }
472
473 /*!
474     Set the desired size in bits of the alpha channel of the color buffer.
475 */
476 void QSurfaceFormat::setAlphaBufferSize(int size)
477 {
478     if (d->alphaBufferSize != size) {
479         detach();
480         d->alphaBufferSize = size;
481     }
482 }
483
484 /*!
485     Sets the desired renderable type.
486
487     Chooses between desktop OpenGL, OpenGL ES, and OpenVG.
488 */
489 void QSurfaceFormat::setRenderableType(RenderableType type)
490 {
491     if (d->renderableType != type) {
492         detach();
493         d->renderableType = type;
494     }
495 }
496
497 /*!
498     Gets the renderable type.
499
500     Chooses between desktop OpenGL, OpenGL ES, and OpenVG.
501 */
502 QSurfaceFormat::RenderableType QSurfaceFormat::renderableType() const
503 {
504     return d->renderableType;
505 }
506
507 /*!
508     Sets the desired OpenGL context profile.
509
510     This setting is ignored if the requested OpenGL version is
511     less than 3.2.
512 */
513 void QSurfaceFormat::setProfile(OpenGLContextProfile profile)
514 {
515     if (d->profile != profile) {
516         detach();
517         d->profile = profile;
518     }
519 }
520
521 /*!
522     Get the configured OpenGL context profile.
523
524     This setting is ignored if the requested OpenGL version is
525     less than 3.2.
526 */
527 QSurfaceFormat::OpenGLContextProfile QSurfaceFormat::profile() const
528 {
529     return d->profile;
530 }
531
532 /*!
533     Sets the desired major OpenGL version.
534 */
535 void QSurfaceFormat::setMajorVersion(int major)
536 {
537     if (d->major != major) {
538         detach();
539         d->major = major;
540     }
541 }
542
543 /*!
544     Returns the major OpenGL version.
545
546     The default version is 2.0.
547 */
548 int QSurfaceFormat::majorVersion() const
549 {
550     return d->major;
551 }
552
553 /*!
554     Sets the desired minor OpenGL version.
555
556     The default version is 2.0.
557 */
558 void QSurfaceFormat::setMinorVersion(int minor)
559 {
560     if (d->minor != minor) {
561         detach();
562         d->minor = minor;
563     }
564 }
565
566 /*!
567     Returns the minor OpenGL version.
568 */
569 int QSurfaceFormat::minorVersion() const
570 {
571     return d->minor;
572 }
573
574 /*!
575     Returns true if all the options of the two QSurfaceFormat objects
576     are equal.
577
578     \relates QSurfaceFormat
579 */
580 bool operator==(const QSurfaceFormat& a, const QSurfaceFormat& b)
581 {
582     return (a.d == b.d) || ((int) a.d->opts == (int) b.d->opts
583         && a.d->stencilSize == b.d->stencilSize
584         && a.d->redBufferSize == b.d->redBufferSize
585         && a.d->greenBufferSize == b.d->greenBufferSize
586         && a.d->blueBufferSize == b.d->blueBufferSize
587         && a.d->alphaBufferSize == b.d->alphaBufferSize
588         && a.d->depthSize == b.d->depthSize
589         && a.d->numSamples == b.d->numSamples
590         && a.d->swapBehavior == b.d->swapBehavior
591         && a.d->profile == b.d->profile
592         && a.d->major == b.d->major
593         && a.d->minor == b.d->minor);
594 }
595
596 /*!
597     Returns false if all the options of the two QSurfaceFormat objects
598     \a a and \a b are equal; otherwise returns true.
599
600     \relates QSurfaceFormat
601 */
602 bool operator!=(const QSurfaceFormat& a, const QSurfaceFormat& b)
603 {
604     return !(a == b);
605 }
606
607 #ifndef QT_NO_DEBUG_STREAM
608 QDebug operator<<(QDebug dbg, const QSurfaceFormat &f)
609 {
610     const QSurfaceFormatPrivate * const d = f.d;
611
612     dbg.nospace() << "QSurfaceFormat("
613                   << "version " << d->major << '.' << d->minor
614                   << ", options " << d->opts
615                   << ", depthBufferSize " << d->depthSize
616                   << ", redBufferSize " << d->redBufferSize
617                   << ", greenBufferSize " << d->greenBufferSize
618                   << ", blueBufferSize " << d->blueBufferSize
619                   << ", alphaBufferSize " << d->alphaBufferSize
620                   << ", stencilBufferSize " << d->stencilSize
621                   << ", samples " << d->numSamples
622                   << ", swapBehavior " << d->swapBehavior
623                   << ", profile  " << d->profile
624                   << ')';
625
626     return dbg.space();
627 }
628 #endif
629
630 QT_END_NAMESPACE