]> git.tdb.fi Git - libs/gl.git/commitdiff
Use a sorted vector in place of set for small data
authorMikko Rasa <tdb@tdb.fi>
Sat, 30 Oct 2021 19:07:48 +0000 (22:07 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 30 Oct 2021 22:28:12 +0000 (01:28 +0300)
Despite having worse algorithmic performance, cache effects make the
vector faster for total data size of up to about 8 kB (YMMV).

The GLSL compiler can keep its sets for now, I'll create a proper class
for this at some point.

source/effects/effect.cpp
source/effects/effect.h
source/effects/environmentmap.cpp
source/effects/shadowmap.cpp
source/effects/sky.cpp
source/render/occludedscene.cpp
source/render/occludedscene.h
source/render/simplescene.cpp
source/render/simplescene.h
source/render/zsortedscene.cpp
source/render/zsortedscene.h

index 05ef5a10f1c2acee31f801053ffe94fc50259d5a..e59aeed8e039dcbc352d6daf6904a3b44eacaa06 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/core/algorithm.h>
 #include "effect.h"
 
 namespace Msp {
@@ -6,17 +7,27 @@ namespace GL {
 Effect::Effect(Renderable &r):
        renderable(r)
 {
-       enabled_methods.insert(Tag());
+       enable_for_method(Tag());
 }
 
 void Effect::enable_for_method(Tag tag)
 {
-       enabled_methods.insert(tag);
+       auto i = lower_bound(enabled_methods, tag);
+       if(i==enabled_methods.end() || *i!=tag)
+               enabled_methods.insert(i, tag);
 }
 
 void Effect::disable_for_method(Tag tag)
 {
-       enabled_methods.erase(tag);
+       auto i = lower_bound(enabled_methods, tag);
+       if(i!=enabled_methods.end() && *i==tag)
+               enabled_methods.erase(i);
+}
+
+bool Effect::is_enabled_for_method(Tag tag) const
+{
+       auto i = lower_bound(enabled_methods, tag);
+       return (i!=enabled_methods.end() && *i==tag);
 }
 
 
index eadb4dc845984a3d8e04d83e93d6a819df81bdf0..0d794a3a2d9b6b264b17e880cf0a02c95d8218d7 100644 (file)
@@ -35,7 +35,7 @@ public:
 
 protected:
        Renderable &renderable;
-       std::set<Tag> enabled_methods;
+       std::vector<Tag> enabled_methods;
 
 protected:
        Effect(Renderable &);
@@ -44,6 +44,7 @@ public:
 
        void enable_for_method(Tag);
        void disable_for_method(Tag);
+       bool is_enabled_for_method(Tag) const;
 
        virtual const Matrix *get_matrix() const { return renderable.get_matrix(); }
        virtual const Geometry::BoundingSphere<float, 3> *get_bounding_sphere() const { return renderable.get_bounding_sphere(); }
index b9a7124ccd93f786b7e03d816184d483f7de18ec..b1a50ecc720df131be3226e96cd59b3384680e85 100644 (file)
@@ -169,7 +169,7 @@ void EnvironmentMap::render(Renderer &renderer, Tag tag) const
 {
        if(in_setup_frame)
                return;
-       if(!enabled_methods.count(tag))
+       if(!is_enabled_for_method(tag))
                return renderable.render(renderer, tag);
 
        Renderer::Push _push_rend(renderer);
index 55da7301803f76f9aef0a44cf625aa20e728399f..6b926dd897355b68b461299bb6f070207c552d86 100644 (file)
@@ -250,7 +250,7 @@ void ShadowMap::finish_frame()
 
 void ShadowMap::render(Renderer &renderer, Tag tag) const
 {
-       if(!enabled_methods.count(tag))
+       if(!is_enabled_for_method(tag))
                return renderable.render(renderer, tag);
 
        Renderer::Push _push_rend(renderer);
index ab322f230e34365e6363c3ea9c867b2be251d79c..0744e7b9adaacda6b02be7cfaf775e9a53e97600 100644 (file)
@@ -132,7 +132,7 @@ void Sky::render(Renderer &renderer, Tag tag) const
 {
        renderable.render(renderer, tag);
 
-       if(!enabled_methods.count(tag))
+       if(!is_enabled_for_method(tag))
                return;
 
        Renderer::Push push(renderer);
index 5d85b5d5bf762d43f056d114e383cd613ef67198..bfe17349fd13ee836234c9297ec5476e6039d9f7 100644 (file)
@@ -1,4 +1,4 @@
-#include <algorithm>
+#include <msp/core/algorithm.h>
 #include "camera.h"
 #include "mesh.h"
 #include "occludedscene.h"
@@ -21,14 +21,22 @@ OccludedScene::OccludedScene():
 
 void OccludedScene::add(Renderable &r)
 {
-       renderables.insert(&r);
-       cache_dirty = true;
+       auto i = lower_bound(renderables, &r);
+       if(i==renderables.end() || *i!=&r)
+       {
+               renderables.insert(i, &r);
+               cache_dirty = true;
+       }
 }
 
 void OccludedScene::remove(Renderable &r)
 {
-       renderables.erase(&r);
-       cache_dirty = true;
+       auto i = lower_bound(renderables, &r);
+       if(i!=renderables.end() && *i==&r)
+       {
+               renderables.erase(i);
+               cache_dirty = true;
+       }
 }
 
 void OccludedScene::populate_cache() const
index 6efb354e37706cdcf4bece658678638f28f382ff..4d56db7a1ff6c565585a2dbd7d006a206d6c46d0 100644 (file)
@@ -36,7 +36,7 @@ private:
        const Program &bounding_shader;
        Blend no_color_write;
        DepthTest no_depth_write = { LEQUAL, false };
-       std::set<Renderable *> renderables;
+       std::vector<Renderable *> renderables;
        float occluder_min_size = 0.25f;
        mutable QueryPool queries;
        mutable std::vector<OccludedRenderable> occluded_cache;
index 4ddbeca6732d78a90695cb76833ae8b8b2dd037c..fbdb004f9a0e8f8917b5ae42a8a2554d84b54d22 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/core/algorithm.h>
 #include "renderer.h"
 #include "simplescene.h"
 
@@ -6,51 +7,41 @@ namespace GL {
 
 void SimpleScene::add(Renderable &r)
 {
-       // Add to cache as well if the cache is valid
-       if(renderables.insert(&r).second && !cache.empty())
-               cache.push_back(&r);
+       auto i = lower_bound(renderables, &r);
+       if(i==renderables.end() || *i!=&r)
+               renderables.insert(i, &r);
 }
 
 void SimpleScene::remove(Renderable &r)
 {
-       renderables.erase(&r);
-       cache.clear();
-}
-
-void SimpleScene::populate_cache() const
-{
-       if(cache.empty() && !renderables.empty())
-       {
-               cache.reserve(renderables.size());
-               cache.insert(cache.end(), renderables.begin(), renderables.end());
-       }
+       auto i = find(renderables, &r);
+       if(i!=renderables.end())
+               renderables.erase(i);
 }
 
 void SimpleScene::setup_frame(Renderer &renderer)
 {
-       populate_cache();
-       for(Renderable *r: cache)
+       for(Renderable *r: renderables)
                r->setup_frame(renderer);
 }
 
 void SimpleScene::finish_frame()
 {
-       for(Renderable *r: cache)
+       for(Renderable *r: renderables)
                r->finish_frame();
 }
 
 void SimpleScene::render(Renderer &renderer, Tag tag) const
 {
-       populate_cache();
        if(setup_frustum(renderer))
        {
-               for(Renderable *r: cache)
+               for(Renderable *r: renderables)
                        if(!frustum_cull(*r))
                                r->render(renderer, tag);
        }
        else
        {
-               for(Renderable *r: cache)
+               for(Renderable *r: renderables)
                        r->render(renderer, tag);
        }
 }
index 1e90874b9e1ab6fa682ab385a48e4a37e629e9b1..ccca360a5c1275f44aedc897ed6f097dd38f68c0 100644 (file)
@@ -16,17 +16,12 @@ public:
        using Scene::Loader;
 
 private:
-       std::set<Renderable *> renderables;
-       mutable std::vector<Renderable *> cache;
+       std::vector<Renderable *> renderables;
 
 public:
        virtual void add(Renderable &);
        virtual void remove(Renderable &);
 
-private:
-       void populate_cache() const;
-
-public:
        virtual void setup_frame(Renderer &);
        virtual void finish_frame();
 
index dd5f1f3ac701f727cd81b67b44f153eaa99d6282..af3c5b86140823968a12cc19cf36a747fe3b5c1c 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/core/algorithm.h>
 #include "camera.h"
 #include "renderer.h"
 #include "zsortedscene.h"
@@ -9,14 +10,23 @@ namespace GL {
 
 void ZSortedScene::add(Renderable &r)
 {
-       if(renderables.insert(&r).second && !sorted_cache.empty())
-               sorted_cache.push_back(&r);
+       auto i = lower_bound(renderables, &r);
+       if(i==renderables.end() || *i!=&r)
+       {
+               renderables.insert(i, &r);
+               if(!sorted_cache.empty())
+                       sorted_cache.push_back(&r);
+       }
 }
 
 void ZSortedScene::remove(Renderable &r)
 {
-       renderables.erase(&r);
-       sorted_cache.clear();
+       auto i = lower_bound(renderables, &r);
+       if(i!=renderables.end() && *i==&r)
+       {
+               renderables.erase(i);
+               sorted_cache.clear();
+       }
 }
 
 void ZSortedScene::set_order(SortOrder o)
index f268f5297e3b279e064173c71f938494ade5431a..749a97052e8010ad8097e0fcc5f2034d019a6341 100644 (file)
@@ -42,7 +42,7 @@ private:
                bool operator<(const SortedRenderable &o) const { return depth<o.depth; }
        };
 
-       std::set<Renderable *> renderables;
+       std::vector<Renderable *> renderables;
        SortOrder order = BACK_TO_FRONT;
        DepthReference reference = FURTHEST;
        mutable std::vector<SortedRenderable> sorted_cache;