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:
parent
9c47fdcf7e
commit
5242e2695c
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user