1 /****************************************************************************
3 ** Copyright (C) 2012 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 <QtQuick/private/qsgcontext_p.h>
43 #include <QtQuick/private/qsgdefaultrenderer_p.h>
44 #include <QtQuick/private/qsgdistancefieldutil_p.h>
45 #include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h>
46 #include <QtQuick/private/qsgdefaultrectanglenode_p.h>
47 #include <QtQuick/private/qsgdefaultimagenode_p.h>
48 #include <QtQuick/private/qsgdefaultglyphnode_p.h>
49 #include <QtQuick/private/qsgdistancefieldglyphnode_p.h>
50 #include <QtQuick/private/qsgtexture_p.h>
51 #include <QtQuick/private/qdeclarativepixmapcache_p.h>
53 #include <QGuiApplication>
54 #include <QOpenGLContext>
56 #include <QDeclarativeImageProvider>
57 #include <private/qdeclarativeglobal_p.h>
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
91 , distanceFieldCacheManager(0)
92 , flashMode(qmlFlashMode())
93 , distanceFieldDisabled(qmlDisableDistanceField())
95 renderAlpha = qmlTranslucentMode() ? 0.5 : 1;
104 QHash<QSGMaterialType *, QSGMaterialShader *> materials;
105 QHash<QDeclarativeTextureFactory *, QSGTexture *> textures;
107 QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager;
111 bool distanceFieldDisabled;
118 \brief The QSGContext holds the scene graph entry points for one QML engine.
120 The context is not ready for use until it has a QOpenGLContext. Once that happens,
121 the scene graph population can start.
126 QSGContext::QSGContext(QObject *parent) :
127 QObject(*(new QSGContextPrivate), parent)
132 QSGContext::~QSGContext()
139 void QSGContext::invalidate()
142 qDeleteAll(d->textures.values());
144 qDeleteAll(d->materials.values());
145 d->materials.clear();
146 delete d->distanceFieldCacheManager;
147 d->distanceFieldCacheManager = 0;
155 QSGTexture *QSGContext::textureForFactory(QDeclarativeTextureFactory *factory)
161 QSGTexture *texture = d->textures.value(factory);
163 if (QDeclarativeDefaultTextureFactory *dtf = qobject_cast<QDeclarativeDefaultTextureFactory *>(factory))
164 texture = createTexture(dtf->image());
166 texture = factory->createTexture();
167 d->textures.insert(factory, texture);
168 connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *)));
174 void QSGContext::textureFactoryDestroyed(QObject *o)
177 QDeclarativeTextureFactory *f = static_cast<QDeclarativeTextureFactory *>(o);
179 // This function will only be called on the scene graph thread, so it is
180 // safe to directly delete the texture here.
181 delete d->textures.take(f);
185 QOpenGLContext *QSGContext::glContext() const
187 Q_D(const QSGContext);
192 Initializes the scene graph context with the GL context \a context. This also
193 emits the ready() signal so that the QML graph can start building scene graph nodes.
195 void QSGContext::initialize(QOpenGLContext *context)
207 Returns if the scene graph context is ready or not, meaning that it has a valid
210 bool QSGContext::isReady() const
212 Q_D(const QSGContext);
217 void QSGContext::renderNextFrame(QSGRenderer *renderer, QOpenGLFramebufferObject *fbo)
220 QSGBindableFbo bindable(fbo);
221 renderer->renderScene(bindable);
223 renderer->renderScene();
229 Factory function for scene graph backends of the Rectangle element.
231 QSGRectangleNode *QSGContext::createRectangleNode()
233 return new QSGDefaultRectangleNode(this);
237 Factory function for scene graph backends of the Image element.
239 QSGImageNode *QSGContext::createImageNode()
241 return new QSGDefaultImageNode;
245 Factory function for scene graph backends of the distance-field glyph cache.
247 QSGDistanceFieldGlyphCache *QSGContext::createDistanceFieldGlyphCache(const QRawFont &font)
250 return new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font);
254 Factory function for scene graph backends of the Text elements;
256 QSGGlyphNode *QSGContext::createGlyphNode()
260 // ### Do something with these before final release...
261 static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing"));
262 static bool doLowQualSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing-lowq"));
263 static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing"));
265 if (d->distanceFieldDisabled) {
266 return new QSGDefaultGlyphNode;
268 if (!d->distanceFieldCacheManager) {
269 d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager(this);
271 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::HighQualitySubPixelAntialiasing);
272 else if (doLowQualSubpixel)
273 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::LowQualitySubPixelAntialiasing);
275 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
278 QSGGlyphNode *node = new QSGDistanceFieldGlyphNode(d->distanceFieldCacheManager);
284 Factory function for the scene graph renderers.
286 The renderers are used for the toplevel renderer and once for every
287 QQuickShaderEffectSource used in the QML scene.
289 QSGRenderer *QSGContext::createRenderer()
291 // ### Do something with this before release...
292 static bool doFrontToBack = qApp->arguments().contains(QLatin1String("--opaque-front-to-back"));
293 QSGDefaultRenderer *renderer = new QSGDefaultRenderer(this);
295 printf("QSGContext: Sorting opaque nodes front to back...\n");
296 renderer->setSortFrontToBackEnabled(true);
304 QSurfaceFormat QSGContext::defaultSurfaceFormat() const
306 QSurfaceFormat format;
307 format.setDepthBufferSize(24);
308 format.setStencilBufferSize(8);
309 format.setSamples(16);
315 Factory function for texture objects.
317 If \a image is a valid image, the QSGTexture::setImage function
318 will be called with \a image as argument.
321 QSGTexture *QSGContext::createTexture(const QImage &image) const
323 QSGPlainTexture *t = new QSGPlainTexture();
332 Returns the minimum supported framebuffer object size.
335 QSize QSGContext::minimumFBOSize() const
338 return QSize(33, 33);
347 Returns a material shader for the given material.
350 QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
353 QSGMaterialType *type = material->type();
354 QSGMaterialShader *shader = d->materials.value(type);
358 shader = material->createShader();
360 shader->initialize();
361 d->materials[type] = shader;
369 Sets whether the scene graph should render with flashing update rectangles or not
372 void QSGContext::setFlashModeEnabled(bool enabled)
374 d_func()->flashMode = enabled;
379 Returns true if the scene graph should be rendered with flashing update rectangles
381 bool QSGContext::isFlashModeEnabled() const
383 return d_func()->flashMode;
388 Sets the toplevel opacity for rendering. This value will be multiplied into all
389 drawing calls where possible.
391 The default value is 1. Any other value will cause artifacts and is primarily
392 useful for debugging.
394 void QSGContext::setRenderAlpha(qreal renderAlpha)
396 d_func()->renderAlpha = renderAlpha;
401 Returns the toplevel opacity used for rendering.
403 The default value is 1.
407 qreal QSGContext::renderAlpha() const
409 return d_func()->renderAlpha;
414 Sets whether or not the scene graph should use the distance field technique to render text
416 void QSGContext::setDistanceFieldEnabled(bool enabled)
418 d_func()->distanceFieldDisabled = !enabled;
423 Returns true if the scene graph uses the distance field technique to render text
425 bool QSGContext::isDistanceFieldEnabled() const
427 return !d_func()->distanceFieldDisabled;
433 Creates a new animation driver.
436 QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
438 return new QAnimationDriver(parent);