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/qsgdistancefieldutil_p.h>
49 #include <private/qsgdefaultdistancefieldglyphcache_p.h>
50 #include <private/qsgdefaultrectanglenode_p.h>
51 #include <private/qsgdefaultimagenode_p.h>
52 #include <private/qsgdefaultglyphnode_p.h>
53 #include <private/qsgdistancefieldglyphnode_p.h>
55 #include <private/qsgtexture_p.h>
56 #include <QGuiApplication>
57 #include <QOpenGLContext>
59 #include <private/qobject_p.h>
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)
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 , distanceFieldCacheManager(0)
94 , flashMode(qmlFlashMode())
95 , distanceFieldDisabled(qmlDisableDistanceField())
97 renderAlpha = qmlTranslucentMode() ? 0.5 : 1;
104 QSGRootNode *rootNode;
105 QSGRenderer *renderer;
109 QHash<QSGMaterialType *, QSGMaterialShader *> materials;
111 QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager;
114 QList<QSGTexture *> texturesToClean;
118 bool distanceFieldDisabled;
125 \brief The QSGContext holds the scene graph entry points for one QML engine.
127 The context is not ready for use until it has a QOpenGLContext. Once that happens,
128 the scene graph population can start.
133 QSGContext::QSGContext(QObject *parent) :
134 QObject(*(new QSGContextPrivate), parent)
140 QSGContext::~QSGContext()
146 qDeleteAll(d->materials.values());
147 delete d->distanceFieldCacheManager;
151 Schedules the texture to be cleaned up on the rendering thread
154 The texture can be considered as deleted after this function has
157 void QSGContext::scheduleTextureForCleanup(QSGTexture *texture)
160 d->textureMutex.lock();
161 Q_ASSERT(!d->texturesToClean.contains(texture));
162 d->texturesToClean << texture;
163 d->textureMutex.unlock();
169 Deletes all textures that have been scheduled for cleanup
171 void QSGContext::cleanupTextures()
174 d->textureMutex.lock();
175 qDeleteAll(d->texturesToClean);
176 d->texturesToClean.clear();
177 d->textureMutex.unlock();
181 Returns the renderer. The renderer instance is created through the adaptation layer.
183 QSGRenderer *QSGContext::renderer() const
185 Q_D(const QSGContext);
191 Returns the root node. The root node instance is only created once the scene graph
192 context becomes ready.
194 QSGRootNode *QSGContext::rootNode() const
196 Q_D(const QSGContext);
201 QOpenGLContext *QSGContext::glContext() const
203 Q_D(const QSGContext);
208 Initializes the scene graph context with the GL context \a context. This also
209 emits the ready() signal so that the QML graph can start building scene graph nodes.
211 void QSGContext::initialize(QOpenGLContext *context)
219 d->renderer = createRenderer();
220 d->renderer->setClearColor(Qt::white);
222 d->rootNode = new QSGRootNode();
223 d->renderer->setRootNode(d->rootNode);
230 Returns if the scene graph context is ready or not, meaning that it has a valid
233 bool QSGContext::isReady() const
235 Q_D(const QSGContext);
240 void QSGContext::renderNextFrame(QOpenGLFramebufferObject *fbo)
247 QSGBindableFbo bindable(fbo);
248 d->renderer->renderScene(bindable);
250 d->renderer->renderScene();
256 Factory function for scene graph backends of the Rectangle element.
258 QSGRectangleNode *QSGContext::createRectangleNode()
260 return new QSGDefaultRectangleNode(this);
264 Factory function for scene graph backends of the Image element.
266 QSGImageNode *QSGContext::createImageNode()
268 return new QSGDefaultImageNode;
272 Factory function for scene graph backends of the distance-field glyph cache.
274 QSGDistanceFieldGlyphCache *QSGContext::createDistanceFieldGlyphCache(const QRawFont &font)
277 return new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font);
281 Factory function for scene graph backends of the Text elements;
283 QSGGlyphNode *QSGContext::createGlyphNode()
287 // ### Do something with these before final release...
288 static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing"));
289 static bool doLowQualSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing-lowq"));
290 static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing"));
292 if (d->distanceFieldDisabled) {
293 return new QSGDefaultGlyphNode;
295 if (!d->distanceFieldCacheManager) {
296 d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager(this);
298 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::HighQualitySubPixelAntialiasing);
299 else if (doLowQualSubpixel)
300 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::LowQualitySubPixelAntialiasing);
302 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
305 QSGGlyphNode *node = new QSGDistanceFieldGlyphNode(d->distanceFieldCacheManager);
311 Factory function for the scene graph renderers.
313 The renderers are used for the toplevel renderer and once for every
314 QQuickShaderEffectSource used in the QML scene.
316 QSGRenderer *QSGContext::createRenderer()
318 // ### Do something with this before release...
319 static bool doFrontToBack = qApp->arguments().contains(QLatin1String("--opaque-front-to-back"));
320 QSGDefaultRenderer *renderer = new QSGDefaultRenderer(this);
322 printf("QSGContext: Sorting opaque nodes front to back...\n");
323 renderer->setSortFrontToBackEnabled(true);
331 Return true if the image provider supports direct decoding of images,
332 straight into textures without going through a QImage first.
334 If the implementation returns true from this function, the decodeImageToTexture() function
335 will be called to read data from a QIODevice, rather than QML decoding
336 the image using QImageReader and passing the result to setImage().
338 \warning This function will be called from outside the GUI and rendering threads
339 and must not make use of OpenGL.
342 bool QSGContext::canDecodeImageToTexture() const
350 Decode the data in \a dev directly to a texture provider of \a requestSize size.
351 The size of the decoded data should be written to \a impsize.
353 If the implementation fails to decode the image data, it should return 0. The
354 image data will then be decoded normally.
356 \warning This function will be called from outside the GUI and renderer threads
357 and must not make use of GL calls.
360 QSGTexture *QSGContext::decodeImageToTexture(QIODevice *dev,
362 const QSize &requestSize)
366 Q_UNUSED(requestSize);
372 QSurfaceFormat QSGContext::defaultSurfaceFormat() const
374 QSurfaceFormat format;
375 format.setDepthBufferSize(24);
376 format.setStencilBufferSize(8);
377 format.setSamples(16);
383 Factory function for texture objects.
385 If \a image is a valid image, the QSGTexture::setImage function
386 will be called with \a image as argument.
389 QSGTexture *QSGContext::createTexture(const QImage &image) const
391 QSGPlainTexture *t = new QSGPlainTexture();
400 Returns the minimum supported framebuffer object size.
403 QSize QSGContext::minimumFBOSize() const
406 return QSize(33, 33);
415 Returns a material shader for the given material.
418 QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
421 QSGMaterialType *type = material->type();
422 QSGMaterialShader *shader = d->materials.value(type);
426 shader = material->createShader();
428 shader->initialize();
429 d->materials[type] = shader;
437 Sets whether the scene graph should render with flashing update rectangles or not
440 void QSGContext::setFlashModeEnabled(bool enabled)
442 d_func()->flashMode = enabled;
447 Returns true if the scene graph should be rendered with flashing update rectangles
449 bool QSGContext::isFlashModeEnabled() const
451 return d_func()->flashMode;
456 Sets the toplevel opacity for rendering. This value will be multiplied into all
457 drawing calls where possible.
459 The default value is 1. Any other value will cause artifacts and is primarily
460 useful for debugging.
462 void QSGContext::setRenderAlpha(qreal renderAlpha)
464 d_func()->renderAlpha = renderAlpha;
469 Returns the toplevel opacity used for rendering.
471 The default value is 1.
475 qreal QSGContext::renderAlpha() const
477 return d_func()->renderAlpha;
482 Sets whether or not the scene graph should use the distance field technique to render text
484 void QSGContext::setDistanceFieldEnabled(bool enabled)
486 d_func()->distanceFieldDisabled = !enabled;
491 Returns true if the scene graph uses the distance field technique to render text
493 bool QSGContext::isDistanceFieldEnabled() const
495 return !d_func()->distanceFieldDisabled;
501 Creates a new animation driver.
504 QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
506 return new QAnimationDriver(parent);