mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +00:00
refactors hashed std::map (#3199)
We currently apply a strange algorithm to `LightManager::mStateSetCache`. For some reason this algorithm inserts hashed keys into `std::map` in a way that fails to handle hash collisions and exhibits worse lookup complexity than `std::unordered_map`. With this PR we just use `std::unordered_map` here.
This commit is contained in:
parent
3042c000c6
commit
1979ee1491
2 changed files with 33 additions and 17 deletions
|
@ -1,6 +1,8 @@
|
|||
#include "lightmanager.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <osg/BufferObject>
|
||||
#include <osg/BufferIndexBinding>
|
||||
|
@ -1158,29 +1160,39 @@ namespace SceneUtil
|
|||
return mSun;
|
||||
}
|
||||
|
||||
size_t LightManager::HashLightIdList::operator()(const LightIdList& lightIdList) const
|
||||
{
|
||||
size_t hash = 0;
|
||||
for (size_t i = 0; i < lightIdList.size(); ++i)
|
||||
Misc::hashCombine(hash, lightIdList[i]);
|
||||
return hash;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::StateSet> LightManager::getLightListStateSet(const LightList& lightList, size_t frameNum, const osg::RefMatrix* viewMatrix)
|
||||
{
|
||||
// possible optimization: return a StateSet containing all requested lights plus some extra lights (if a suitable one exists)
|
||||
size_t hash = 0;
|
||||
for (size_t i = 0; i < lightList.size(); ++i)
|
||||
|
||||
if (getLightingMethod() == LightingMethod::SingleUBO)
|
||||
{
|
||||
auto id = lightList[i]->mLightSource->getId();
|
||||
Misc::hashCombine(hash, id);
|
||||
for (size_t i = 0; i < lightList.size(); ++i)
|
||||
{
|
||||
auto id = lightList[i]->mLightSource->getId();
|
||||
if (getLightIndexMap(frameNum).find(id) != getLightIndexMap(frameNum).end())
|
||||
continue;
|
||||
|
||||
if (getLightingMethod() != LightingMethod::SingleUBO)
|
||||
continue;
|
||||
|
||||
if (getLightIndexMap(frameNum).find(id) != getLightIndexMap(frameNum).end())
|
||||
continue;
|
||||
|
||||
int index = getLightIndexMap(frameNum).size() + 1;
|
||||
updateGPUPointLight(index, lightList[i]->mLightSource, frameNum, viewMatrix);
|
||||
getLightIndexMap(frameNum).emplace(lightList[i]->mLightSource->getId(), index);
|
||||
int index = getLightIndexMap(frameNum).size() + 1;
|
||||
updateGPUPointLight(index, lightList[i]->mLightSource, frameNum, viewMatrix);
|
||||
getLightIndexMap(frameNum).emplace(id, index);
|
||||
}
|
||||
}
|
||||
|
||||
auto& stateSetCache = mStateSetCache[frameNum%2];
|
||||
|
||||
auto found = stateSetCache.find(hash);
|
||||
LightIdList lightIdList;
|
||||
lightIdList.reserve(lightList.size());
|
||||
std::transform(lightList.begin(), lightList.end(), std::back_inserter(lightIdList), [] (const LightSourceViewBound* l) { return l->mLightSource->getId(); });
|
||||
|
||||
auto found = stateSetCache.find(lightIdList);
|
||||
if (found != stateSetCache.end())
|
||||
{
|
||||
mStateSetGenerator->update(found->second, lightList, frameNum);
|
||||
|
@ -1188,7 +1200,7 @@ namespace SceneUtil
|
|||
}
|
||||
|
||||
auto stateset = mStateSetGenerator->generate(lightList, frameNum);
|
||||
stateSetCache.emplace(hash, stateset);
|
||||
stateSetCache.emplace(lightIdList, stateset);
|
||||
return stateset;
|
||||
}
|
||||
|
||||
|
|
|
@ -207,8 +207,12 @@ namespace SceneUtil
|
|||
using LightSourceViewBoundCollection = std::vector<LightSourceViewBound>;
|
||||
std::map<osg::observer_ptr<osg::Camera>, LightSourceViewBoundCollection> mLightsInViewSpace;
|
||||
|
||||
// < Light list hash , StateSet >
|
||||
using LightStateSetMap = std::map<size_t, osg::ref_ptr<osg::StateSet>>;
|
||||
using LightIdList = std::vector<int>;
|
||||
struct HashLightIdList
|
||||
{
|
||||
size_t operator()(const LightIdList&) const;
|
||||
};
|
||||
using LightStateSetMap = std::unordered_map<LightIdList, osg::ref_ptr<osg::StateSet>, HashLightIdList>;
|
||||
LightStateSetMap mStateSetCache[2];
|
||||
|
||||
std::vector<osg::ref_ptr<osg::StateAttribute>> mDummies;
|
||||
|
|
Loading…
Reference in a new issue