1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-06 00:55:50 +00:00

avoids memory allocations within ComputeLightSpaceBounds (#3156)

Currently, we create a new ComputeLightSpaceBounds visitor per frame. Within this visitor, we require excessive memory allocations, mainly a new osg::RefMatrix per encountered Transform node.

With this PR we reuse a single ComputeLightSpaceBounds visitor across frames and enable the createOrReuseMatrix functionality to avoid allocating new matrices every frame. osgUtil::CullVisitor internally uses the same approach.
This commit is contained in:
Bo Svensson 2021-10-08 07:56:55 +00:00 committed by GitHub
parent 9c47fdcf7e
commit 5242e2695c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 9 deletions

View File

@ -353,18 +353,20 @@ void VDSMCameraCullCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
} // namespace
MWShadowTechnique::ComputeLightSpaceBounds::ComputeLightSpaceBounds(osg::Viewport* viewport, const osg::Matrixd& projectionMatrix, osg::Matrixd& viewMatrix) :
MWShadowTechnique::ComputeLightSpaceBounds::ComputeLightSpaceBounds() :
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN)
{
setCullingMode(osg::CullSettings::VIEW_FRUSTUM_CULLING);
pushViewport(viewport);
pushProjectionMatrix(new osg::RefMatrix(projectionMatrix));
pushModelViewMatrix(new osg::RefMatrix(viewMatrix), osg::Transform::ABSOLUTE_RF);
setName("SceneUtil::MWShadowTechnique::ComputeLightSpaceBounds,AcceptedByComponentsTerrainQuadTreeWorld");
}
void MWShadowTechnique::ComputeLightSpaceBounds::reset()
{
osg::CullStack::reset();
_bb = osg::BoundingBox();
}
void MWShadowTechnique::ComputeLightSpaceBounds::apply(osg::Node& node)
{
if (isCulled(node)) return;
@ -421,9 +423,9 @@ void MWShadowTechnique::ComputeLightSpaceBounds::apply(osg::Transform& transform
// absolute transforms won't affect a shadow map so their subgraphs should be ignored.
if (transform.getReferenceFrame() == osg::Transform::RELATIVE_RF)
{
osg::ref_ptr<osg::RefMatrix> matrix = new osg::RefMatrix(*getModelViewMatrix());
osg::RefMatrix* matrix = createOrReuseMatrix(*getModelViewMatrix());
transform.computeLocalToWorldMatrix(*matrix, this);
pushModelViewMatrix(matrix.get(), transform.getReferenceFrame());
pushModelViewMatrix(matrix, transform.getReferenceFrame());
traverse(transform);
@ -1125,7 +1127,12 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
// osg::ElapsedTime timer;
osg::ref_ptr<osg::Viewport> viewport = new osg::Viewport(0,0,2048,2048);
ComputeLightSpaceBounds clsb(viewport.get(), projectionMatrix, viewMatrix);
if (!_clsb) _clsb = new ComputeLightSpaceBounds;
ComputeLightSpaceBounds& clsb = *_clsb;
clsb.reset();
clsb.pushViewport(viewport);
clsb.pushProjectionMatrix(new osg::RefMatrix(projectionMatrix));
clsb.pushModelViewMatrix(new osg::RefMatrix(viewMatrix), osg::Transform::ABSOLUTE_RF);
clsb.setTraversalMask(_shadowedScene->getCastsShadowTraversalMask());
osg::Matrixd invertModelView;
@ -1139,6 +1146,12 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
_shadowedScene->accept(clsb);
clsb.popCullingSet();
clsb.popModelViewMatrix();
clsb.popProjectionMatrix();
clsb.popViewport();
// OSG_NOTICE<<"Extents of LightSpace "<<clsb._bb.xMin()<<", "<<clsb._bb.xMax()<<", "<<clsb._bb.yMin()<<", "<<clsb._bb.yMax()<<", "<<clsb._bb.zMin()<<", "<<clsb._bb.zMax()<<std::endl;
// OSG_NOTICE<<" time "<<timer.elapsedTime_m()<<"ms, mask = "<<std::hex<<_shadowedScene->getCastsShadowTraversalMask()<<std::endl;

View File

@ -90,7 +90,7 @@ namespace SceneUtil {
class ComputeLightSpaceBounds : public osg::NodeVisitor, public osg::CullStack
{
public:
ComputeLightSpaceBounds(osg::Viewport* viewport, const osg::Matrixd& projectionMatrix, osg::Matrixd& viewMatrix);
ComputeLightSpaceBounds();
void apply(osg::Node& node) override;
@ -112,6 +112,8 @@ namespace SceneUtil {
void update(const osg::Vec3& v);
void reset() override;
osg::BoundingBox _bb;
};
@ -238,6 +240,8 @@ namespace SceneUtil {
protected:
virtual ~MWShadowTechnique();
osg::ref_ptr<ComputeLightSpaceBounds> _clsb;
typedef std::map< osgUtil::CullVisitor*, osg::ref_ptr<ViewDependentData> > ViewDependentDataMap;
mutable std::mutex _viewDependentDataMapMutex;
ViewDependentDataMap _viewDependentDataMap;