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 <QGuiApplication>
58 #include <QOpenGLContext>
60 #include <private/qobject_p.h>
63 DEFINE_BOOL_CONFIG_OPTION(qmlFlashMode, QML_FLASH_MODE)
64 DEFINE_BOOL_CONFIG_OPTION(qmlTranslucentMode, QML_TRANSLUCENT_MODE)
65 DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
68 Comments about this class from Gunnar:
70 The QSGContext class is right now two things.. The first is the
71 adaptation layer and central storage ground for all the things
72 in the scene graph, like textures and materials. This part really
73 belongs inside the scene graph coreapi.
75 The other part is the QML adaptation classes, like how to implement
76 rectangle nodes. This is not part of the scene graph core API, but
77 more part of the QML adaptation of scene graph.
79 If we ever move the scene graph core API into its own thing, this class
80 needs to be split in two. Right now its one because we're lazy when it comes
81 to defining plugin interfaces..
87 class QSGContextPrivate : public QObjectPrivate
94 , distanceFieldCacheManager(0)
95 , flashMode(qmlFlashMode())
96 , distanceFieldDisabled(qmlDisableDistanceField())
98 renderAlpha = qmlTranslucentMode() ? 0.5 : 1;
105 QSGRootNode *rootNode;
106 QSGRenderer *renderer;
112 QHash<QSGMaterialType *, QSGMaterialShader *> materials;
114 QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager;
117 QList<QSGTexture *> texturesToClean;
121 bool distanceFieldDisabled;
128 \brief The QSGContext holds the scene graph entry points for one QML engine.
130 The context is not ready for use until it has a QOpenGLContext. Once that happens,
131 the scene graph population can start.
136 QSGContext::QSGContext(QObject *parent) :
137 QObject(*(new QSGContextPrivate), parent)
140 d->engine.setContext(this);
144 QSGContext::~QSGContext()
150 qDeleteAll(d->materials.values());
151 delete d->distanceFieldCacheManager;
155 Returns the scene graph engine for this context.
157 The main purpose of the QSGEngine is to serve as a public API
161 QSGEngine *QSGContext::engine() const
163 return const_cast<QSGEngine *>(&d_func()->engine);
167 Schedules the texture to be cleaned up on the rendering thread
170 The texture can be considered as deleted after this function has
173 void QSGContext::scheduleTextureForCleanup(QSGTexture *texture)
176 d->textureMutex.lock();
177 Q_ASSERT(!d->texturesToClean.contains(texture));
178 d->texturesToClean << texture;
179 d->textureMutex.unlock();
185 Deletes all textures that have been scheduled for cleanup
187 void QSGContext::cleanupTextures()
190 d->textureMutex.lock();
191 qDeleteAll(d->texturesToClean);
192 d->texturesToClean.clear();
193 d->textureMutex.unlock();
197 Returns the renderer. The renderer instance is created through the adaptation layer.
199 QSGRenderer *QSGContext::renderer() const
201 Q_D(const QSGContext);
207 Returns the root node. The root node instance is only created once the scene graph
208 context becomes ready.
210 QSGRootNode *QSGContext::rootNode() const
212 Q_D(const QSGContext);
217 QOpenGLContext *QSGContext::glContext() const
219 Q_D(const QSGContext);
224 Initializes the scene graph context with the GL context \a context. This also
225 emits the ready() signal so that the QML graph can start building scene graph nodes.
227 void QSGContext::initialize(QOpenGLContext *context)
235 d->renderer = createRenderer();
236 d->renderer->setClearColor(Qt::white);
238 d->rootNode = new QSGRootNode();
239 d->renderer->setRootNode(d->rootNode);
246 Returns if the scene graph context is ready or not, meaning that it has a valid
249 bool QSGContext::isReady() const
251 Q_D(const QSGContext);
256 void QSGContext::renderNextFrame(QOpenGLFramebufferObject *fbo)
260 emit d->engine.beforeRendering();
265 QSGBindableFbo bindable(fbo);
266 d->renderer->renderScene(bindable);
268 d->renderer->renderScene();
271 emit d->engine.afterRendering();
276 Factory function for scene graph backends of the Rectangle element.
278 QSGRectangleNode *QSGContext::createRectangleNode()
280 return new QSGDefaultRectangleNode(this);
284 Factory function for scene graph backends of the Image element.
286 QSGImageNode *QSGContext::createImageNode()
288 return new QSGDefaultImageNode;
292 Factory function for scene graph backends of the Text elements;
294 QSGGlyphNode *QSGContext::createGlyphNode()
298 // ### Do something with these before final release...
299 static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing"));
300 static bool doLowQualSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing-lowq"));
301 static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing"));
303 if (d->distanceFieldDisabled) {
304 return new QSGDefaultGlyphNode;
306 if (!d->distanceFieldCacheManager) {
307 d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager(d->gl);
309 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::HighQualitySubPixelAntialiasing);
310 else if (doLowQualSubpixel)
311 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::LowQualitySubPixelAntialiasing);
313 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
316 QSGGlyphNode *node = new QSGDistanceFieldGlyphNode(d->distanceFieldCacheManager);
322 Factory function for the scene graph renderers.
324 The renderers are used for the toplevel renderer and once for every
325 QSGShaderEffectSource used in the QML scene.
327 QSGRenderer *QSGContext::createRenderer()
329 // ### Do something with this before release...
330 static bool doFrontToBack = qApp->arguments().contains(QLatin1String("--opaque-front-to-back"));
331 QSGDefaultRenderer *renderer = new QSGDefaultRenderer(this);
333 printf("QSGContext: Sorting opaque nodes front to back...\n");
334 renderer->setSortFrontToBackEnabled(true);
342 Return true if the image provider supports direct decoding of images,
343 straight into textures without going through a QImage first.
345 If the implementation returns true from this function, the decodeImageToTexture() function
346 will be called to read data from a QIODevice, rather than QML decoding
347 the image using QImageReader and passing the result to setImage().
349 \warning This function will be called from outside the GUI and rendering threads
350 and must not make use of OpenGL.
353 bool QSGContext::canDecodeImageToTexture() const
361 Decode the data in \a dev directly to a texture provider of \a requestSize size.
362 The size of the decoded data should be written to \a impsize.
364 If the implementation fails to decode the image data, it should return 0. The
365 image data will then be decoded normally.
367 \warning This function will be called from outside the GUI and renderer threads
368 and must not make use of GL calls.
371 QSGTexture *QSGContext::decodeImageToTexture(QIODevice *dev,
373 const QSize &requestSize)
377 Q_UNUSED(requestSize);
383 QSurfaceFormat QSGContext::defaultSurfaceFormat() const
385 QSurfaceFormat format;
386 format.setDepthBufferSize(24);
387 format.setStencilBufferSize(8);
388 format.setSamples(16);
394 Factory function for texture objects.
396 If \a image is a valid image, the QSGTexture::setImage function
397 will be called with \a image as argument.
400 QSGTexture *QSGContext::createTexture(const QImage &image) const
402 QSGPlainTexture *t = new QSGPlainTexture();
411 Returns the minimum supported framebuffer object size.
414 QSize QSGContext::minimumFBOSize() const
417 return QSize(33, 33);
426 Returns a material shader for the given material.
429 QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
432 QSGMaterialType *type = material->type();
433 QSGMaterialShader *shader = d->materials.value(type);
437 shader = material->createShader();
439 shader->initialize();
440 d->materials[type] = shader;
448 Sets whether the scene graph should render with flashing update rectangles or not
451 void QSGContext::setFlashModeEnabled(bool enabled)
453 d_func()->flashMode = enabled;
458 Returns true if the scene graph should be rendered with flashing update rectangles
460 bool QSGContext::isFlashModeEnabled() const
462 return d_func()->flashMode;
467 Sets the toplevel opacity for rendering. This value will be multiplied into all
468 drawing calls where possible.
470 The default value is 1. Any other value will cause artifacts and is primarily
471 useful for debugging.
473 void QSGContext::setRenderAlpha(qreal renderAlpha)
475 d_func()->renderAlpha = renderAlpha;
480 Returns the toplevel opacity used for rendering.
482 The default value is 1.
486 qreal QSGContext::renderAlpha() const
488 return d_func()->renderAlpha;
493 Sets whether or not the scene graph should use the distance field technique to render text
495 void QSGContext::setDistanceFieldEnabled(bool enabled)
497 d_func()->distanceFieldDisabled = !enabled;
502 Returns true if the scene graph uses the distance field technique to render text
504 bool QSGContext::isDistanceFieldEnabled() const
506 return !d_func()->distanceFieldDisabled;
512 Creates a new animation driver.
515 QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
517 return new QAnimationDriver(parent);