Doc: Cleaned up the scene graph documentation a little.
[profile/ivi/qtdeclarative.git] / src / declarative / scenegraph / qsgcontext.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 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 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <private/qsgcontext_p.h>
43 #include <private/qsgrenderer_p.h>
44 #include "qsgnode.h"
45
46 #include <private/qsgdefaultrenderer_p.h>
47
48 #include <private/qsgdefaultrectanglenode_p.h>
49 #include <private/qsgdefaultimagenode_p.h>
50 #include <private/qsgdefaultglyphnode_p.h>
51 #include <private/qsgdistancefieldglyphnode_p.h>
52 #include <private/qsgdistancefieldglyphcache_p.h>
53
54 #include <private/qsgtexture_p.h>
55 #include <qsgengine.h>
56
57 #include <QApplication>
58 #include <QGLContext>
59
60 #include <private/qobject_p.h>
61 #include <qmutex.h>
62
63 DEFINE_BOOL_CONFIG_OPTION(qmlFlashMode, QML_FLASH_MODE)
64 DEFINE_BOOL_CONFIG_OPTION(qmlTranslucentMode, QML_TRANSLUCENT_MODE)
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         : rootNode(0)
91         , renderer(0)
92         , gl(0)
93         , flashMode(qmlFlashMode())
94     {
95         renderAlpha = qmlTranslucentMode() ? 0.5 : 1;
96     }
97
98     ~QSGContextPrivate() 
99     {
100     }
101
102     QSGRootNode *rootNode;
103     QSGRenderer *renderer;
104
105     QGLContext *gl;
106
107     QSGEngine engine;
108
109     QHash<QSGMaterialType *, QSGMaterialShader *> materials;
110
111     QMutex textureMutex;
112     QList<QSGTexture *> texturesToClean;
113
114     bool flashMode;
115     float renderAlpha;
116 };
117
118
119 /*!
120     \class QSGContext
121
122     \brief The QSGContext holds the scene graph entry points for one QML engine.
123
124     The context is not ready for use until it has a QGLContext. Once that happens,
125     the scene graph population can start.
126
127     \internal
128  */
129
130 QSGContext::QSGContext(QObject *parent) :
131     QObject(*(new QSGContextPrivate), parent)
132 {
133     Q_D(QSGContext);
134     d->engine.setContext(this);
135 }
136
137
138 QSGContext::~QSGContext()
139 {
140     Q_D(QSGContext);
141     delete d->renderer;
142     delete d->rootNode;
143     cleanupTextures();
144     qDeleteAll(d->materials.values());
145 }
146
147 /*!
148     Returns the scene graph engine for this context.
149
150     The main purpose of the QSGEngine is to serve as a public API
151     to the QSGContext.
152
153  */
154 QSGEngine *QSGContext::engine() const
155 {
156     return const_cast<QSGEngine *>(&d_func()->engine);
157 }
158
159 /*!
160     Schedules the texture to be cleaned up on the rendering thread
161     at a later time.
162
163     The texture can be considered as deleted after this function has
164     been called.
165   */
166 void QSGContext::scheduleTextureForCleanup(QSGTexture *texture)
167 {
168     Q_D(QSGContext);
169     d->textureMutex.lock();
170     Q_ASSERT(!d->texturesToClean.contains(texture));
171     d->texturesToClean << texture;
172     d->textureMutex.unlock();
173 }
174
175
176
177 /*!
178     Deletes all textures that have been scheduled for cleanup
179  */
180 void QSGContext::cleanupTextures()
181 {
182     Q_D(QSGContext);
183     d->textureMutex.lock();
184     qDeleteAll(d->texturesToClean);
185     d->texturesToClean.clear();
186     d->textureMutex.unlock();
187 }
188
189 /*!
190     Returns the renderer. The renderer instance is created through the adaptation layer.
191  */
192 QSGRenderer *QSGContext::renderer() const
193 {
194     Q_D(const QSGContext);
195     return d->renderer;
196 }
197
198
199 /*!
200     Returns the root node. The root node instance is only created once the scene graph
201     context becomes ready.
202  */
203 QSGRootNode *QSGContext::rootNode() const
204 {
205     Q_D(const QSGContext);
206     return d->rootNode;
207 }
208
209
210 QGLContext *QSGContext::glContext() const
211 {
212     Q_D(const QSGContext);
213     return d->gl;
214 }
215
216 /*!
217     Initializes the scene graph context with the GL context \a context. This also
218     emits the ready() signal so that the QML graph can start building scene graph nodes.
219  */
220 void QSGContext::initialize(QGLContext *context)
221 {
222     Q_D(QSGContext);
223
224     Q_ASSERT(!d->gl);
225
226     d->gl = context;
227
228     d->renderer = createRenderer();
229     d->renderer->setClearColor(Qt::white);
230
231     d->rootNode = new QSGRootNode();
232     d->renderer->setRootNode(d->rootNode);
233
234     emit ready();
235 }
236
237
238 /*!
239     Returns if the scene graph context is ready or not, meaning that it has a valid
240     GL context.
241  */
242 bool QSGContext::isReady() const
243 {
244     Q_D(const QSGContext);
245     return d->gl;
246 }
247
248
249 void QSGContext::renderNextFrame()
250 {
251     Q_D(QSGContext);
252
253     emit d->engine.beforeRendering();
254
255     cleanupTextures();
256     d->renderer->renderScene();
257
258     emit d->engine.afterRendering();
259
260 }
261
262 /*!
263     Factory function for scene graph backends of the Rectangle element.
264  */
265 QSGRectangleNode *QSGContext::createRectangleNode()
266 {
267     return new QSGDefaultRectangleNode(this);
268 }
269
270 /*!
271     Factory function for scene graph backends of the Image element.
272  */
273 QSGImageNode *QSGContext::createImageNode()
274 {
275     return new QSGDefaultImageNode;
276 }
277
278 /*!
279     Factory function for scene graph backends of the Text elements;
280  */
281 QSGGlyphNode *QSGContext::createGlyphNode()
282 {
283     // ### Do something with these before final release...
284     static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing"));
285     static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing"));
286
287     if (QSGDistanceFieldGlyphCache::distanceFieldEnabled()) {
288         QSGGlyphNode *node = new QSGDistanceFieldGlyphNode;
289
290         if (doSubpixel)
291             node->setPreferredAntialiasingMode(QSGGlyphNode::SubPixelAntialiasing);
292         else if (doGray)
293             node->setPreferredAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
294         return node;
295     } else {
296         return new QSGDefaultGlyphNode;
297     }
298 }
299
300 /*!
301     Factory function for the scene graph renderers.
302
303     The renderers are used for the toplevel renderer and once for every
304     QSGShaderEffectSource used in the QML scene.
305  */
306 QSGRenderer *QSGContext::createRenderer()
307 {
308     // ### Do something with this before release...
309     static bool doFrontToBack = qApp->arguments().contains(QLatin1String("--opaque-front-to-back"));
310     QMLRenderer *renderer = new QMLRenderer(this);
311     if (doFrontToBack) {
312         printf("QSGContext: Sorting opaque nodes front to back...\n");
313         renderer->setSortFrontToBackEnabled(true);
314     }
315     return renderer;
316 }
317
318
319
320 /*!
321     Return true if the image provider supports direct decoding of images,
322     straight into textures without going through a QImage first.
323
324     If the implementation returns true from this function, the decodeImageToTexture() function
325     will be called to read data from a QIODevice, rather than QML decoding
326     the image using QImageReader and passing the result to setImage().
327
328     \warning This function will be called from outside the GUI and rendering threads
329     and must not make use of OpenGL.
330  */
331
332 bool QSGContext::canDecodeImageToTexture() const
333 {
334     return true;
335 }
336
337
338
339 /*!
340     Decode the data in \a dev directly to a texture provider of \a requestSize size.
341     The size of the decoded data should be written to \a impsize.
342
343     If the implementation fails to decode the image data, it should return 0. The
344     image data will then be decoded normally.
345
346     \warning This function will be called from outside the GUI and renderer threads
347     and must not make use of GL calls.
348  */
349
350 QSGTexture *QSGContext::decodeImageToTexture(QIODevice *dev,
351                                              QSize *size,
352                                              const QSize &requestSize)
353 {
354     Q_UNUSED(dev);
355     Q_UNUSED(size);
356     Q_UNUSED(requestSize);
357     return 0;
358 }
359
360
361
362 /*!
363     Factory function for texture objects.
364
365     If \a image is a valid image, the QSGTexture::setImage function
366     will be called with \a image as argument.
367  */
368
369 QSGTexture *QSGContext::createTexture(const QImage &image) const
370 {
371     QSGPlainTexture *t = new QSGPlainTexture();
372     if (!image.isNull())
373         t->setImage(image);
374     return t;
375 }
376
377
378
379 /*!
380     Returns a material shader for the given material.
381  */
382
383 QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
384 {
385     Q_D(QSGContext);
386     QSGMaterialType *type = material->type();
387     QSGMaterialShader *shader = d->materials.value(type);
388     if (shader)
389         return shader;
390
391     shader = material->createShader();
392     shader->compile();
393     shader->initialize();
394     d->materials[type] = shader;
395
396     return shader;
397 }
398
399
400
401 /*!
402     Sets whether the scene graph should render with flashing update rectangles or not
403   */
404
405 void QSGContext::setFlashModeEnabled(bool enabled)
406 {
407     d_func()->flashMode = enabled;
408 }
409
410
411 /*!
412     Returns true if the scene graph should be rendered with flashing update rectangles
413  */
414 bool QSGContext::isFlashModeEnabled() const
415 {
416     return d_func()->flashMode;
417 }
418
419
420 /*!
421     Sets the toplevel opacity for rendering. This value will be multiplied into all
422     drawing calls where possible.
423
424     The default value is 1. Any other value will cause artifacts and is primarily
425     useful for debugging.
426  */
427 void QSGContext::setRenderAlpha(qreal renderAlpha)
428 {
429     d_func()->renderAlpha = renderAlpha;
430 }
431
432
433 /*!
434     Returns the toplevel opacity used for rendering.
435
436     The default value is 1.
437
438     \sa setRenderAlpha()
439  */
440 qreal QSGContext::renderAlpha() const
441 {
442     return d_func()->renderAlpha;
443 }
444
445
446
447 /*!
448     Creates a new animation driver.
449  */
450
451 QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
452 {
453     return new QAnimationDriver(parent);
454 }
455
456
457 QT_END_NAMESPACE