Began work on providing support for threading camera cull traversals in parallel with
the previous frames draw traversal. Changes range from osg::State, through osgUtil::RenderBin, through to osgViewer
This commit is contained in:
@@ -753,6 +753,47 @@ class OSG_EXPORT State : public Referenced
|
||||
* if true steps should be taken to complete rendering early.*/
|
||||
bool getAbortRendering() const { return _abortRenderingPtr!=0?(*_abortRenderingPtr):false; }
|
||||
|
||||
|
||||
struct DynamicObjectRenderingCompletedCallback : public osg::Referenced
|
||||
{
|
||||
virtual void completed(osg::State*) = 0;
|
||||
};
|
||||
|
||||
/** Set the callback to be called when the dynamic object count hits 0.*/
|
||||
void setDynamicObjectRenderingCompletedCallback(DynamicObjectRenderingCompletedCallback* cb){ _completeDynamicObjectRenderingCallback = cb; }
|
||||
|
||||
/** Get the callback to be called when the dynamic object count hits 0.*/
|
||||
DynamicObjectRenderingCompletedCallback* getDynamicObjectRenderingCompletedCallback() { return _completeDynamicObjectRenderingCallback.get(); }
|
||||
|
||||
/** Set the number of dynamic objects that will be rendered in this graphics context this frame.*/
|
||||
void setDynamicObjectCount(unsigned int count, bool callCallbackOnZero = false)
|
||||
{
|
||||
if (_dynamicObjectCount != count)
|
||||
{
|
||||
_dynamicObjectCount = count;
|
||||
if (_dynamicObjectCount==0 && callCallbackOnZero && _completeDynamicObjectRenderingCallback.valid())
|
||||
{
|
||||
_completeDynamicObjectRenderingCallback->completed(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the number of dynamic objects that will be rendered in this graphics context this frame.*/
|
||||
unsigned int getDynamicObjectCount() const { return _dynamicObjectCount; }
|
||||
|
||||
/** Decrement the number of dynamic objects left to render this frame, and once the count goes to zero call the
|
||||
* DynamicObjectRenderingCompletedCallback to inform of completion.*/
|
||||
inline void decrementDynamicObjectCount()
|
||||
{
|
||||
--_dynamicObjectCount;
|
||||
if (_dynamicObjectCount==0 && _completeDynamicObjectRenderingCallback.valid())
|
||||
{
|
||||
_completeDynamicObjectRenderingCallback->completed(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum CheckForGLErrors
|
||||
{
|
||||
/** NEVER_CHECK_GL_ERRORS hints that OpenGL need not be checked for, this
|
||||
@@ -1028,6 +1069,9 @@ class OSG_EXPORT State : public Referenced
|
||||
DisableVertexAttribProc _glDisableVertexAttribArray;
|
||||
void initializeExtensionProcs();
|
||||
|
||||
unsigned int _dynamicObjectCount;
|
||||
osg::ref_ptr<DynamicObjectRenderingCompletedCallback> _completeDynamicObjectRenderingCallback;
|
||||
|
||||
};
|
||||
|
||||
inline void State::pushModeList(ModeMap& modeMap,const StateSet::ModeList& modeList)
|
||||
|
||||
@@ -82,6 +82,7 @@ class OSGUTIL_EXPORT Optimizer
|
||||
MERGE_GEODES = 0x1000,
|
||||
FLATTEN_BILLBOARDS = 0x2000,
|
||||
TEXTURE_ATLAS_BUILDER = 0x4000,
|
||||
STATIC_OBJECT_DETECTION = 0x8000,
|
||||
DEFAULT_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS |
|
||||
REMOVE_REDUNDANT_NODES |
|
||||
REMOVE_LOADED_PROXY_NODES |
|
||||
@@ -89,7 +90,8 @@ class OSGUTIL_EXPORT Optimizer
|
||||
SHARE_DUPLICATE_STATE |
|
||||
MERGE_GEOMETRY |
|
||||
CHECK_GEOMETRY |
|
||||
OPTIMIZE_TEXTURE_SETTINGS,
|
||||
OPTIMIZE_TEXTURE_SETTINGS |
|
||||
STATIC_OBJECT_DETECTION,
|
||||
ALL_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS |
|
||||
REMOVE_REDUNDANT_NODES |
|
||||
REMOVE_LOADED_PROXY_NODES |
|
||||
@@ -102,7 +104,8 @@ class OSGUTIL_EXPORT Optimizer
|
||||
COPY_SHARED_NODES |
|
||||
TRISTRIP_GEOMETRY |
|
||||
OPTIMIZE_TEXTURE_SETTINGS |
|
||||
TEXTURE_ATLAS_BUILDER
|
||||
TEXTURE_ATLAS_BUILDER |
|
||||
STATIC_OBJECT_DETECTION
|
||||
};
|
||||
|
||||
/** Reset internal data to initial state - the getPermissibleOptionsMap is cleared.*/
|
||||
@@ -740,6 +743,27 @@ class OSGUTIL_EXPORT Optimizer
|
||||
|
||||
};
|
||||
|
||||
/** Optimize the setting of StateSet and Geometry objects in scene so that they have a STATIC DataVariance
|
||||
* when they don't have any callbacks associated with them. */
|
||||
class OSGUTIL_EXPORT StaticObjectDetectionVisitor : public BaseOptimizerVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
/// default to traversing all children.
|
||||
StaticObjectDetectionVisitor(Optimizer* optimizer=0):
|
||||
BaseOptimizerVisitor(optimizer, STATIC_OBJECT_DETECTION) {}
|
||||
|
||||
virtual void apply(osg::Node& node);
|
||||
|
||||
virtual void apply(osg::Geode& geode);
|
||||
|
||||
protected:
|
||||
|
||||
void applyStateSet(osg::StateSet& stateset);
|
||||
|
||||
void applyDrawable(osg::Drawable& drawable);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
inline bool BaseOptimizerVisitor::isOperationPermissibleForObject(const osg::StateSet* object) const
|
||||
|
||||
@@ -140,6 +140,9 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
|
||||
|
||||
/** Extract stats for current draw list. */
|
||||
bool getStats(Statistics& primStats) const;
|
||||
|
||||
/** Compute the number of dynamic RenderLeaves.*/
|
||||
virtual unsigned int computeNumberOfDynamicRenderLeaves() const;
|
||||
|
||||
void copyLeavesFromStateGraphListToRenderLeafList();
|
||||
|
||||
|
||||
@@ -39,16 +39,20 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced
|
||||
_drawable(drawable),
|
||||
_projection(projection),
|
||||
_modelview(modelview),
|
||||
_depth(depth) {}
|
||||
_depth(depth)
|
||||
{
|
||||
_dynamic = (drawable->getDataVariance()==osg::Object::DYNAMIC);
|
||||
}
|
||||
|
||||
|
||||
inline void set(osg::Drawable* drawable,osg::RefMatrix* projection,osg::RefMatrix* modelview, float depth=0.0f)
|
||||
{
|
||||
_parent = 0;
|
||||
_drawable = drawable;
|
||||
_projection = projection,
|
||||
_modelview = modelview,
|
||||
_projection = projection,
|
||||
_modelview = modelview,
|
||||
_depth = depth;
|
||||
_dynamic = (drawable->getDataVariance()==osg::Object::DYNAMIC);
|
||||
}
|
||||
|
||||
inline void reset()
|
||||
@@ -58,6 +62,7 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced
|
||||
_projection = 0;
|
||||
_modelview = 0;
|
||||
_depth = 0.0f;
|
||||
_dynamic = false;
|
||||
}
|
||||
|
||||
virtual void render(osg::RenderInfo& renderInfo,RenderLeaf* previous);
|
||||
@@ -72,6 +77,7 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced
|
||||
osg::ref_ptr<osg::RefMatrix> _projection;
|
||||
osg::ref_ptr<osg::RefMatrix> _modelview;
|
||||
float _depth;
|
||||
bool _dynamic;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -201,9 +201,10 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
|
||||
/** Extract stats for current draw list. */
|
||||
bool getStats(Statistics& stats) const;
|
||||
|
||||
/** Compute the number of dynamic RenderLeaves.*/
|
||||
virtual unsigned int computeNumberOfDynamicRenderLeaves() const;
|
||||
|
||||
|
||||
struct Attachment
|
||||
struct Attachment
|
||||
{
|
||||
osg::ref_ptr<osg::Image> _image;
|
||||
GLenum _imageReadPixelFormat;
|
||||
|
||||
@@ -58,6 +58,7 @@ class OSGUTIL_EXPORT StateGraph : public osg::Referenced
|
||||
|
||||
osg::ref_ptr<osg::Referenced> _userData;
|
||||
|
||||
bool _dynamic;
|
||||
|
||||
StateGraph():
|
||||
osg::Referenced(false),
|
||||
@@ -66,7 +67,8 @@ class OSGUTIL_EXPORT StateGraph : public osg::Referenced
|
||||
_depth(0),
|
||||
_averageDistance(0),
|
||||
_minimumDistance(0),
|
||||
_userData(NULL)
|
||||
_userData(NULL),
|
||||
_dynamic(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -77,9 +79,13 @@ class OSGUTIL_EXPORT StateGraph : public osg::Referenced
|
||||
_depth(0),
|
||||
_averageDistance(0),
|
||||
_minimumDistance(0),
|
||||
_userData(NULL)
|
||||
_userData(NULL),
|
||||
_dynamic(false)
|
||||
{
|
||||
if (_parent) _depth = _parent->_depth + 1;
|
||||
|
||||
if (_parent && _parent->_dynamic) _dynamic = true;
|
||||
else _dynamic = stateset->getDataVariance()==osg::Object::DYNAMIC;
|
||||
}
|
||||
|
||||
~StateGraph() {}
|
||||
@@ -176,6 +182,7 @@ class OSGUTIL_EXPORT StateGraph : public osg::Referenced
|
||||
_minimumDistance = FLT_MAX; // signify dirty.
|
||||
_leaves.push_back(leaf);
|
||||
leaf->_parent = this;
|
||||
if (_dynamic) leaf->_dynamic = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,30 @@
|
||||
|
||||
namespace osgViewer {
|
||||
|
||||
class OSGVIEWER_EXPORT EndOfDynamicDrawBlock : public osg::State::DynamicObjectRenderingCompletedCallback
|
||||
{
|
||||
public:
|
||||
|
||||
EndOfDynamicDrawBlock();
|
||||
|
||||
void completed(osg::State* state);
|
||||
|
||||
void block();
|
||||
|
||||
void release();
|
||||
|
||||
void set(unsigned int blockCount);
|
||||
|
||||
protected:
|
||||
|
||||
~EndOfDynamicDrawBlock();
|
||||
|
||||
OpenThreads::Mutex _mut;
|
||||
OpenThreads::Condition _cond;
|
||||
unsigned int _blockCount;
|
||||
};
|
||||
|
||||
|
||||
/** View holds a single view on a scene, this view may be composed of one or more slave cameras.*/
|
||||
class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter
|
||||
{
|
||||
|
||||
@@ -63,6 +63,13 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View
|
||||
/** Get the threading model the rendering traversals will use.*/
|
||||
ThreadingModel getThreadingModel() const { return _threadingModel; }
|
||||
|
||||
/** Set whether the main thread, calling frame(), should be used for the rendering traversals.*/
|
||||
void setUseMainThreadForRenderingTraversals(bool flag);
|
||||
|
||||
/** Get whether the main thread, calling frame(), should be used for the rendering traversals.*/
|
||||
bool getUseMainThreadForRenderingTraversals() const { return _useMainThreadForRenderingTraversal; }
|
||||
|
||||
|
||||
enum BarrierPosition
|
||||
{
|
||||
BeforeSwapBuffers,
|
||||
@@ -148,11 +155,13 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View
|
||||
int _keyEventSetsDone;
|
||||
bool _quitEventSetsDone;
|
||||
|
||||
ThreadingModel _threadingModel;
|
||||
ThreadingModel _threadingModel;
|
||||
bool _useMainThreadForRenderingTraversal;
|
||||
BarrierPosition _endBarrierPosition;
|
||||
|
||||
osg::ref_ptr<osg::BarrierOperation> _startRenderingBarrier;
|
||||
osg::ref_ptr<osg::BarrierOperation> _endRenderingDispatchBarrier;
|
||||
osg::ref_ptr<EndOfDynamicDrawBlock> _endDynamicDrawBlock;
|
||||
|
||||
unsigned int computeNumberOfThreadsIncludingMainRequired();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user