1 /****************************************************************************
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #include <private/qsgcontext_p.h>
43 #include <private/qsgrenderer_p.h>
46 #include <private/qsgdefaultrenderer_p.h>
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>
54 #include <private/qsgtexture_p.h>
55 #include <qsgengine.h>
57 #include <QApplication>
60 #include <private/qobject_p.h>
63 DEFINE_BOOL_CONFIG_OPTION(qmlFlashMode, QML_FLASH_MODE)
64 DEFINE_BOOL_CONFIG_OPTION(qmlTranslucentMode, QML_TRANSLUCENT_MODE)
67 Comments about this class from Gunnar:
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.
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.
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..
86 class QSGContextPrivate : public QObjectPrivate
93 , flashMode(qmlFlashMode())
95 renderAlpha = qmlTranslucentMode() ? 0.5 : 1;
102 QSGRootNode *rootNode;
103 QSGRenderer *renderer;
109 QHash<QSGMaterialType *, QSGMaterialShader *> materials;
112 QList<QSGTexture *> texturesToClean;
122 \brief The QSGContext holds the scene graph entry points for one QML engine.
124 The context is not ready for use until it has a QGLContext. Once that happens,
125 the scene graph population can start.
130 QSGContext::QSGContext(QObject *parent) :
131 QObject(*(new QSGContextPrivate), parent)
134 d->engine.setContext(this);
138 QSGContext::~QSGContext()
144 qDeleteAll(d->materials.values());
148 Returns the scene graph engine for this context.
150 The main purpose of the QSGEngine is to serve as a public API
154 QSGEngine *QSGContext::engine() const
156 return const_cast<QSGEngine *>(&d_func()->engine);
160 Schedules the texture to be cleaned up on the rendering thread
163 The texture can be considered as deleted after this function has
166 void QSGContext::scheduleTextureForCleanup(QSGTexture *texture)
169 d->textureMutex.lock();
170 Q_ASSERT(!d->texturesToClean.contains(texture));
171 d->texturesToClean << texture;
172 d->textureMutex.unlock();
178 Deletes all textures that have been scheduled for cleanup
180 void QSGContext::cleanupTextures()
183 d->textureMutex.lock();
184 qDeleteAll(d->texturesToClean);
185 d->texturesToClean.clear();
186 d->textureMutex.unlock();
190 Returns the renderer. The renderer instance is created through the adaptation layer.
192 QSGRenderer *QSGContext::renderer() const
194 Q_D(const QSGContext);
200 Returns the root node. The root node instance is only created once the scene graph
201 context becomes ready.
203 QSGRootNode *QSGContext::rootNode() const
205 Q_D(const QSGContext);
210 QGLContext *QSGContext::glContext() const
212 Q_D(const QSGContext);
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.
220 void QSGContext::initialize(QGLContext *context)
228 d->renderer = createRenderer();
229 d->renderer->setClearColor(Qt::white);
231 d->rootNode = new QSGRootNode();
232 d->renderer->setRootNode(d->rootNode);
239 Returns if the scene graph context is ready or not, meaning that it has a valid
242 bool QSGContext::isReady() const
244 Q_D(const QSGContext);
249 void QSGContext::renderNextFrame(QGLFramebufferObject *fbo)
253 emit d->engine.beforeRendering();
258 BindableFbo bindable(fbo);
259 d->renderer->renderScene(bindable);
261 d->renderer->renderScene();
264 emit d->engine.afterRendering();
269 Factory function for scene graph backends of the Rectangle element.
271 QSGRectangleNode *QSGContext::createRectangleNode()
273 return new QSGDefaultRectangleNode(this);
277 Factory function for scene graph backends of the Image element.
279 QSGImageNode *QSGContext::createImageNode()
281 return new QSGDefaultImageNode;
285 Factory function for scene graph backends of the Text elements;
287 QSGGlyphNode *QSGContext::createGlyphNode()
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"));
293 if (QSGDistanceFieldGlyphCache::distanceFieldEnabled()) {
294 QSGGlyphNode *node = new QSGDistanceFieldGlyphNode;
297 node->setPreferredAntialiasingMode(QSGGlyphNode::SubPixelAntialiasing);
299 node->setPreferredAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
302 return new QSGDefaultGlyphNode;
307 Factory function for the scene graph renderers.
309 The renderers are used for the toplevel renderer and once for every
310 QSGShaderEffectSource used in the QML scene.
312 QSGRenderer *QSGContext::createRenderer()
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);
318 printf("QSGContext: Sorting opaque nodes front to back...\n");
319 renderer->setSortFrontToBackEnabled(true);
327 Return true if the image provider supports direct decoding of images,
328 straight into textures without going through a QImage first.
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().
334 \warning This function will be called from outside the GUI and rendering threads
335 and must not make use of OpenGL.
338 bool QSGContext::canDecodeImageToTexture() const
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.
349 If the implementation fails to decode the image data, it should return 0. The
350 image data will then be decoded normally.
352 \warning This function will be called from outside the GUI and renderer threads
353 and must not make use of GL calls.
356 QSGTexture *QSGContext::decodeImageToTexture(QIODevice *dev,
358 const QSize &requestSize)
362 Q_UNUSED(requestSize);
369 Factory function for texture objects.
371 If \a image is a valid image, the QSGTexture::setImage function
372 will be called with \a image as argument.
375 QSGTexture *QSGContext::createTexture(const QImage &image) const
377 QSGPlainTexture *t = new QSGPlainTexture();
386 Returns a material shader for the given material.
389 QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
392 QSGMaterialType *type = material->type();
393 QSGMaterialShader *shader = d->materials.value(type);
397 shader = material->createShader();
399 shader->initialize();
400 d->materials[type] = shader;
408 Sets whether the scene graph should render with flashing update rectangles or not
411 void QSGContext::setFlashModeEnabled(bool enabled)
413 d_func()->flashMode = enabled;
418 Returns true if the scene graph should be rendered with flashing update rectangles
420 bool QSGContext::isFlashModeEnabled() const
422 return d_func()->flashMode;
427 Sets the toplevel opacity for rendering. This value will be multiplied into all
428 drawing calls where possible.
430 The default value is 1. Any other value will cause artifacts and is primarily
431 useful for debugging.
433 void QSGContext::setRenderAlpha(qreal renderAlpha)
435 d_func()->renderAlpha = renderAlpha;
440 Returns the toplevel opacity used for rendering.
442 The default value is 1.
446 qreal QSGContext::renderAlpha() const
448 return d_func()->renderAlpha;
454 Creates a new animation driver.
457 QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
459 return new QAnimationDriver(parent);