1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** 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/qsgshareddistancefieldglyphcache_p.h>
52 #include <QtQuick/private/qsgtexture_p.h>
53 #include <QtQuick/private/qdeclarativepixmapcache_p.h>
55 #include <QGuiApplication>
56 #include <QOpenGLContext>
58 #include <QDeclarativeImageProvider>
59 #include <private/qdeclarativeglobal_p.h>
61 #include <QtQuick/private/qsgtexture_p.h>
62 #include <QtGui/private/qguiapplication_p.h>
64 #include <QtGui/qplatformsharedgraphicscache_qpa.h>
66 #include <private/qobject_p.h>
69 DEFINE_BOOL_CONFIG_OPTION(qmlFlashMode, QML_FLASH_MODE)
70 DEFINE_BOOL_CONFIG_OPTION(qmlTranslucentMode, QML_TRANSLUCENT_MODE)
71 DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
74 Comments about this class from Gunnar:
76 The QSGContext class is right now two things.. The first is the
77 adaptation layer and central storage ground for all the things
78 in the scene graph, like textures and materials. This part really
79 belongs inside the scene graph coreapi.
81 The other part is the QML adaptation classes, like how to implement
82 rectangle nodes. This is not part of the scene graph core API, but
83 more part of the QML adaptation of scene graph.
85 If we ever move the scene graph core API into its own thing, this class
86 needs to be split in two. Right now its one because we're lazy when it comes
87 to defining plugin interfaces..
93 class QSGContextPrivate : public QObjectPrivate
98 , distanceFieldCacheManager(0)
99 , flashMode(qmlFlashMode())
100 , distanceFieldDisabled(qmlDisableDistanceField())
102 renderAlpha = qmlTranslucentMode() ? 0.5 : 1;
111 QHash<QSGMaterialType *, QSGMaterialShader *> materials;
112 QHash<QDeclarativeTextureFactory *, QSGTexture *> textures;
114 QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager;
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)
139 QSGContext::~QSGContext()
146 void QSGContext::invalidate()
149 qDeleteAll(d->textures.values());
151 qDeleteAll(d->materials.values());
152 d->materials.clear();
153 delete d->distanceFieldCacheManager;
154 d->distanceFieldCacheManager = 0;
162 QSGTexture *QSGContext::textureForFactory(QDeclarativeTextureFactory *factory)
168 QSGTexture *texture = d->textures.value(factory);
170 if (QDeclarativeDefaultTextureFactory *dtf = qobject_cast<QDeclarativeDefaultTextureFactory *>(factory))
171 texture = createTexture(dtf->image());
173 texture = factory->createTexture();
174 d->textures.insert(factory, texture);
175 connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *)));
181 void QSGContext::textureFactoryDestroyed(QObject *o)
184 QDeclarativeTextureFactory *f = static_cast<QDeclarativeTextureFactory *>(o);
186 // This function will only be called on the scene graph thread, so it is
187 // safe to directly delete the texture here.
188 delete d->textures.take(f);
192 QOpenGLContext *QSGContext::glContext() const
194 Q_D(const QSGContext);
199 Initializes the scene graph context with the GL context \a context. This also
200 emits the ready() signal so that the QML graph can start building scene graph nodes.
202 void QSGContext::initialize(QOpenGLContext *context)
214 Returns if the scene graph context is ready or not, meaning that it has a valid
217 bool QSGContext::isReady() const
219 Q_D(const QSGContext);
224 void QSGContext::renderNextFrame(QSGRenderer *renderer, GLuint fboId)
227 QSGBindableFboId bindable(fboId);
228 renderer->renderScene(bindable);
230 renderer->renderScene();
236 Factory function for scene graph backends of the Rectangle element.
238 QSGRectangleNode *QSGContext::createRectangleNode()
240 return new QSGDefaultRectangleNode(this);
244 Factory function for scene graph backends of the Image element.
246 QSGImageNode *QSGContext::createImageNode()
248 return new QSGDefaultImageNode;
252 Factory function for scene graph backends of the distance-field glyph cache.
254 QSGDistanceFieldGlyphCache *QSGContext::createDistanceFieldGlyphCache(const QRawFont &font)
258 QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
259 if (platformIntegration != 0
260 && platformIntegration->hasCapability(QPlatformIntegration::SharedGraphicsCache)) {
261 QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
262 if (!fe->faceId().filename.isEmpty()) {
263 QByteArray keyName = fe->faceId().filename;
264 if (font.style() != QFont::StyleNormal)
265 keyName += QByteArray(" I");
266 if (font.weight() != QFont::Normal)
267 keyName += " " + QByteArray::number(font.weight());
268 keyName += QByteArray(" DF");
269 QPlatformSharedGraphicsCache *sharedGraphicsCache =
270 platformIntegration->createPlatformSharedGraphicsCache(keyName);
272 if (sharedGraphicsCache != 0) {
273 sharedGraphicsCache->ensureCacheInitialized(keyName,
274 QPlatformSharedGraphicsCache::OpenGLTexture,
275 QPlatformSharedGraphicsCache::Alpha8);
277 return new QSGSharedDistanceFieldGlyphCache(keyName,
279 d->distanceFieldCacheManager,
286 return new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font);
290 Factory function for scene graph backends of the Text elements;
292 QSGGlyphNode *QSGContext::createGlyphNode()
296 // ### Do something with these before final release...
297 static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing"));
298 static bool doLowQualSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing-lowq"));
299 static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing"));
301 if (d->distanceFieldDisabled) {
302 return new QSGDefaultGlyphNode;
304 if (!d->distanceFieldCacheManager) {
305 d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager(this);
307 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::HighQualitySubPixelAntialiasing);
308 else if (doLowQualSubpixel)
309 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::LowQualitySubPixelAntialiasing);
311 d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
314 QSGGlyphNode *node = new QSGDistanceFieldGlyphNode(d->distanceFieldCacheManager);
320 Factory function for the scene graph renderers.
322 The renderers are used for the toplevel renderer and once for every
323 QQuickShaderEffectSource used in the QML scene.
325 QSGRenderer *QSGContext::createRenderer()
327 // ### Do something with this before release...
328 static bool doFrontToBack = qApp->arguments().contains(QLatin1String("--opaque-front-to-back"));
329 QSGDefaultRenderer *renderer = new QSGDefaultRenderer(this);
331 printf("QSGContext: Sorting opaque nodes front to back...\n");
332 renderer->setSortFrontToBackEnabled(true);
340 QSurfaceFormat QSGContext::defaultSurfaceFormat() const
342 QSurfaceFormat format;
343 format.setDepthBufferSize(24);
344 format.setStencilBufferSize(8);
345 format.setSamples(16);
351 Factory function for texture objects.
353 If \a image is a valid image, the QSGTexture::setImage function
354 will be called with \a image as argument.
357 QSGTexture *QSGContext::createTexture(const QImage &image) const
359 QSGPlainTexture *t = new QSGPlainTexture();
368 Returns the minimum supported framebuffer object size.
371 QSize QSGContext::minimumFBOSize() const
374 return QSize(33, 33);
383 Returns a material shader for the given material.
386 QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
389 QSGMaterialType *type = material->type();
390 QSGMaterialShader *shader = d->materials.value(type);
394 shader = material->createShader();
396 shader->initialize();
397 d->materials[type] = shader;
405 Sets whether the scene graph should render with flashing update rectangles or not
408 void QSGContext::setFlashModeEnabled(bool enabled)
410 d_func()->flashMode = enabled;
415 Returns true if the scene graph should be rendered with flashing update rectangles
417 bool QSGContext::isFlashModeEnabled() const
419 return d_func()->flashMode;
424 Sets the toplevel opacity for rendering. This value will be multiplied into all
425 drawing calls where possible.
427 The default value is 1. Any other value will cause artifacts and is primarily
428 useful for debugging.
430 void QSGContext::setRenderAlpha(qreal renderAlpha)
432 d_func()->renderAlpha = renderAlpha;
437 Returns the toplevel opacity used for rendering.
439 The default value is 1.
443 qreal QSGContext::renderAlpha() const
445 return d_func()->renderAlpha;
450 Sets whether or not the scene graph should use the distance field technique to render text
452 void QSGContext::setDistanceFieldEnabled(bool enabled)
454 d_func()->distanceFieldDisabled = !enabled;
459 Returns true if the scene graph uses the distance field technique to render text
461 bool QSGContext::isDistanceFieldEnabled() const
463 return !d_func()->distanceFieldDisabled;
469 Creates a new animation driver.
472 QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
474 return new QAnimationDriver(parent);