Update copyright year in Nokia copyright headers.
[profile/ivi/qtdeclarative.git] / src / quick / scenegraph / qsgcontext.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtQuick/private/qsgcontext_p.h>
43 #include <QtQuick/private/qsgdefaultrenderer_p.h>
44 #include <QtQuick/private/qsgdistancefieldutil_p.h>
45 #include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h>
46 #include <QtQuick/private/qsgdefaultrectanglenode_p.h>
47 #include <QtQuick/private/qsgdefaultimagenode_p.h>
48 #include <QtQuick/private/qsgdefaultglyphnode_p.h>
49 #include <QtQuick/private/qsgdistancefieldglyphnode_p.h>
50 #include <QtQuick/private/qsgtexture_p.h>
51 #include <QtQuick/private/qdeclarativepixmapcache_p.h>
52
53 #include <QGuiApplication>
54 #include <QOpenGLContext>
55
56 #include <QDeclarativeImageProvider>
57 #include <private/qdeclarativeglobal_p.h>
58
59 #include <private/qobject_p.h>
60 #include <qmutex.h>
61
62 DEFINE_BOOL_CONFIG_OPTION(qmlFlashMode, QML_FLASH_MODE)
63 DEFINE_BOOL_CONFIG_OPTION(qmlTranslucentMode, QML_TRANSLUCENT_MODE)
64 DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
65
66 /*
67     Comments about this class from Gunnar:
68
69     The QSGContext class is right now two things.. The first is the
70     adaptation layer and central storage ground for all the things
71     in the scene graph, like textures and materials. This part really
72     belongs inside the scene graph coreapi.
73
74     The other part is the QML adaptation classes, like how to implement
75     rectangle nodes. This is not part of the scene graph core API, but
76     more part of the QML adaptation of scene graph.
77
78     If we ever move the scene graph core API into its own thing, this class
79     needs to be split in two. Right now its one because we're lazy when it comes
80     to defining plugin interfaces..
81 */
82
83
84 QT_BEGIN_NAMESPACE
85
86 class QSGContextPrivate : public QObjectPrivate
87 {
88 public:
89     QSGContextPrivate()
90         : gl(0)
91         , distanceFieldCacheManager(0)
92         , flashMode(qmlFlashMode())
93         , distanceFieldDisabled(qmlDisableDistanceField())
94     {
95         renderAlpha = qmlTranslucentMode() ? 0.5 : 1;
96     }
97
98     ~QSGContextPrivate()
99     {
100     }
101
102     QOpenGLContext *gl;
103
104     QHash<QSGMaterialType *, QSGMaterialShader *> materials;
105     QHash<QDeclarativeTextureFactory *, QSGTexture *> textures;
106
107     QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager;
108
109     bool flashMode;
110     float renderAlpha;
111     bool distanceFieldDisabled;
112 };
113
114
115 /*!
116     \class QSGContext
117
118     \brief The QSGContext holds the scene graph entry points for one QML engine.
119
120     The context is not ready for use until it has a QOpenGLContext. Once that happens,
121     the scene graph population can start.
122
123     \internal
124  */
125
126 QSGContext::QSGContext(QObject *parent) :
127     QObject(*(new QSGContextPrivate), parent)
128 {
129 }
130
131
132 QSGContext::~QSGContext()
133 {
134     invalidate();
135 }
136
137
138
139 void QSGContext::invalidate()
140 {
141     Q_D(QSGContext);
142     qDeleteAll(d->textures.values());
143     d->textures.clear();
144     qDeleteAll(d->materials.values());
145     d->materials.clear();
146     delete d->distanceFieldCacheManager;
147     d->distanceFieldCacheManager = 0;
148
149     d->gl = 0;
150
151     emit invalidated();
152 }
153
154
155 QSGTexture *QSGContext::textureForFactory(QDeclarativeTextureFactory *factory)
156 {
157     Q_D(QSGContext);
158     if (!factory)
159         return 0;
160
161     QSGTexture *texture = d->textures.value(factory);
162     if (!texture) {
163         if (QDeclarativeDefaultTextureFactory *dtf = qobject_cast<QDeclarativeDefaultTextureFactory *>(factory))
164             texture = createTexture(dtf->image());
165         else
166             texture = factory->createTexture();
167         d->textures.insert(factory, texture);
168         connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *)));
169     }
170     return texture;
171 }
172
173
174 void QSGContext::textureFactoryDestroyed(QObject *o)
175 {
176     Q_D(QSGContext);
177     QDeclarativeTextureFactory *f = static_cast<QDeclarativeTextureFactory *>(o);
178
179     // This function will only be called on the scene graph thread, so it is
180     // safe to directly delete the texture here.
181     delete d->textures.take(f);
182 }
183
184
185 QOpenGLContext *QSGContext::glContext() const
186 {
187     Q_D(const QSGContext);
188     return d->gl;
189 }
190
191 /*!
192     Initializes the scene graph context with the GL context \a context. This also
193     emits the ready() signal so that the QML graph can start building scene graph nodes.
194  */
195 void QSGContext::initialize(QOpenGLContext *context)
196 {
197     Q_D(QSGContext);
198
199     Q_ASSERT(!d->gl);
200     d->gl = context;
201
202     emit initialized();
203 }
204
205
206 /*!
207     Returns if the scene graph context is ready or not, meaning that it has a valid
208     GL context.
209  */
210 bool QSGContext::isReady() const
211 {
212     Q_D(const QSGContext);
213     return d->gl;
214 }
215
216
217 void QSGContext::renderNextFrame(QSGRenderer *renderer, QOpenGLFramebufferObject *fbo)
218 {
219     if (fbo) {
220         QSGBindableFbo bindable(fbo);
221         renderer->renderScene(bindable);
222     } else {
223         renderer->renderScene();
224     }
225
226 }
227
228 /*!
229     Factory function for scene graph backends of the Rectangle element.
230  */
231 QSGRectangleNode *QSGContext::createRectangleNode()
232 {
233     return new QSGDefaultRectangleNode(this);
234 }
235
236 /*!
237     Factory function for scene graph backends of the Image element.
238  */
239 QSGImageNode *QSGContext::createImageNode()
240 {
241     return new QSGDefaultImageNode;
242 }
243
244 /*!
245     Factory function for scene graph backends of the distance-field glyph cache.
246  */
247 QSGDistanceFieldGlyphCache *QSGContext::createDistanceFieldGlyphCache(const QRawFont &font)
248 {
249     Q_D(QSGContext);
250     return new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font);
251 }
252
253 /*!
254     Factory function for scene graph backends of the Text elements;
255  */
256 QSGGlyphNode *QSGContext::createGlyphNode()
257 {
258     Q_D(QSGContext);
259
260     // ### Do something with these before final release...
261     static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing"));
262     static bool doLowQualSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing-lowq"));
263     static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing"));
264
265     if (d->distanceFieldDisabled) {
266         return new QSGDefaultGlyphNode;
267     } else {
268         if (!d->distanceFieldCacheManager) {
269             d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager(this);
270             if (doSubpixel)
271                 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::HighQualitySubPixelAntialiasing);
272             else if (doLowQualSubpixel)
273                 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::LowQualitySubPixelAntialiasing);
274             else if (doGray)
275                d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
276         }
277
278         QSGGlyphNode *node = new QSGDistanceFieldGlyphNode(d->distanceFieldCacheManager);
279         return node;
280     }
281 }
282
283 /*!
284     Factory function for the scene graph renderers.
285
286     The renderers are used for the toplevel renderer and once for every
287     QQuickShaderEffectSource used in the QML scene.
288  */
289 QSGRenderer *QSGContext::createRenderer()
290 {
291     // ### Do something with this before release...
292     static bool doFrontToBack = qApp->arguments().contains(QLatin1String("--opaque-front-to-back"));
293     QSGDefaultRenderer *renderer = new QSGDefaultRenderer(this);
294     if (doFrontToBack) {
295         printf("QSGContext: Sorting opaque nodes front to back...\n");
296         renderer->setSortFrontToBackEnabled(true);
297     }
298     return renderer;
299 }
300
301
302
303
304 QSurfaceFormat QSGContext::defaultSurfaceFormat() const
305 {
306     QSurfaceFormat format;
307     format.setDepthBufferSize(24);
308     format.setStencilBufferSize(8);
309     format.setSamples(16);
310     return format;
311 }
312
313
314 /*!
315     Factory function for texture objects.
316
317     If \a image is a valid image, the QSGTexture::setImage function
318     will be called with \a image as argument.
319  */
320
321 QSGTexture *QSGContext::createTexture(const QImage &image) const
322 {
323     QSGPlainTexture *t = new QSGPlainTexture();
324     if (!image.isNull())
325         t->setImage(image);
326     return t;
327 }
328
329
330
331 /*!
332     Returns the minimum supported framebuffer object size.
333  */
334
335 QSize QSGContext::minimumFBOSize() const
336 {
337 #ifdef Q_OS_MAC
338     return QSize(33, 33);
339 #else
340     return QSize(1, 1);
341 #endif
342 }
343
344
345
346 /*!
347     Returns a material shader for the given material.
348  */
349
350 QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
351 {
352     Q_D(QSGContext);
353     QSGMaterialType *type = material->type();
354     QSGMaterialShader *shader = d->materials.value(type);
355     if (shader)
356         return shader;
357
358     shader = material->createShader();
359     shader->compile();
360     shader->initialize();
361     d->materials[type] = shader;
362
363     return shader;
364 }
365
366
367
368 /*!
369     Sets whether the scene graph should render with flashing update rectangles or not
370   */
371
372 void QSGContext::setFlashModeEnabled(bool enabled)
373 {
374     d_func()->flashMode = enabled;
375 }
376
377
378 /*!
379     Returns true if the scene graph should be rendered with flashing update rectangles
380  */
381 bool QSGContext::isFlashModeEnabled() const
382 {
383     return d_func()->flashMode;
384 }
385
386
387 /*!
388     Sets the toplevel opacity for rendering. This value will be multiplied into all
389     drawing calls where possible.
390
391     The default value is 1. Any other value will cause artifacts and is primarily
392     useful for debugging.
393  */
394 void QSGContext::setRenderAlpha(qreal renderAlpha)
395 {
396     d_func()->renderAlpha = renderAlpha;
397 }
398
399
400 /*!
401     Returns the toplevel opacity used for rendering.
402
403     The default value is 1.
404
405     \sa setRenderAlpha()
406  */
407 qreal QSGContext::renderAlpha() const
408 {
409     return d_func()->renderAlpha;
410 }
411
412
413 /*!
414     Sets whether or not the scene graph should use the distance field technique to render text
415   */
416 void QSGContext::setDistanceFieldEnabled(bool enabled)
417 {
418     d_func()->distanceFieldDisabled = !enabled;
419 }
420
421
422 /*!
423     Returns true if the scene graph uses the distance field technique to render text
424  */
425 bool QSGContext::isDistanceFieldEnabled() const
426 {
427     return !d_func()->distanceFieldDisabled;
428 }
429
430
431
432 /*!
433     Creates a new animation driver.
434  */
435
436 QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
437 {
438     return new QAnimationDriver(parent);
439 }
440
441
442 QT_END_NAMESPACE