diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2020-05-20 14:33:50 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2020-06-16 07:11:43 +0200 |
commit | a26f9042043b3b5a3ebbdd8f4b7cf277f9210de1 (patch) | |
tree | f308394d00d8d124bd16a06c6b7bb405647c6d6a | |
parent | 9d6cc0f7ecafde186ec729f44dd412be3c845638 (diff) |
Speed up rendering huge static scenes
With really big, static scenes, traversal of the geometry list
is expensive enough that it becomes a limitation on the frame
rate if we do it in the inner loop of every frame. And going
through the whole list of geometry every frame just to verify
that nothing has been removed is a waste of time.
In a test with two million opaque items in a single draw call,
I can hit 144 fps with this small optimization versus 50 fps
on the same machine without the patch.
Change-Id: Id11c1d96456e79a62c33b89e5f115bdaacceeacd
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
(cherry picked from commit a8d357761dbf74cbdc72348be6c655cafb745ff2)
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 10 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h | 2 |
2 files changed, 11 insertions, 1 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index ce3c4aac4f..a74e82b1bd 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -859,6 +859,9 @@ bool Batch::geometryWasChanged(QSGGeometryNode *gn) void Batch::cleanupRemovedElements() { + if (!needsPurge) + return; + // remove from front of batch.. while (first && first->removed) { first = first->nextInBatch; @@ -875,6 +878,8 @@ void Batch::cleanupRemovedElements() } } + + needsPurge = false; } /* @@ -1379,6 +1384,7 @@ void Renderer::nodeWasRemoved(Node *node) } if (e->batch) { e->batch->needsUpload = true; + e->batch->needsPurge = true; } } @@ -1400,7 +1406,6 @@ void Renderer::nodeWasRemoved(Node *node) if (e) { e->removed = true; m_elementsToDelete.add(e); - if (m_renderNodeElements.isEmpty()) { static const bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); if (m_rhi) @@ -1408,6 +1413,9 @@ void Renderer::nodeWasRemoved(Node *node) else m_useDepthBuffer = useDepth && m_context->openglContext()->format().depthBufferSize() > 0; } + + if (e->batch != nullptr) + e->batch->needsPurge = true; } } diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index 878b63fc8c..a6c5e615ba 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -463,6 +463,7 @@ struct Batch uploadedThisFrame = false; isRenderNode = false; ubufDataValid = false; + needsPurge = false; clipState.reset(); blendConstant = QColor(); } @@ -482,6 +483,7 @@ struct Batch uint merged : 1; uint isRenderNode : 1; uint ubufDataValid : 1; + uint needsPurge : 1; mutable uint uploadedThisFrame : 1; // solely for debugging purposes |