From b480fa83a632b2ae5606e2870b47358328b479a2 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 14 Aug 2013 07:27:07 +0200 Subject: New scenegraph renderer and atlas textures. The renderer tries to batch primitives together where possible, isolate non-changing subparts of the scene from changing subparts and retain vertexdata on the GPU as much as possible. Atlas textures are crucial in enabling batching. The renderer and atlas texture are described in detail in the doc page "Qt Quick Scene Graph Renderer". Change-Id: Ia476c7f0f42e1fc57a2cef528e93ee88cf8f7055 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/quick/scenegraph/qsgcontext.cpp | 39 ++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'src/quick/scenegraph/qsgcontext.cpp') diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index cb0a6d5afc..070a8422d0 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include -#include +#include #include #include #include @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -114,6 +115,7 @@ public: #else , distanceFieldAntialiasing(QSGGlyphNode::GrayAntialiasing) #endif + , atlasManager(0) , flashMode(qmlFlashMode()) , distanceFieldDisabled(qmlDisableDistanceField()) { @@ -134,6 +136,8 @@ public: QSGDistanceFieldGlyphNode::AntialiasingMode distanceFieldAntialiasing; + QSGAtlasTexture::Manager *atlasManager; + bool flashMode; float renderAlpha; bool distanceFieldDisabled; @@ -196,6 +200,25 @@ void QSGContext::invalidate() 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->atlasManager->deleteLater(); + d->atlasManager = 0; } @@ -260,6 +283,8 @@ void QSGContext::initialize(QOpenGLContext *context) if (requested.stencilBufferSize() > 0 && actual.stencilBufferSize() <= 0) qWarning("QSGContext::initialize: stencil buffer support missing, expect rendering errors"); + d->atlasManager = new QSGAtlasTexture::Manager(); + Q_ASSERT(!d->gl); d->gl = context; @@ -414,7 +439,7 @@ QSGGlyphNode *QSGContext::createGlyphNode() */ QSGRenderer *QSGContext::createRenderer() { - return new QSGDefaultRenderer(this); + return new QSGBatchRenderer::Renderer(this); } @@ -441,10 +466,11 @@ QSurfaceFormat QSGContext::defaultSurfaceFormat() const QSGTexture *QSGContext::createTexture(const QImage &image) const { - QSGPlainTexture *t = new QSGPlainTexture(); - if (!image.isNull()) - t->setImage(image); - return t; + Q_D(const QSGContext); + QSGTexture *at = d->atlasManager->create(image); + if (at) + return at; + return createTextureNoAtlas(image); } QSGTexture *QSGContext::createTextureNoAtlas(const QImage &image) const @@ -455,7 +481,6 @@ QSGTexture *QSGContext::createTextureNoAtlas(const QImage &image) const return t; } - /*! Returns the minimum supported framebuffer object size. */ -- cgit v1.2.3