Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimizations for selection performance #1419

Merged
merged 1 commit into from
Sep 11, 2016

Conversation

ericwa
Copy link
Collaborator

@ericwa ericwa commented Aug 19, 2016

I was messing around with #1404 a bit, tried some micro-optimization and got MapView3D::doRenderMap about 33% faster when making a selection on a large map.

IMO there are two approaches to improving the selection performance:

  1. "proper" ones, involving trying to rendering only the changed parts of the map, using arguments of functions likeMapRenderer::selectionDidChange. (or partitioning the brushes into subsets, and only re-rendering the subsets containing the brushes that changed selection state). As you were saying in Selection performance on large maps #1404 , re-rendering only the exact set of changed brushes would interfere with OpenGL batching. It might be a performance win overall to forget about OpenGL batching.
  2. micro-optimizing the current code, this is what I tried in this PR. What I noticed was a lot of stuff was being recomputed per-edge and per-face that only needed to be evaluated per-brush.

The code is certainly uglier with this change.. personally I'm not sure it's worth 33% better performance ;)

In particular, in the doCollectShownFaces implementations in MapRenderer.cpp I inlined some bits of code from EditorContext. e.g. replacing per-face calls to visible(const Model::BrushFace* face) with checking visible(brush) once, and using that, since the implementation of visible(const Model::BrushFace* face) is:

bool EditorContext::visible(const Model::BrushFace* face) const {
            return visible(face->brush());
        }

That's the worst thing.

Also, the CollectShownFaces/CollectShownEdges classes could be replaced with C++11 lambdas when TB switches to C++11.

Focusing on reducing recomputation in Filter
(e.g. reduce number of calls to EditorContext::visible(const Model::Brush* brush) )

MapView3D::doRenderMap is about 33% faster when making a selection on a large map.
@ericwa
Copy link
Collaborator Author

ericwa commented Aug 19, 2016

btw, this was my benchmarking code:

diff --git a/common/src/View/MapView3D.cpp b/common/src/View/MapView3D.cpp
index ad45adf..5256852 100644
--- a/common/src/View/MapView3D.cpp
+++ b/common/src/View/MapView3D.cpp
@@ -566,8 +566,13 @@ namespace TrenchBroom {
         void MapView3D::doRenderGrid(Renderer::RenderContext& renderContext, Renderer::RenderBatch& renderBatch) {}

         void MapView3D::doRenderMap(Renderer::MapRenderer& renderer, Renderer::RenderContext& renderContext, Renderer::RenderBatch& renderBatch) {
+            wxMilliClock_t start = wxGetLocalTimeMillis();
+            
             renderer.render(renderContext, renderBatch);

+            wxMilliClock_t end = wxGetLocalTimeMillis();
+            printf("MapView3D::doRenderMap took %d ms\n", (int)wxMilliClockToLong(end - start));
+            
             MapDocumentSPtr document = lock(m_document);
             if (renderContext.showSelectionGuide() && document->hasSelectedNodes()) {
                 const BBox3& bounds = document->selectionBounds();

@kduske
Copy link
Collaborator

kduske commented Aug 19, 2016

Alright, will have a look soon. One thing though, can you please make sure that face selection still works, esp. with the correct edges being shown as selected? Because that might be affected by this change.

@ericwa
Copy link
Collaborator Author

ericwa commented Aug 20, 2016

I'm away from my PC for a few days, but will check on Wednesday

@ericwa
Copy link
Collaborator Author

ericwa commented Aug 24, 2016

Face selection (including rendering of selected edges) still looks correct with this.

@kduske
Copy link
Collaborator

kduske commented Aug 24, 2016

Excellent, thanks.

@kduske kduske added Type:Enhancement New features Platform:All Prio:3 Low priority: Minor problems and nice to have features Prio:2 Medium priority: Non crash bugs that impede the user, features that add new functionality. and removed Prio:3 Low priority: Minor problems and nice to have features labels Sep 10, 2016
@kduske kduske added this to the TrenchBroom 2.0.0 milestone Sep 10, 2016
@kduske kduske self-assigned this Sep 10, 2016
@kduske kduske merged commit 847a787 into TrenchBroom:release/v2.0.0 Sep 11, 2016
kduske added a commit that referenced this pull request Sep 11, 2016
kduske added a commit that referenced this pull request Sep 11, 2016
kduske added a commit that referenced this pull request Sep 11, 2016
@kduske
Copy link
Collaborator

kduske commented Sep 11, 2016

The code is actually not ugly, but the control flow is a bit murky. I have mostly changed the names of the new classes / methods to reflect the new provider / acceptor nature of the control flow. Thanks for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Prio:2 Medium priority: Non crash bugs that impede the user, features that add new functionality. Type:Enhancement New features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants