Update licenseheader text in source files for qtdeclarative Qt module
[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 ** 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 <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(QGLFramebufferObject *fbo)
250 {
251     Q_D(QSGContext);
252
253     emit d->engine.beforeRendering();
254
255     cleanupTextures();
256
257     if (fbo) {
258         BindableFbo bindable(fbo);
259         d->renderer->renderScene(bindable);
260     } else {
261         d->renderer->renderScene();
262     }
263
264     emit d->engine.afterRendering();
265
266 }
267
268 /*!
269     Factory function for scene graph backends of the Rectangle element.
270  */
271 QSGRectangleNode *QSGContext::createRectangleNode()
272 {
273     return new QSGDefaultRectangleNode(this);
274 }
275
276 /*!
277     Factory function for scene graph backends of the Image element.
278  */
279 QSGImageNode *QSGContext::createImageNode()
280 {
281     return new QSGDefaultImageNode;
282 }
283
284 /*!
285     Factory function for scene graph backends of the Text elements;
286  */
287 QSGGlyphNode *QSGContext::createGlyphNode()
288 {
289     // ### Do something with these before final release...
290     static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing"));
291     static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing"));
292
293     if (QSGDistanceFieldGlyphCache::distanceFieldEnabled()) {
294         QSGGlyphNode *node = new QSGDistanceFieldGlyphNode;
295
296         if (doSubpixel)
297             node->setPreferredAntialiasingMode(QSGGlyphNode::SubPixelAntialiasing);
298         else if (doGray)
299             node->setPreferredAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
300         return node;
301     } else {
302         return new QSGDefaultGlyphNode;
303     }
304 }
305
306 /*!
307     Factory function for the scene graph renderers.
308
309     The renderers are used for the toplevel renderer and once for every
310     QSGShaderEffectSource used in the QML scene.
311  */
312 QSGRenderer *QSGContext::createRenderer()
313 {
314     // ### Do something with this before release...
315     static bool doFrontToBack = qApp->arguments().contains(QLatin1String("--opaque-front-to-back"));
316     QSGDefaultRenderer *renderer = new QSGDefaultRenderer(this);
317     if (doFrontToBack) {
318         printf("QSGContext: Sorting opaque nodes front to back...\n");
319         renderer->setSortFrontToBackEnabled(true);
320     }
321     return renderer;
322 }
323
324
325
326 /*!
327     Return true if the image provider supports direct decoding of images,
328     straight into textures without going through a QImage first.
329
330     If the implementation returns true from this function, the decodeImageToTexture() function
331     will be called to read data from a QIODevice, rather than QML decoding
332     the image using QImageReader and passing the result to setImage().
333
334     \warning This function will be called from outside the GUI and rendering threads
335     and must not make use of OpenGL.
336  */
337
338 bool QSGContext::canDecodeImageToTexture() const
339 {
340     return true;
341 }
342
343
344
345 /*!
346     Decode the data in \a dev directly to a texture provider of \a requestSize size.
347     The size of the decoded data should be written to \a impsize.
348
349     If the implementation fails to decode the image data, it should return 0. The
350     image data will then be decoded normally.
351
352     \warning This function will be called from outside the GUI and renderer threads
353     and must not make use of GL calls.
354  */
355
356 QSGTexture *QSGContext::decodeImageToTexture(QIODevice *dev,
357                                              QSize *size,
358                                              const QSize &requestSize)
359 {
360     Q_UNUSED(dev);
361     Q_UNUSED(size);
362     Q_UNUSED(requestSize);
363     return 0;
364 }
365
366
367
368 /*!
369     Factory function for texture objects.
370
371     If \a image is a valid image, the QSGTexture::setImage function
372     will be called with \a image as argument.
373  */
374
375 QSGTexture *QSGContext::createTexture(const QImage &image) const
376 {
377     QSGPlainTexture *t = new QSGPlainTexture();
378     if (!image.isNull())
379         t->setImage(image);
380     return t;
381 }
382
383
384
385 /*!
386     Returns a material shader for the given material.
387  */
388
389 QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
390 {
391     Q_D(QSGContext);
392     QSGMaterialType *type = material->type();
393     QSGMaterialShader *shader = d->materials.value(type);
394     if (shader)
395         return shader;
396
397     shader = material->createShader();
398     shader->compile();
399     shader->initialize();
400     d->materials[type] = shader;
401
402     return shader;
403 }
404
405
406
407 /*!
408     Sets whether the scene graph should render with flashing update rectangles or not
409   */
410
411 void QSGContext::setFlashModeEnabled(bool enabled)
412 {
413     d_func()->flashMode = enabled;
414 }
415
416
417 /*!
418     Returns true if the scene graph should be rendered with flashing update rectangles
419  */
420 bool QSGContext::isFlashModeEnabled() const
421 {
422     return d_func()->flashMode;
423 }
424
425
426 /*!
427     Sets the toplevel opacity for rendering. This value will be multiplied into all
428     drawing calls where possible.
429
430     The default value is 1. Any other value will cause artifacts and is primarily
431     useful for debugging.
432  */
433 void QSGContext::setRenderAlpha(qreal renderAlpha)
434 {
435     d_func()->renderAlpha = renderAlpha;
436 }
437
438
439 /*!
440     Returns the toplevel opacity used for rendering.
441
442     The default value is 1.
443
444     \sa setRenderAlpha()
445  */
446 qreal QSGContext::renderAlpha() const
447 {
448     return d_func()->renderAlpha;
449 }
450
451
452
453 /*!
454     Creates a new animation driver.
455  */
456
457 QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
458 {
459     return new QAnimationDriver(parent);
460 }
461
462
463 QT_END_NAMESPACE