diff options
Diffstat (limited to 'src/quick/scenegraph/coreapi')
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h | 11 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 87 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h | 35 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsggeometry_p.h | 11 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgmaterial.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgmaterialshader_p.h | 11 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgnode.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgnode_p.h | 11 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgnodeupdater.cpp | 18 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgnodeupdater_p.h | 11 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgrenderer.cpp | 11 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgrenderer_p.h | 11 |
12 files changed, 163 insertions, 58 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h index c5504513f4..17de89bf11 100644 --- a/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer_p.h @@ -34,6 +34,17 @@ #ifndef QSGABSTRACTRENDERER_P_H #define QSGABSTRACTRENDERER_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "qsgabstractrenderer.h" #include "qsgnode.h" diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 4b0bc683c2..b1792d27a7 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -61,6 +61,8 @@ QT_BEGIN_NAMESPACE extern QByteArray qsgShaderRewriter_insertZAttributes(const char *input, QSurfaceFormat::OpenGLContextProfile profile); +int qt_sg_envInt(const char *name, int defaultValue); + namespace QSGBatchRenderer { @@ -198,9 +200,9 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate void ShaderManager::invalidated() { - qDeleteAll(stockShaders.values()); + qDeleteAll(stockShaders); stockShaders.clear(); - qDeleteAll(rewrittenShaders.values()); + qDeleteAll(rewrittenShaders); rewrittenShaders.clear(); delete blitProgram; blitProgram = 0; @@ -487,6 +489,11 @@ void Updater::visitGeometryNode(Node *n) if (e->batch) renderer->invalidateBatchAndOverlappingRenderOrders(e->batch); } + if (n->dirtyState & QSGNode::DirtyMaterial) { + Element *e = n->element(); + if (e->batch && e->batch->isMaterialCompatible(e) == BatchBreaksOnCompare) + renderer->invalidateBatchAndOverlappingRenderOrders(e->batch); + } } SHADOWNODE_TRAVERSE(n) visitNode(*child); @@ -780,30 +787,17 @@ Renderer::Renderer(QSGRenderContext *ctx) } m_bufferStrategy = GL_STATIC_DRAW; - QByteArray strategy = qgetenv("QSG_RENDERER_BUFFER_STRATEGY"); - if (strategy == "dynamic") { - m_bufferStrategy = GL_DYNAMIC_DRAW; - } else if (strategy == "stream") { - m_bufferStrategy = GL_STREAM_DRAW; - } - - m_batchNodeThreshold = 64; - QByteArray alternateThreshold = qgetenv("QSG_RENDERER_BATCH_NODE_THRESHOLD"); - if (alternateThreshold.length() > 0) { - bool ok = false; - int threshold = alternateThreshold.toInt(&ok); - if (ok) - m_batchNodeThreshold = threshold; - } - - m_batchVertexThreshold = 1024; - alternateThreshold = qgetenv("QSG_RENDERER_BATCH_VERTEX_THRESHOLD"); - if (alternateThreshold.length() > 0) { - bool ok = false; - int threshold = alternateThreshold.toInt(&ok); - if (ok) - m_batchVertexThreshold = threshold; + if (Q_UNLIKELY(qEnvironmentVariableIsSet("QSG_RENDERER_BUFFER_STRATEGY"))) { + const QByteArray strategy = qgetenv("QSG_RENDERER_BUFFER_STRATEGY"); + if (strategy == "dynamic") + m_bufferStrategy = GL_DYNAMIC_DRAW; + else if (strategy == "stream") + m_bufferStrategy = GL_STREAM_DRAW; } + + m_batchNodeThreshold = qt_sg_envInt("QSG_RENDERER_BATCH_NODE_THRESHOLD", 64); + m_batchVertexThreshold = qt_sg_envInt("QSG_RENDERER_BATCH_VERTEX_THRESHOLD", 1024); + if (Q_UNLIKELY(debug_build() || debug_render())) { qDebug() << "Batch thresholds: nodes:" << m_batchNodeThreshold << " vertices:" << m_batchVertexThreshold; qDebug() << "Using buffer strategy:" << (m_bufferStrategy == GL_STATIC_DRAW ? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream")); @@ -816,7 +810,8 @@ Renderer::Renderer(QSGRenderContext *ctx) m_vao->create(); } - m_useDepthBuffer = ctx->openglContext()->format().depthBufferSize() > 0; + bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); + m_useDepthBuffer = useDepth && ctx->openglContext()->format().depthBufferSize() > 0; } static void qsg_wipeBuffer(Buffer *buffer, QOpenGLFunctions *funcs) @@ -1081,6 +1076,11 @@ void Renderer::nodeWasRemoved(Node *node) if (e) { e->removed = true; m_elementsToDelete.add(e); + + if (m_renderNodeElements.isEmpty()) { + static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); + m_useDepthBuffer = useDepth && context()->openglContext()->format().depthBufferSize() > 0; + } } } @@ -1213,10 +1213,7 @@ void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) if (e->isMaterialBlended != blended) { m_rebuild |= Renderer::FullRebuild; e->isMaterialBlended = blended; - } else if (e->batch) { - if (e->batch->isMaterialCompatible(e) == BatchBreaksOnCompare) - invalidateBatchAndOverlappingRenderOrders(e->batch); - } else { + } else if (!e->batch) { m_rebuild |= Renderer::BuildBatches; } } @@ -2554,8 +2551,15 @@ void Renderer::render() QSGNodeDumper::dump(rootNode()); } - if (Q_UNLIKELY(debug_render() || debug_build())) { + QElapsedTimer timer; + quint64 timeRenderLists = 0; + quint64 timePrepareOpaque = 0; + quint64 timePrepareAlpha = 0; + quint64 timeSorting = 0; + quint64 timeUploadOpaque = 0; + quint64 timeUploadAlpha = 0; + if (Q_UNLIKELY(debug_render() || debug_build())) { QByteArray type("rebuild:"); if (m_rebuild == 0) type += " none"; @@ -2571,6 +2575,7 @@ void Renderer::render() } qDebug() << "Renderer::render()" << this << type; + timer.start(); } if (m_vao) @@ -2597,6 +2602,7 @@ void Renderer::render() } } } + if (Q_UNLIKELY(debug_render())) timeRenderLists = timer.restart(); for (int i=0; i<m_opaqueBatches.size(); ++i) m_opaqueBatches.at(i)->cleanupRemovedElements(); @@ -2609,7 +2615,9 @@ void Renderer::render() if (m_rebuild & BuildBatches) { prepareOpaqueBatches(); + if (Q_UNLIKELY(debug_render())) timePrepareOpaque = timer.restart(); prepareAlphaBatches(); + if (Q_UNLIKELY(debug_render())) timePrepareAlpha = timer.restart(); if (Q_UNLIKELY(debug_build())) { qDebug() << "Opaque Batches:"; @@ -2629,8 +2637,11 @@ void Renderer::render() } } } + } else { + if (Q_UNLIKELY(debug_render())) timePrepareOpaque = timePrepareAlpha = timer.restart(); } + deleteRemovedElements(); if (m_rebuild != 0) { @@ -2646,6 +2657,8 @@ void Renderer::render() m_zRange = 1.0 / (m_nextRenderOrder); } + if (Q_UNLIKELY(debug_render())) timeSorting = timer.restart(); + int largestVBO = 0; #ifdef QSG_SEPARATE_INDEX_BUFFER int largestIBO = 0; @@ -2660,6 +2673,8 @@ void Renderer::render() #endif uploadBatch(b); } + if (Q_UNLIKELY(debug_render())) timeUploadOpaque = timer.restart(); + if (Q_UNLIKELY(debug_upload())) qDebug() << "Uploading Alpha Batches:"; for (int i=0; i<m_alphaBatches.size(); ++i) { @@ -2670,6 +2685,7 @@ void Renderer::render() largestIBO = qMax(b->ibo.size, largestIBO); #endif } + if (Q_UNLIKELY(debug_render())) timeUploadAlpha = timer.restart(); if (largestVBO * 2 < m_vertexUploadPool.size()) m_vertexUploadPool.resize(largestVBO * 2); @@ -2680,6 +2696,15 @@ void Renderer::render() renderBatches(); + if (Q_UNLIKELY(debug_render())) { + qDebug(" -> times: build: %d, prepare(opaque/alpha): %d/%d, sorting: %d, upload(opaque/alpha): %d/%d, render: %d", + (int) timeRenderLists, + (int) timePrepareOpaque, (int) timePrepareAlpha, + (int) timeSorting, + (int) timeUploadOpaque, (int) timeUploadAlpha, + (int) timer.elapsed()); + } + m_rebuild = 0; m_renderOrderRebuildLower = -1; m_renderOrderRebuildUpper = -1; diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index 6b494dbaeb..8cd9e7e3ff 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -34,6 +34,17 @@ #ifndef QSGBATCHRENDERER_P_H #define QSGBATCHRENDERER_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include <private/qsgrenderer_p.h> #include <private/qsgnodeupdater_p.h> #include <private/qdatabuffer_p.h> @@ -100,6 +111,7 @@ template <typename Type, int PageSize> class Allocator { public: Allocator() + : m_freePage(0) { pages.push_back(new AllocatorPage<Type, PageSize>()); } @@ -112,14 +124,21 @@ public: Type *allocate() { AllocatorPage<Type, PageSize> *p = 0; - for (int i=0; i<pages.size(); ++i) { + for (int i = m_freePage; i < pages.size(); i++) { if (pages.at(i)->available > 0) { p = pages.at(i); + m_freePage = i; break; } } + + // we couldn't find a free page from m_freePage to the last page. + // either there is no free pages, or there weren't any in the area we + // scanned: rescanning is expensive, so let's just assume there isn't + // one. when an item is released, we'll reset m_freePage anyway. if (!p) { p = new AllocatorPage<Type, PageSize>(); + m_freePage = pages.count(); pages.push_back(p); } uint pos = p->blocks[PageSize - p->available]; @@ -151,6 +170,9 @@ public: delete page; page = pages.back(); } + + // Reset the free page to force a scan for a new free point. + m_freePage = 0; } void release(Type *t) @@ -172,6 +194,7 @@ public: } QVector<AllocatorPage<Type, PageSize> *> pages; + int m_freePage; }; @@ -500,8 +523,8 @@ public: ShaderManager(QSGRenderContext *ctx) : blitProgram(0), visualizeProgram(0), context(ctx) { } ~ShaderManager() { - qDeleteAll(rewrittenShaders.values()); - qDeleteAll(stockShaders.values()); + qDeleteAll(rewrittenShaders); + qDeleteAll(stockShaders); } public Q_SLOTS: @@ -534,8 +557,8 @@ public: }; protected: - void nodeChanged(QSGNode *node, QSGNode::DirtyState state); - void render(); + void nodeChanged(QSGNode *node, QSGNode::DirtyState state) Q_DECL_OVERRIDE; + void render() Q_DECL_OVERRIDE; private: enum ClipTypeBit @@ -604,7 +627,7 @@ private: void visualizeOverdraw(); void visualizeOverdraw_helper(Node *node); void visualizeDrawGeometry(const QSGGeometry *g); - void setCustomRenderMode(const QByteArray &mode); + void setCustomRenderMode(const QByteArray &mode) Q_DECL_OVERRIDE; QSet<Node *> m_taggedRoots; QDataBuffer<Element *> m_opaqueRenderList; diff --git a/src/quick/scenegraph/coreapi/qsggeometry_p.h b/src/quick/scenegraph/coreapi/qsggeometry_p.h index c52a45b25b..152fcb3427 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry_p.h +++ b/src/quick/scenegraph/coreapi/qsggeometry_p.h @@ -34,6 +34,17 @@ #ifndef QSGGEOMETRY_P_H #define QSGGEOMETRY_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "qsggeometry.h" QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp index 367c0b1ee5..5fb0a9867e 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp @@ -64,7 +64,7 @@ const char *QSGMaterialShaderPrivate::loadShaderSource(QOpenGLShader::ShaderType } #ifndef QT_NO_DEBUG -static bool qsg_leak_check = !qgetenv("QML_LEAK_CHECK").isEmpty(); +static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK"); #endif /*! diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h b/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h index fab6d00f84..6b31e406ca 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h +++ b/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h @@ -34,6 +34,17 @@ #ifndef QSGMATERIALSHADER_P_H #define QSGMATERIALSHADER_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include <private/qtquickglobal_p.h> #include <QOpenGLShader> diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp index 51f3976ed9..c09af7c0a3 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.cpp +++ b/src/quick/scenegraph/coreapi/qsgnode.cpp @@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_DEBUG -static bool qsg_leak_check = !qgetenv("QML_LEAK_CHECK").isEmpty(); +static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK"); static int qt_node_count = 0; static void qt_print_node_count() diff --git a/src/quick/scenegraph/coreapi/qsgnode_p.h b/src/quick/scenegraph/coreapi/qsgnode_p.h index c455e342c8..7fbb65ef81 100644 --- a/src/quick/scenegraph/coreapi/qsgnode_p.h +++ b/src/quick/scenegraph/coreapi/qsgnode_p.h @@ -34,6 +34,17 @@ #ifndef QSGNODE_P_H #define QSGNODE_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include <qglobal.h> #include "qsgnode.h" diff --git a/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp b/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp index 8293c106b5..f7c9fe7fae 100644 --- a/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp +++ b/src/quick/scenegraph/coreapi/qsgnodeupdater.cpp @@ -63,24 +63,6 @@ void QSGNodeUpdater::updateStates(QSGNode *n) visitNode(n); } -/*! - \fn void QSGNodeUpdater::setToplevelOpacity(qreal opacity) - - Sets the toplevel opacity that will be multiplied with the - - The default opacity is 1. Any other value will cause artifacts, and is - primarily useful for debug purposes. - - The changing the value during an update pass will have undefined results - */ - -/*! - \fn qreal QSGNodeUpdater::toplevelOpacity() const - - Returns the toplevel opacity for the node updater. The default - value is 1. - */ - /*! Returns true if \a node is has something that blocks it in the chain from diff --git a/src/quick/scenegraph/coreapi/qsgnodeupdater_p.h b/src/quick/scenegraph/coreapi/qsgnodeupdater_p.h index e578586a19..2e408d0dbe 100644 --- a/src/quick/scenegraph/coreapi/qsgnodeupdater_p.h +++ b/src/quick/scenegraph/coreapi/qsgnodeupdater_p.h @@ -34,6 +34,17 @@ #ifndef QSGNODEUPDATER_P_H #define QSGNODEUPDATER_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include <private/qtquickglobal_p.h> #include <QtGui/private/qdatabuffer_p.h> diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index a9752cb9a9..775277e588 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -40,12 +40,21 @@ QT_BEGIN_NAMESPACE -static bool qsg_sanity_check = qgetenv("QSG_SANITY_CHECK").toInt(); +static const bool qsg_sanity_check = qEnvironmentVariableIntValue("QSG_SANITY_CHECK"); static QElapsedTimer frameTimer; static qint64 preprocessTime; static qint64 updatePassTime; +int qt_sg_envInt(const char *name, int defaultValue) +{ + if (Q_LIKELY(!qEnvironmentVariableIsSet(name))) + return defaultValue; + bool ok = false; + int value = qgetenv(name).toInt(&ok); + return ok ? value : defaultValue; +} + void QSGBindable::clear(QSGAbstractRenderer::ClearMode mode) const { GLuint bits = 0; diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h index 7e4d52730a..319d0a46b6 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h @@ -34,6 +34,17 @@ #ifndef QSGRENDERER_P_H #define QSGRENDERER_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "qsgabstractrenderer.h" #include "qsgabstractrenderer_p.h" #include "qsgnode.h" |