From a26f9042043b3b5a3ebbdd8f4b7cf277f9210de1 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 20 May 2020 14:33:50 +0200 Subject: 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 (cherry picked from commit a8d357761dbf74cbdc72348be6c655cafb745ff2) --- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 10 +++++++++- src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) 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 -- cgit v1.2.3