aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/qsgcontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph/qsgcontext.cpp')
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp591
1 files changed, 297 insertions, 294 deletions
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index bb8e3c4b36..afde7939f2 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -72,11 +72,8 @@
#include <private/qqmlprofilerservice_p.h>
-DEFINE_BOOL_CONFIG_OPTION(qmlFlashMode, QML_FLASH_MODE)
-DEFINE_BOOL_CONFIG_OPTION(qmlTranslucentMode, QML_TRANSLUCENT_MODE)
DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
-
/*
Comments about this class from Gunnar:
@@ -94,51 +91,38 @@ DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
to defining plugin interfaces..
*/
-
QT_BEGIN_NAMESPACE
class QSGContextPrivate : public QObjectPrivate
{
public:
QSGContextPrivate()
- : gl(0)
- , depthStencilBufferManager(0)
- , distanceFieldCacheManager(0)
- #if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE)
- , distanceFieldAntialiasing(QSGGlyphNode::HighQualitySubPixelAntialiasing)
- #else
- , distanceFieldAntialiasing(QSGGlyphNode::GrayAntialiasing)
- #endif
- , atlasManager(0)
- , flashMode(qmlFlashMode())
+ : antialiasingMethod(QSGContext::UndecidedAntialiasing)
, distanceFieldDisabled(qmlDisableDistanceField())
- , msaa(false)
+ , distanceFieldAntialiasing(
+#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE)
+ QSGGlyphNode::HighQualitySubPixelAntialiasing
+#else
+ QSGGlyphNode::GrayAntialiasing
+#endif
+ )
{
- renderAlpha = qmlTranslucentMode() ? 0.5 : 1;
}
~QSGContextPrivate()
{
}
- QOpenGLContext *gl;
-
- QMutex textureMutex;
- QHash<QQuickTextureFactory *, QSGTexture *> textures;
- QSGDepthStencilBufferManager *depthStencilBufferManager;
- QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager;
-
- QSGDistanceFieldGlyphNode::AntialiasingMode distanceFieldAntialiasing;
-
- QSGAtlasTexture::Manager *atlasManager;
-
- bool flashMode;
- float renderAlpha;
+ QMutex mutex;
+ QSGContext::AntialiasingMethod antialiasingMethod;
bool distanceFieldDisabled;
+ QSGDistanceFieldGlyphNode::AntialiasingMode distanceFieldAntialiasing;
- bool msaa;
+ static QOpenGLContext *sharedOpenGLContext;
};
+QOpenGLContext *QSGContextPrivate::sharedOpenGLContext = 0;
+
class QSGTextureCleanupEvent : public QEvent
{
public:
@@ -188,144 +172,190 @@ QSGContext::QSGContext(QObject *parent) :
QSGContext::~QSGContext()
{
- invalidate();
}
+/*!
+ * This function is used by the Qt WebEngine to set up context sharing
+ * across multiple windows. Do not use it for any other purpose.
+ */
+void QSGContext::setSharedOpenGLContext(QOpenGLContext *context)
+{
+ QSGContextPrivate::sharedOpenGLContext = context;
+}
+QOpenGLContext *QSGContext::sharedOpenGLContext()
+{
+ return QSGContextPrivate::sharedOpenGLContext;
+}
-void QSGContext::invalidate()
+void QSGContext::renderContextInitialized(QSGRenderContext *renderContext)
{
Q_D(QSGContext);
- d->textureMutex.lock();
- qDeleteAll(d->textures.values());
- d->textures.clear();
- d->textureMutex.unlock();
- delete d->depthStencilBufferManager;
- d->depthStencilBufferManager = 0;
- delete d->distanceFieldCacheManager;
- d->distanceFieldCacheManager = 0;
- d->gl = 0;
-
- emit invalidated();
-
- /* The cleanup of the atlas textures is a bit intruiging.
- As part of the cleanup in the threaded render loop, we
- do:
- 1. call this function
- 2. call QCoreApp::sendPostedEvents() to immediately process
- any pending deferred deletes.
- 3. delete the GL context.
- As textures need the atlas manager while cleaning up, the
- manager needs to be cleaned up after the textures, so
- we post a deleteLater here at the very bottom so it gets
- deferred deleted last.
-
- Another alternative would be to use a QPointer in
- QSGAtlasTexture::Texture, but this seemed simpler.
- */
+ d->mutex.lock();
+ if (d->antialiasingMethod == UndecidedAntialiasing) {
+ QByteArray aaType = qgetenv("QSG_ANTIALIASING_METHOD");
+ if (aaType == "msaa") {
+ d->antialiasingMethod = MsaaAntialiasing;
+ } else if (aaType == "vertex") {
+ d->antialiasingMethod = VertexAntialiasing;
+ } else {
+ if (renderContext->openglContext()->format().samples() > 0)
+ d->antialiasingMethod = MsaaAntialiasing;
+ else
+ d->antialiasingMethod = VertexAntialiasing;
+ }
+ }
- if (d->atlasManager) {
- d->atlasManager->deleteLater();
- d->atlasManager = 0;
+ static bool dumped = false;
+ if (!dumped && qEnvironmentVariableIsSet("QSG_INFO")) {
+ dumped = true;
+ qDebug() << "GL_VENDOR: " << (const char *) glGetString(GL_VENDOR);
+ qDebug() << "GL_RENDERER: " << (const char *) glGetString(GL_RENDERER);
+ qDebug() << "GL_VERSION: " << (const char *) glGetString(GL_VERSION);
+ qDebug() << "GL_EXTENSIONS:\n " << QByteArray((const char *) glGetString(GL_EXTENSIONS)).replace(" ", "\n ").constData();
}
+
+ d->mutex.unlock();
}
+void QSGContext::renderContextInvalidated(QSGRenderContext *)
+{
+}
-QSGTexture *QSGContext::textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window)
+/*!
+ Factory function for scene graph backends of the Rectangle element.
+ */
+QSGRectangleNode *QSGContext::createRectangleNode()
{
Q_D(QSGContext);
- if (!factory)
- return 0;
-
- d->textureMutex.lock();
- QSGTexture *texture = d->textures.value(factory);
- if (!texture) {
- if (QQuickDefaultTextureFactory *dtf = qobject_cast<QQuickDefaultTextureFactory *>(factory))
- texture = createTexture(dtf->image());
- else
- texture = factory->createTexture(window);
- d->textures.insert(factory, texture);
- connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *)), Qt::DirectConnection);
- }
- d->textureMutex.unlock();
- return texture;
+ return d->antialiasingMethod == MsaaAntialiasing
+ ? new QSGMultisampleAntialiasing::RectangleNode
+ : new QSGDefaultRectangleNode;
}
+/*!
+ Factory function for scene graph backends of the Image element.
+ */
+QSGImageNode *QSGContext::createImageNode()
+{
+ Q_D(QSGContext);
+ return d->antialiasingMethod == MsaaAntialiasing
+ ? new QSGMultisampleAntialiasing::ImageNode
+ : new QSGDefaultImageNode;
+}
-void QSGContext::textureFactoryDestroyed(QObject *o)
+/*!
+ Factory function for scene graph backends of the Text elements which supports native
+ text rendering. Used in special cases where native look and feel is a main objective.
+*/
+QSGGlyphNode *QSGContext::createNativeGlyphNode(QSGRenderContext *rc)
{
+#if defined(QT_OPENGL_ES) && !defined(QT_OPENGL_ES_2_ANGLE)
Q_D(QSGContext);
- QQuickTextureFactory *f = static_cast<QQuickTextureFactory *>(o);
+ if (d->distanceFieldDisabled)
+ return new QSGDefaultGlyphNode;
+ else
+ return createGlyphNode(rc);
+#else
+ Q_UNUSED(rc);
+ return new QSGDefaultGlyphNode;
+#endif
+}
- d->textureMutex.lock();
- QSGTexture *t = d->textures.take(f);
- d->textureMutex.unlock();
+/*!
+ Factory function for scene graph backends of the Text elements;
+ */
+QSGGlyphNode *QSGContext::createGlyphNode(QSGRenderContext *rc)
+{
+ Q_D(QSGContext);
- if (t) {
- if (t->thread() == thread())
- t->deleteLater();
- else
- QCoreApplication::postEvent(this, new QSGTextureCleanupEvent(t));
+ if (d->distanceFieldDisabled) {
+ return createNativeGlyphNode(rc);
+ } else {
+ QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(rc);
+ node->setPreferredAntialiasingMode(d->distanceFieldAntialiasing);
+ return node;
}
}
-
-QOpenGLContext *QSGContext::glContext() const
+QSurfaceFormat QSGContext::defaultSurfaceFormat() const
{
- Q_D(const QSGContext);
- return d->gl;
+ QSurfaceFormat format;
+ format.setDepthBufferSize(24);
+ format.setStencilBufferSize(8);
+ if (QQuickWindow::hasDefaultAlphaBuffer())
+ format.setAlphaBufferSize(8);
+ format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ return format;
}
/*!
- Initializes the scene graph context with the GL context \a context. This also
- emits the ready() signal so that the QML graph can start building scene graph nodes.
+ Returns the minimum supported framebuffer object size.
*/
-void QSGContext::initialize(QOpenGLContext *context)
+
+QSize QSGContext::minimumFBOSize() const
{
- Q_D(QSGContext);
+#ifdef Q_OS_MAC
+ return QSize(33, 33);
+#else
+ return QSize(1, 1);
+#endif
+}
- QByteArray aaType = qgetenv("QSG_ANTIALIASING_METHOD");
- if (aaType == "msaa") {
- d->msaa = true;
- } else if (aaType == "vertex") {
- d->msaa = false;
- } else {
- if (context->format().samples() > 0)
- d->msaa = true;
- else
- d->msaa = false;
- }
- // Sanity check the surface format, in case it was overridden by the application
- QSurfaceFormat requested = defaultSurfaceFormat();
- QSurfaceFormat actual = context->format();
- if (requested.depthBufferSize() > 0 && actual.depthBufferSize() <= 0)
- qWarning("QSGContext::initialize: depth buffer support missing, expect rendering errors");
- if (requested.stencilBufferSize() > 0 && actual.stencilBufferSize() <= 0)
- qWarning("QSGContext::initialize: stencil buffer support missing, expect rendering errors");
- d->atlasManager = new QSGAtlasTexture::Manager();
+/*!
+ Sets whether or not the scene graph should use the distance field technique to render text
+ */
+void QSGContext::setDistanceFieldEnabled(bool enabled)
+{
+ d_func()->distanceFieldDisabled = !enabled;
+}
- Q_ASSERT(!d->gl);
- d->gl = context;
- emit initialized();
+/*!
+ Returns true if the scene graph uses the distance field technique to render text
+ */
+bool QSGContext::isDistanceFieldEnabled() const
+{
+ return !d_func()->distanceFieldDisabled;
}
+
+
/*!
- Returns if the scene graph context is ready or not, meaning that it has a valid
- GL context.
+ Creates a new animation driver.
*/
-bool QSGContext::isReady() const
+
+QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
{
- Q_D(const QSGContext);
- return d->gl;
+ return new QAnimationDriver(parent);
}
+QSGRenderContext::QSGRenderContext(QSGContext *context)
+ : m_gl(0)
+ , m_sg(context)
+ , m_atlasManager(0)
+ , m_depthStencilManager(0)
+ , m_distanceFieldCacheManager(0)
+ , m_brokenIBOs(false)
+ , m_serializedRender(false)
+{
+}
-void QSGContext::renderNextFrame(QSGRenderer *renderer, GLuint fboId)
+QSGRenderContext::~QSGRenderContext()
{
+ invalidate();
+}
+
+static QBasicMutex qsg_framerender_mutex;
+
+void QSGRenderContext::renderNextFrame(QSGRenderer *renderer, GLuint fboId)
+{
+ if (m_serializedRender)
+ qsg_framerender_mutex.lock();
+
if (fboId) {
QSGBindableFboId bindable(fboId);
renderer->renderScene(bindable);
@@ -333,39 +363,20 @@ void QSGContext::renderNextFrame(QSGRenderer *renderer, GLuint fboId)
renderer->renderScene();
}
-}
+ if (m_serializedRender)
+ qsg_framerender_mutex.unlock();
-/*!
- Factory function for scene graph backends of the Rectangle element.
- */
-QSGRectangleNode *QSGContext::createRectangleNode()
-{
- Q_D(QSGContext);
- return d->msaa ? new QSGMultisampleAntialiasing::RectangleNode
- : new QSGDefaultRectangleNode;
-}
-
-/*!
- Factory function for scene graph backends of the Image element.
- */
-QSGImageNode *QSGContext::createImageNode()
-{
- Q_D(QSGContext);
- return d->msaa ? new QSGMultisampleAntialiasing::ImageNode
- : new QSGDefaultImageNode;
}
/*!
Factory function for scene graph backends of the distance-field glyph cache.
*/
-QSGDistanceFieldGlyphCache *QSGContext::distanceFieldGlyphCache(const QRawFont &font)
+QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRawFont &font)
{
- Q_D(QSGContext);
-
- if (!d->distanceFieldCacheManager)
- d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager;
+ if (!m_distanceFieldCacheManager)
+ m_distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager;
- QSGDistanceFieldGlyphCache *cache = d->distanceFieldCacheManager->cache(font);
+ QSGDistanceFieldGlyphCache *cache = m_distanceFieldCacheManager->cache(font);
if (!cache) {
QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
if (platformIntegration != 0
@@ -387,125 +398,125 @@ QSGDistanceFieldGlyphCache *QSGContext::distanceFieldGlyphCache(const QRawFont &
QPlatformSharedGraphicsCache::Alpha8);
cache = new QSGSharedDistanceFieldGlyphCache(keyName,
- sharedGraphicsCache,
- d->distanceFieldCacheManager,
- glContext(),
- font);
+ sharedGraphicsCache,
+ m_distanceFieldCacheManager,
+ openglContext(),
+ font);
}
}
}
if (!cache)
- cache = new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font);
- d->distanceFieldCacheManager->insertCache(font, cache);
+ cache = new QSGDefaultDistanceFieldGlyphCache(m_distanceFieldCacheManager, openglContext(), font);
+ m_distanceFieldCacheManager->insertCache(font, cache);
}
+
return cache;
}
-/*!
- Factory function for scene graph backends of the Text elements which supports native
- text rendering. Used in special cases where native look and feel is a main objective.
-*/
-QSGGlyphNode *QSGContext::createNativeGlyphNode()
+#define QSG_RENDERCONTEXT_PROPERTY "_q_sgrendercontext"
+
+QSGRenderContext *QSGRenderContext::from(QOpenGLContext *context)
{
-#if defined(QT_OPENGL_ES) && !defined(QT_OPENGL_ES_2_ANGLE)
- Q_D(QSGContext);
- if (d->distanceFieldDisabled)
- return new QSGDefaultGlyphNode;
- else
- return createGlyphNode();
-#else
- return new QSGDefaultGlyphNode;
-#endif
+ return qobject_cast<QSGRenderContext *>(context->property(QSG_RENDERCONTEXT_PROPERTY).value<QObject *>());
}
-/*!
- Factory function for scene graph backends of the Text elements;
- */
-QSGGlyphNode *QSGContext::createGlyphNode()
+void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine)
{
- Q_D(QSGContext);
-
- if (d->distanceFieldDisabled) {
- return createNativeGlyphNode();
- } else {
- QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(this);
- node->setPreferredAntialiasingMode(d->distanceFieldAntialiasing);
- return node;
- }
+ m_fontEnginesToClean << engine;
}
/*!
- Factory function for the scene graph renderers.
-
- The renderers are used for the toplevel renderer and once for every
- QQuickShaderEffectSource used in the QML scene.
+ Initializes the scene graph render context with the GL context \a context. This also
+ emits the ready() signal so that the QML graph can start building scene graph nodes.
*/
-QSGRenderer *QSGContext::createRenderer()
+void QSGRenderContext::initialize(QOpenGLContext *context)
{
- return new QSGBatchRenderer::Renderer(this);
-}
-
-
+ // Sanity check the surface format, in case it was overridden by the application
+ QSurfaceFormat requested = m_sg->defaultSurfaceFormat();
+ QSurfaceFormat actual = context->format();
+ if (requested.depthBufferSize() > 0 && actual.depthBufferSize() <= 0)
+ qWarning("QSGContext::initialize: depth buffer support missing, expect rendering errors");
+ if (requested.stencilBufferSize() > 0 && actual.stencilBufferSize() <= 0)
+ qWarning("QSGContext::initialize: stencil buffer support missing, expect rendering errors");
+ if (!m_atlasManager)
+ m_atlasManager = new QSGAtlasTexture::Manager();
+
+ Q_ASSERT_X(!m_gl, "QSGRenderContext::initialize", "already initialized!");
+ m_gl = context;
+ m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant::fromValue(this));
+ m_sg->renderContextInitialized(this);
+
+#ifdef Q_OS_LINUX
+ const char *vendor = (const char *) glGetString(GL_VENDOR);
+ if (strstr(vendor, "nouveau"))
+ m_brokenIBOs = true;
+ const char *renderer = (const char *) glGetString(GL_RENDERER);
+ if (strstr(renderer, "llvmpipe"))
+ m_serializedRender = true;
+#endif
-QSurfaceFormat QSGContext::defaultSurfaceFormat() const
-{
- QSurfaceFormat format;
- format.setDepthBufferSize(24);
- format.setStencilBufferSize(8);
- if (QQuickWindow::hasDefaultAlphaBuffer())
- format.setAlphaBufferSize(8);
- format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
- return format;
+ emit initialized();
}
-
-/*!
- Factory function for texture objects.
-
- If \a image is a valid image, the QSGTexture::setImage function
- will be called with \a image as argument.
- */
-
-QSGTexture *QSGContext::createTexture(const QImage &image) const
+void QSGRenderContext::invalidate()
{
- Q_D(const QSGContext);
- QSGTexture *at = d->atlasManager->create(image);
- if (at)
- return at;
- return createTextureNoAtlas(image);
-}
+ if (!m_gl)
+ return;
+
+ qDeleteAll(m_textures.values());
+ m_textures.clear();
+
+ /* The cleanup of the atlas textures is a bit intriguing.
+ As part of the cleanup in the threaded render loop, we
+ do:
+ 1. call this function
+ 2. call QCoreApp::sendPostedEvents() to immediately process
+ any pending deferred deletes.
+ 3. delete the GL context.
+
+ As textures need the atlas manager while cleaning up, the
+ manager needs to be cleaned up after the textures, so
+ we post a deleteLater here at the very bottom so it gets
+ deferred deleted last.
+
+ Another alternative would be to use a QPointer in
+ QSGAtlasTexture::Texture, but this seemed simpler.
+ */
+ m_atlasManager->invalidate();
+ m_atlasManager->deleteLater();
+ m_atlasManager = 0;
+
+ // The following piece of code will read/write to the font engine's caches,
+ // potentially from different threads. However, this is safe because this
+ // code is only called from QQuickWindow's shutdown which is called
+ // only when the GUI is blocked, and multiple threads will call it in
+ // sequence. (see qsgdefaultglyphnode_p.cpp's init())
+ for (QSet<QFontEngine *>::const_iterator it = m_fontEnginesToClean.constBegin(),
+ end = m_fontEnginesToClean.constEnd(); it != end; ++it) {
+ (*it)->clearGlyphCache(m_gl);
+ }
+ m_fontEnginesToClean.clear();
-QSGTexture *QSGContext::createTextureNoAtlas(const QImage &image) const
-{
- QSGPlainTexture *t = new QSGPlainTexture();
- if (!image.isNull())
- t->setImage(image);
- return t;
-}
+ delete m_depthStencilManager;
+ m_depthStencilManager = 0;
-/*!
- Returns the minimum supported framebuffer object size.
- */
-
-QSize QSGContext::minimumFBOSize() const
-{
-#ifdef Q_OS_MAC
- return QSize(33, 33);
-#else
- return QSize(1, 1);
-#endif
-}
+ delete m_distanceFieldCacheManager;
+ m_distanceFieldCacheManager = 0;
+ m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant());
+ m_gl = 0;
+ m_sg->renderContextInvalidated(this);
+ emit invalidated();
+}
/*!
Returns a shared pointer to a depth stencil buffer that can be used with \a fbo.
*/
-QSharedPointer<QSGDepthStencilBuffer> QSGContext::depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo)
+QSharedPointer<QSGDepthStencilBuffer> QSGRenderContext::depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo)
{
- Q_D(QSGContext);
- if (!d->gl)
+ if (!m_gl)
return QSharedPointer<QSGDepthStencilBuffer>();
QSGDepthStencilBufferManager *manager = depthStencilBufferManager();
QSGDepthStencilBuffer::Format format;
@@ -514,7 +525,7 @@ QSharedPointer<QSGDepthStencilBuffer> QSGContext::depthStencilBufferForFbo(QOpen
format.attachments = QSGDepthStencilBuffer::DepthAttachment | QSGDepthStencilBuffer::StencilAttachment;
QSharedPointer<QSGDepthStencilBuffer> buffer = manager->bufferForFormat(format);
if (buffer.isNull()) {
- buffer = QSharedPointer<QSGDepthStencilBuffer>(new QSGDefaultDepthStencilBuffer(d->gl, format));
+ buffer = QSharedPointer<QSGDepthStencilBuffer>(new QSGDefaultDepthStencilBuffer(m_gl, format));
manager->insertBuffer(buffer);
}
return buffer;
@@ -524,89 +535,81 @@ QSharedPointer<QSGDepthStencilBuffer> QSGContext::depthStencilBufferForFbo(QOpen
Returns a pointer to the context's depth/stencil buffer manager. This is useful for custom
implementations of \l depthStencilBufferForFbo().
*/
-QSGDepthStencilBufferManager *QSGContext::depthStencilBufferManager()
+QSGDepthStencilBufferManager *QSGRenderContext::depthStencilBufferManager()
{
- Q_D(QSGContext);
- if (!d->gl)
+ if (!m_gl)
return 0;
- if (!d->depthStencilBufferManager)
- d->depthStencilBufferManager = new QSGDepthStencilBufferManager(d->gl);
- return d->depthStencilBufferManager;
+ if (!m_depthStencilManager)
+ m_depthStencilManager = new QSGDepthStencilBufferManager(m_gl);
+ return m_depthStencilManager;
}
/*!
- Sets whether the scene graph should render with flashing update rectangles or not
- */
-
-void QSGContext::setFlashModeEnabled(bool enabled)
-{
- d_func()->flashMode = enabled;
-}
-
+ Factory function for texture objects.
-/*!
- Returns true if the scene graph should be rendered with flashing update rectangles
+ If \a image is a valid image, the QSGTexture::setImage function
+ will be called with \a image as argument.
*/
-bool QSGContext::isFlashModeEnabled() const
+
+QSGTexture *QSGRenderContext::createTexture(const QImage &image) const
{
- return d_func()->flashMode;
+ QSGTexture *t = m_atlasManager->create(image);
+ if (t)
+ return t;
+ return createTextureNoAtlas(image);
}
-
-/*!
- Sets the toplevel opacity for rendering. This value will be multiplied into all
- drawing calls where possible.
-
- The default value is 1. Any other value will cause artifacts and is primarily
- useful for debugging.
- */
-void QSGContext::setRenderAlpha(qreal renderAlpha)
+QSGTexture *QSGRenderContext::createTextureNoAtlas(const QImage &image) const
{
- d_func()->renderAlpha = renderAlpha;
+ QSGPlainTexture *t = new QSGPlainTexture();
+ if (!image.isNull())
+ t->setImage(image);
+ return t;
}
-
/*!
- Returns the toplevel opacity used for rendering.
-
- The default value is 1.
+ Factory function for the scene graph renderers.
- \sa setRenderAlpha()
+ The renderers are used for the toplevel renderer and once for every
+ QQuickShaderEffectSource used in the QML scene.
*/
-qreal QSGContext::renderAlpha() const
+QSGRenderer *QSGRenderContext::createRenderer()
{
- return d_func()->renderAlpha;
+ return new QSGBatchRenderer::Renderer(this);
}
-
-/*!
- Sets whether or not the scene graph should use the distance field technique to render text
- */
-void QSGContext::setDistanceFieldEnabled(bool enabled)
+QSGTexture *QSGRenderContext::textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window)
{
- d_func()->distanceFieldDisabled = !enabled;
-}
+ if (!factory)
+ return 0;
+ m_mutex.lock();
+ QSGTexture *texture = m_textures.value(factory);
+ m_mutex.unlock();
-/*!
- Returns true if the scene graph uses the distance field technique to render text
- */
-bool QSGContext::isDistanceFieldEnabled() const
-{
- return !d_func()->distanceFieldDisabled;
-}
-
+ if (!texture) {
+ if (QQuickDefaultTextureFactory *dtf = qobject_cast<QQuickDefaultTextureFactory *>(factory))
+ texture = createTexture(dtf->image());
+ else
+ texture = factory->createTexture(window);
+ m_mutex.lock();
+ m_textures.insert(factory, texture);
+ m_mutex.unlock();
-/*!
- Creates a new animation driver.
- */
+ connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *)), Qt::DirectConnection);
+ }
+ return texture;
+}
-QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
+void QSGRenderContext::textureFactoryDestroyed(QObject *o)
{
- return new QAnimationDriver(parent);
+ m_mutex.lock();
+ QSGTexture *t = m_textures.take(static_cast<QQuickTextureFactory *>(o));
+ m_mutex.unlock();
+ if (t)
+ t->deleteLater();
}
-
QT_END_NAMESPACE