Preliminary work on support for a texture object pool that is designed to help manage resources down the GPU more tightly.

This commit is contained in:
Robert Osfield
2009-09-22 18:45:24 +00:00
parent 26925be4f4
commit 3d75054e2c
21 changed files with 1616 additions and 566 deletions

View File

@@ -199,6 +199,16 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
void setApplication(const std::string& application) { _application = application; }
const std::string& getApplication() { return _application; }
void setMaxTexturePoolSize(unsigned int size) { _maxTexturePoolSize = size; }
unsigned int getMaxTexturePoolSize() const { return _maxTexturePoolSize; }
void setMaxVBOPoolSize(unsigned int size) { _maxVBOPoolSize = size; }
unsigned int getMaxVBOPoolSize() const { return _maxVBOPoolSize; }
void setMaxFBOPoolSize(unsigned int size) { _maxFBOPoolSize = size; }
unsigned int getMaxFBOPoolSize() const { return _maxFBOPoolSize; }
protected:
virtual ~DisplaySettings();
@@ -240,6 +250,9 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
std::string _application;
unsigned int _maxTexturePoolSize;
unsigned int _maxVBOPoolSize;
unsigned int _maxFBOPoolSize;
};
}

View File

@@ -39,7 +39,7 @@
#ifdef GL_FOG_COORDINATE_ARRAY_EXT
#define GL_FOG_COORDINATE_ARRAY GL_FOG_COORDINATE_ARRAY_EXT
#else
#define GL_FOG_COORDINATE_ARRAY 0x8457
#define GL_FOG_COORDINATE_ARRAY 0x8457
#endif
#endif
@@ -47,14 +47,14 @@
#ifdef GL_SECONDARY_COLOR_ARRAY_EXT
#define GL_SECONDARY_COLOR_ARRAY GL_SECONDARY_COLOR_ARRAY_EXT
#else
#define GL_SECONDARY_COLOR_ARRAY 0x845E
#define GL_SECONDARY_COLOR_ARRAY 0x845E
#endif
#endif
namespace osg {
/** macro for use with osg::StateAttribute::apply methods for detecting and
* reporting OpenGL error messages.*/
* reporting OpenGL error messages.*/
#define OSG_GL_DEBUG(message) \
if (state.getFineGrainedErrorDetection()) \
{ \
@@ -70,37 +70,37 @@ namespace osg {
class GraphicsContext;
/** Encapsulates the current applied OpenGL modes, attributes and vertex arrays settings,
* implements lazy state updating and provides accessors for querying the current state.
* The venerable Red Book says that "OpenGL is a state machine", and this class
* represents the OpenGL state in OSG. Furthermore, \c State also has other
* important features:
* - It works as a stack of states (see \c pushStateSet() and
* \c popStateSet()). Manipulating this stack of OpenGL states manually is
* seldom needed, since OSG does this in the most common situations.
* - It implements lazy state updating. This means that, if one requests a
* state change and that particular state is already in the requested state,
* no OpenGL call will be made. This ensures that the OpenGL pipeline is not
* stalled by unnecessary state changes.
* - It allows to query the current OpenGL state without calls to \c glGet*(),
* which typically stall the graphics pipeline (see, for instance,
* \c captureCurrentState() and \c getModelViewMatrix()).
*/
* implements lazy state updating and provides accessors for querying the current state.
* The venerable Red Book says that "OpenGL is a state machine", and this class
* represents the OpenGL state in OSG. Furthermore, \c State also has other
* important features:
* - It works as a stack of states (see \c pushStateSet() and
* \c popStateSet()). Manipulating this stack of OpenGL states manually is
* seldom needed, since OSG does this in the most common situations.
* - It implements lazy state updating. This means that, if one requests a
* state change and that particular state is already in the requested state,
* no OpenGL call will be made. This ensures that the OpenGL pipeline is not
* stalled by unnecessary state changes.
* - It allows to query the current OpenGL state without calls to \c glGet*(),
* which typically stall the graphics pipeline (see, for instance,
* \c captureCurrentState() and \c getModelViewMatrix()).
*/
class OSG_EXPORT State : public Referenced, public Observer
{
public :
State();
/** Set the graphics context associated with that owns this State object.*/
/** Set the graphics context associated with that owns this State object.*/
void setGraphicsContext(GraphicsContext* context) { _graphicsContext = context; }
/** Get the graphics context associated with that owns this State object.*/
/** Get the graphics context associated with that owns this State object.*/
GraphicsContext* getGraphicsContext() { return _graphicsContext; }
/** Get the const graphics context associated with that owns this State object.*/
/** Get the const graphics context associated with that owns this State object.*/
const GraphicsContext* getGraphicsContext() const { return _graphicsContext; }
/** Set the current OpenGL context uniqueID.
Note, it is the application developers responsibility to
@@ -122,9 +122,9 @@ class OSG_EXPORT State : public Referenced, public Observer
/** Pop stateset off state stack.*/
void popStateSet();
/** pop all statesets off state stack, ensuring it is empty ready for the next frame.
* Note, to return OpenGL to default state, one should do any state.popAllStatSets(); state.apply().*/
* Note, to return OpenGL to default state, one should do any state.popAllStatSets(); state.apply().*/
void popAllStateSets();
/** Insert stateset onto state stack.*/
@@ -132,10 +132,10 @@ class OSG_EXPORT State : public Referenced, public Observer
/** Pop stateset off state stack.*/
void removeStateSet(unsigned int pos);
/** Get the number of StateSet's on the StateSet stack.*/
unsigned int getStateSetStackSize() { return static_cast<unsigned int>(_stateStateStack.size()); }
/** Pop StateSet's for the StateSet stack till its size equals the specified size.*/
void popStateSetStackToSize(unsigned int size) { while (_stateStateStack.size()>size) popStateSet(); }
@@ -143,7 +143,7 @@ class OSG_EXPORT State : public Referenced, public Observer
/** Get the StateSet stack.*/
StateSetStack& getStateSetStack() { return _stateStateStack; }
/** Copy the modes and attributes which capture the current state.*/
void captureCurrentState(StateSet& stateset) const;
@@ -216,14 +216,14 @@ class OSG_EXPORT State : public Referenced, public Observer
void apply(const StateSet* dstate);
/** Updates the OpenGL state so that it matches the \c StateSet at the
* top of the stack of <tt>StateSet</tt>s maintained internally by a
* \c State.
*/
* top of the stack of <tt>StateSet</tt>s maintained internally by a
* \c State.
*/
void apply();
/** Set whether a particular OpenGL mode is valid in the current graphics context.
* Use to disable OpenGL modes that are not supported by current graphics drivers/context.*/
* Use to disable OpenGL modes that are not supported by current graphics drivers/context.*/
inline void setModeValidity(StateAttribute::GLMode mode,bool valid)
{
ModeStack& ms = _modeMap[mode];
@@ -231,7 +231,7 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** Get whether a particular OpenGL mode is valid in the current graphics context.
* Use to disable OpenGL modes that are not supported by current graphics drivers/context.*/
* Use to disable OpenGL modes that are not supported by current graphics drivers/context.*/
inline bool getModeValidity(StateAttribute::GLMode mode)
{
ModeStack& ms = _modeMap[mode];
@@ -251,13 +251,13 @@ class OSG_EXPORT State : public Referenced, public Observer
/** Apply an OpenGL mode if required. This is a wrapper around
* \c glEnable() and \c glDisable(), that just actually calls these
* functions if the \c enabled flag is different than the current
* state.
* @return \c true if the state was actually changed. \c false
* otherwise. Notice that a \c false return does not indicate
* an error, it just means that the mode was already set to the
* same value as the \c enabled parameter.
* \c glEnable() and \c glDisable(), that just actually calls these
* functions if the \c enabled flag is different than the current
* state.
* @return \c true if the state was actually changed. \c false
* otherwise. Notice that a \c false return does not indicate
* an error, it just means that the mode was already set to the
* same value as the \c enabled parameter.
*/
inline bool applyMode(StateAttribute::GLMode mode,bool enabled)
{
@@ -345,44 +345,44 @@ class OSG_EXPORT State : public Referenced, public Observer
void haveAppliedMode(StateAttribute::GLMode mode,StateAttribute::GLModeValue value);
/** Mode has been set externally, therefore dirty the associated mode in osg::State
* so it is applied on next call to osg::State::apply(..)*/
* so it is applied on next call to osg::State::apply(..)*/
void haveAppliedMode(StateAttribute::GLMode mode);
/** Attribute has been applied externally, update state to reflect this setting.*/
void haveAppliedAttribute(const StateAttribute* attribute);
/** Attribute has been applied externally,
* and therefore this attribute type has been dirtied
* and will need to be re-applied on next osg::State.apply(..).
* note, if you have an osg::StateAttribute which you have applied externally
* then use the have_applied(attribute) method as this will cause the osg::State to
* track the current state more accurately and enable lazy state updating such
* that only changed state will be applied.*/
/** Attribute has been applied externally,
* and therefore this attribute type has been dirtied
* and will need to be re-applied on next osg::State.apply(..).
* note, if you have an osg::StateAttribute which you have applied externally
* then use the have_applied(attribute) method as this will cause the osg::State to
* track the current state more accurately and enable lazy state updating such
* that only changed state will be applied.*/
void haveAppliedAttribute(StateAttribute::Type type, unsigned int member=0);
/** Get whether the current specified mode is enabled (true) or disabled (false).*/
/** Get whether the current specified mode is enabled (true) or disabled (false).*/
bool getLastAppliedMode(StateAttribute::GLMode mode) const;
/** Get the current specified attribute, return NULL if one has not yet been applied.*/
/** Get the current specified attribute, return NULL if one has not yet been applied.*/
const StateAttribute* getLastAppliedAttribute(StateAttribute::Type type, unsigned int member=0) const;
/** texture Mode has been set externally, update state to reflect this setting.*/
void haveAppliedTextureMode(unsigned int unit, StateAttribute::GLMode mode,StateAttribute::GLModeValue value);
/** texture Mode has been set externally, therefore dirty the associated mode in osg::State
* so it is applied on next call to osg::State::apply(..)*/
* so it is applied on next call to osg::State::apply(..)*/
void haveAppliedTextureMode(unsigned int unit, StateAttribute::GLMode mode);
/** texture Attribute has been applied externally, update state to reflect this setting.*/
void haveAppliedTextureAttribute(unsigned int unit, const StateAttribute* attribute);
/** texture Attribute has been applied externally,
* and therefore this attribute type has been dirtied
* and will need to be re-applied on next osg::State.apply(..).
* note, if you have an osg::StateAttribute which you have applied externally
* then use the have_applied(attribute) method as this will the osg::State to
* track the current state more accurately and enable lazy state updating such
* that only changed state will be applied.*/
* and therefore this attribute type has been dirtied
* and will need to be re-applied on next osg::State.apply(..).
* note, if you have an osg::StateAttribute which you have applied externally
* then use the have_applied(attribute) method as this will the osg::State to
* track the current state more accurately and enable lazy state updating such
* that only changed state will be applied.*/
void haveAppliedTextureAttribute(unsigned int unit, StateAttribute::Type type, unsigned int member=0);
/** Get whether the current specified texture mode is enabled (true) or disabled (false).*/
@@ -456,18 +456,18 @@ class OSG_EXPORT State : public Referenced, public Observer
inline void unbindPixelBufferObject()
{
if (!_currentPBO) return;
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,0);
_currentPBO = 0;
}
inline void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
if (primcount>=1 && _glDrawArraysInstanced!=0) _glDrawArraysInstanced(mode, first, count, primcount);
else glDrawArrays(mode, first, count);
}
inline void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount )
{
if (primcount>=1 && _glDrawElementsInstanced!=0) _glDrawElementsInstanced(mode, count, type, indices, primcount);
@@ -476,8 +476,8 @@ class OSG_EXPORT State : public Referenced, public Observer
/** Wrapper around glInterleavedArrays(..).
* also resets the internal array points and modes within osg::State to keep the other
* vertex array operations consistent. */
* also resets the internal array points and modes within osg::State to keep the other
* vertex array operations consistent. */
void setInterleavedArrays( GLenum format, GLsizei stride, const GLvoid* pointer);
/** Set the vertex pointer using an osg::Array, and manage any VBO that are required.*/
@@ -487,7 +487,7 @@ class OSG_EXPORT State : public Referenced, public Observer
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
{
bindVertexBufferObject(vbo);
setVertexPointer(array->getDataSize(),array->getDataType(),0,array->getVertexBufferObjectOffset());
}
@@ -501,9 +501,9 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** wrapper around glEnableClientState(GL_VERTEX_ARRAY);glVertexPointer(..);
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void setVertexPointer( GLint size, GLenum type,
GLsizei stride, const GLvoid *ptr )
GLsizei stride, const GLvoid *ptr )
{
if (!_vertexArray._enabled || _vertexArray._dirty)
{
@@ -519,7 +519,7 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** wrapper around glDisableClientState(GL_VERTEX_ARRAY).
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void disableVertexPointer()
{
if (_vertexArray._enabled || _vertexArray._dirty)
@@ -544,9 +544,9 @@ class OSG_EXPORT State : public Referenced, public Observer
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
{
bindVertexBufferObject(vbo);
setNormalPointer(array->getDataType(),0,array->getVertexBufferObjectOffset());
setNormalPointer(array->getDataType(),0,array->getVertexBufferObjectOffset());
}
else
{
@@ -558,9 +558,9 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** wrapper around glEnableClientState(GL_NORMAL_ARRAY);glNormalPointer(..);
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void setNormalPointer( GLenum type, GLsizei stride,
const GLvoid *ptr )
const GLvoid *ptr )
{
if (!_normalArray._enabled || _normalArray._dirty)
{
@@ -576,7 +576,7 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** wrapper around glDisableClientState(GL_NORMAL_ARRAY);
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void disableNormalPointer()
{
if (_normalArray._enabled || _normalArray._dirty)
@@ -600,7 +600,7 @@ class OSG_EXPORT State : public Referenced, public Observer
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
{
bindVertexBufferObject(vbo);
setColorPointer(array->getDataSize(),array->getDataType(),0,array->getVertexBufferObjectOffset());
}
@@ -615,9 +615,9 @@ class OSG_EXPORT State : public Referenced, public Observer
/** wrapper around glEnableClientState(GL_COLOR_ARRAY);glColorPointer(..);
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void setColorPointer( GLint size, GLenum type,
GLsizei stride, const GLvoid *ptr )
GLsizei stride, const GLvoid *ptr )
{
if (!_colorArray._enabled || _colorArray._dirty)
{
@@ -633,7 +633,7 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** wrapper around glDisableClientState(GL_COLOR_ARRAY);
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void disableColorPointer()
{
if (_colorArray._enabled || _colorArray._dirty)
@@ -661,9 +661,9 @@ class OSG_EXPORT State : public Referenced, public Observer
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
{
bindVertexBufferObject(vbo);
#if 0
#if 0
setSecondaryColorPointer(array->getDataSize(),array->getDataType(),0,vbo->getOffset(array->getVertexBufferObjectIndex()));
#else
setSecondaryColorPointer(array->getDataSize(),array->getDataType(),0,array->getVertexBufferObjectOffset());
@@ -679,11 +679,11 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** wrapper around glEnableClientState(GL_SECONDARY_COLOR_ARRAY);glSecondayColorPointer(..);
* note, only updates values that change.*/
* note, only updates values that change.*/
void setSecondaryColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr );
/** wrapper around glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void disableSecondaryColorPointer()
{
if (_secondaryColorArray._enabled || _secondaryColorArray._dirty)
@@ -701,9 +701,9 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** wrapper around glEnableClientState(GL_INDEX_ARRAY);glIndexPointer(..);
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void setIndexPointer( GLenum type, GLsizei stride,
const GLvoid *ptr )
const GLvoid *ptr )
{
if (!_indexArray._enabled || _indexArray._dirty)
{
@@ -719,7 +719,7 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** wrapper around glDisableClientState(GL_INDEX_ARRAY);
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void disableIndexPointer()
{
if (_indexArray._enabled || _indexArray._dirty)
@@ -747,7 +747,7 @@ class OSG_EXPORT State : public Referenced, public Observer
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
{
bindVertexBufferObject(vbo);
#if 0
setFogCoordPointer(array->getDataType(),0,vbo->getOffset(array->getVertexBufferObjectIndex()));
@@ -766,11 +766,11 @@ class OSG_EXPORT State : public Referenced, public Observer
/** wrapper around glEnableClientState(GL_FOG_COORDINATE_ARRAY);glFogCoordPointer(..);
* note, only updates values that change.*/
* note, only updates values that change.*/
void setFogCoordPointer( GLenum type, GLsizei stride, const GLvoid *ptr );
/** wrapper around glDisableClientState(GL_FOG_COORDINATE_ARRAY);
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void disableFogCoordPointer()
{
if (_fogArray._enabled || _fogArray._dirty)
@@ -796,7 +796,7 @@ class OSG_EXPORT State : public Referenced, public Observer
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
{
bindVertexBufferObject(vbo);
#if 0
setTexCoordPointer(unit, array->getDataSize(),array->getDataType(),0,vbo->getOffset(array->getVertexBufferObjectIndex()));
@@ -814,7 +814,7 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** wrapper around glEnableClientState(GL_TEXTURE_COORD_ARRAY);glTexCoordPointer(..);
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void setTexCoordPointer( unsigned int unit,
GLint size, GLenum type,
GLsizei stride, const GLvoid *ptr )
@@ -839,7 +839,7 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** wrapper around glDisableClientState(GL_TEXTURE_COORD_ARRAY);
* note, only updates values that change.*/
* note, only updates values that change.*/
inline void disableTexCoordPointer( unsigned int unit )
{
if (setClientActiveTextureUnit(unit))
@@ -896,16 +896,16 @@ class OSG_EXPORT State : public Referenced, public Observer
/** Set the current texture unit, return true if selected,
* false if selection failed such as when multi texturing is not supported.
* note, only updates values that change.*/
* false if selection failed such as when multi texturing is not supported.
* note, only updates values that change.*/
bool setActiveTextureUnit( unsigned int unit );
/** Get the current texture unit.*/
unsigned int getActiveTextureUnit() const { return _currentActiveTextureUnit; }
/** Set the current tex coord array texture unit, return true if selected,
* false if selection failed such as when multi texturing is not supported.
* note, only updates values that change.*/
* false if selection failed such as when multi texturing is not supported.
* note, only updates values that change.*/
bool setClientActiveTextureUnit( unsigned int unit );
/** Get the current tex coord array texture unit.*/
@@ -918,9 +918,9 @@ class OSG_EXPORT State : public Referenced, public Observer
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
{
bindVertexBufferObject(vbo);
#if 0
#if 0
setVertexAttribPointer(unit, array->getDataSize(),array->getDataType(),normalized,0,vbo->getOffset(array->getVertexBufferObjectIndex()));
#else
setVertexAttribPointer(unit, array->getDataSize(),array->getDataType(),normalized,0,array->getVertexBufferObjectOffset());
@@ -936,13 +936,13 @@ class OSG_EXPORT State : public Referenced, public Observer
}
/** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..);
* note, only updates values that change.*/
* note, only updates values that change.*/
void setVertexAttribPointer( unsigned int index,
GLint size, GLenum type, GLboolean normalized,
GLsizei stride, const GLvoid *ptr );
GLint size, GLenum type, GLboolean normalized,
GLsizei stride, const GLvoid *ptr );
/** wrapper around DisableVertexAttribArrayARB(index);
* note, only updates values that change.*/
* note, only updates values that change.*/
void disableVertexAttribPointer( unsigned int index );
void disableVertexAttribPointersAboveAndIncluding( unsigned int index );
@@ -965,10 +965,10 @@ class OSG_EXPORT State : public Referenced, public Observer
{
if (_lastAppliedProgramObject!=program)
{
_lastAppliedProgramObject = program;
_lastAppliedProgramObject = program;
if (program && _appliedProgramObjectSet.count(program)==0)
{
_appliedProgramObjectSet.insert(program);
_appliedProgramObjectSet.insert(program);
program->addObserver(this);
}
}
@@ -998,8 +998,8 @@ class OSG_EXPORT State : public Referenced, public Observer
/** Set the DisplaySettings. Note, nothing is applied, the visual settings are just
* used in the State object to pass the current visual settings to Drawables
* during rendering. */
* used in the State object to pass the current visual settings to Drawables
* during rendering. */
inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; }
/** Get the DisplaySettings */
@@ -1011,7 +1011,7 @@ class OSG_EXPORT State : public Referenced, public Observer
void setAbortRenderingPtr(bool* abortPtr) { _abortRenderingPtr = abortPtr; }
/** Get flag for early termination of the draw traversal,
* if true steps should be taken to complete rendering early.*/
* if true steps should be taken to complete rendering early.*/
bool getAbortRendering() const { return _abortRenderingPtr!=0?(*_abortRenderingPtr):false; }
@@ -1019,13 +1019,13 @@ class OSG_EXPORT State : public Referenced, public Observer
{
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)
{
@@ -1041,9 +1041,9 @@ class OSG_EXPORT State : public Referenced, public Observer
/** 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.*/
/** 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;
@@ -1051,13 +1051,22 @@ class OSG_EXPORT State : public Referenced, public Observer
{
_completeDynamicObjectRenderingCallback->completed(this);
}
}
}
void setMaxTexturePoolSize(unsigned int size);
unsigned int getMaxTexturePoolSize() const { return _maxTexturePoolSize; }
void setMaxVBOPoolSize(unsigned int size);
unsigned int getMaxVBOPoolSize() const { return _maxVBOPoolSize; }
void setMaxFBOPoolSize(unsigned int size);
unsigned int getMaxFBOPoolSize() const { return _maxFBOPoolSize; }
enum CheckForGLErrors
{
/** NEVER_CHECK_GL_ERRORS hints that OpenGL need not be checked for, this
/** NEVER_CHECK_GL_ERRORS hints that OpenGL need not be checked for, this
is the fastest option since checking for errors does incurr a small overhead.*/
NEVER_CHECK_GL_ERRORS,
/** ONCE_PER_FRAME means that OpenGl errors will be checked for once per
@@ -1154,13 +1163,13 @@ class OSG_EXPORT State : public Referenced, public Observer
/** Apply an OpenGL mode if required, passing in mode, enable flag and
* appropriate mode stack. This is a wrapper around \c glEnable() and
* \c glDisable(), that just actually calls these functions if the
* \c enabled flag is different than the current state.
* @return \c true if the state was actually changed. \c false
* otherwise. Notice that a \c false return does not indicate
* an error, it just means that the mode was already set to the
* same value as the \c enabled parameter.
* appropriate mode stack. This is a wrapper around \c glEnable() and
* \c glDisable(), that just actually calls these functions if the
* \c enabled flag is different than the current state.
* @return \c true if the state was actually changed. \c false
* otherwise. Notice that a \c false return does not indicate
* an error, it just means that the mode was already set to the
* same value as the \c enabled parameter.
*/
inline bool applyMode(StateAttribute::GLMode mode,bool enabled,ModeStack& ms)
{
@@ -1224,7 +1233,7 @@ class OSG_EXPORT State : public Referenced, public Observer
typedef std::map<std::string,UniformStack> UniformMap;
typedef std::vector<ref_ptr<const Matrix> > MatrixStack;
typedef std::set<const Program::PerContextProgram* > AppliedProgramObjectSet;
ModeMap _modeMap;
@@ -1239,6 +1248,11 @@ class OSG_EXPORT State : public Referenced, public Observer
StateSetStack _stateStateStack;
unsigned int _maxTexturePoolSize;
unsigned int _maxVBOPoolSize;
unsigned int _maxFBOPoolSize;
struct EnabledArrayPair
{
EnabledArrayPair():_dirty(true),_enabled(false),_normalized(0),_pointer(0) {}
@@ -1326,7 +1340,7 @@ class OSG_EXPORT State : public Referenced, public Observer
typedef void (APIENTRY * EnableVertexAttribProc) (unsigned int);
typedef void (APIENTRY * DisableVertexAttribProc) (unsigned int);
typedef void (APIENTRY * BindBufferProc) (GLenum target, GLuint buffer);
typedef void (APIENTRY * DrawArraysInstancedProc)( GLenum mode, GLint first, GLsizei count, GLsizei primcount );
typedef void (APIENTRY * DrawElementsInstancedProc)( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount );
@@ -1346,7 +1360,7 @@ class OSG_EXPORT State : public Referenced, public Observer
unsigned int _dynamicObjectCount;
osg::ref_ptr<DynamicObjectRenderingCompletedCallback> _completeDynamicObjectRenderingCallback;
};
inline void State::pushModeList(ModeMap& modeMap,const StateSet::ModeList& modeList)

View File

@@ -470,12 +470,17 @@ class OSG_EXPORT Texture : public osg::StateAttribute
class TextureObject;
/** Returns a pointer to the texture object for the current context. */
/** Returns a pointer to the TextureBbject for the current context. */
inline TextureObject* getTextureObject(unsigned int contextID) const
{
return _textureObjectBuffer[contextID].get();
}
inline void setTextureObject(unsigned int contextID, TextureObject* to)
{
_textureObjectBuffer[contextID] = to;
}
/** Forces a recompile on next apply() of associated OpenGL texture
* objects. */
void dirtyTextureObject();
@@ -759,7 +764,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute
/** Allocate mipmap levels of the texture by subsequent calling of glTexImage* function. */
virtual void allocateMipmap(State& state) const = 0;
/** Returns -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
int compareTexture(const Texture& rhs) const;
@@ -769,7 +774,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute
typedef buffered_value<unsigned int> TexParameterDirtyList;
mutable TexParameterDirtyList _texParametersDirtyList;
mutable TexParameterDirtyList _texMipmapGenerationDirtyList;
WrapMode _wrap_s;
WrapMode _wrap_t;
WrapMode _wrap_r;
@@ -790,31 +795,137 @@ class OSG_EXPORT Texture : public osg::StateAttribute
mutable GLint _internalFormat;
mutable GLenum _sourceFormat;
mutable GLenum _sourceType;
bool _use_shadow_comparison;
ShadowCompareFunc _shadow_compare_func;
ShadowTextureMode _shadow_texture_mode;
float _shadow_ambient;
public:
class TextureObject : public osg::Referenced
struct TextureProfile
{
public:
inline TextureObject(GLuint id,GLenum target):
_id(id),
inline TextureProfile(GLenum target):
_target(target),
_numMipmapLevels(0),
_internalFormat(0),
_width(0),
_height(0),
_depth(0),
_border(0),
_border(0) {}
inline TextureProfile(GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border):
_target(target),
_numMipmapLevels(numMipmapLevels),
_internalFormat(internalFormat),
_width(width),
_height(height),
_depth(depth),
_border(border) {}
#define LESSTHAN(A,B) if (A<B) return true; if (B<A) return false;
#define FINALLESSTHAN(A,B) return (A<B);
bool operator < (const TextureProfile& rhs) const
{
LESSTHAN(_target,rhs._target);
LESSTHAN(_numMipmapLevels,rhs._numMipmapLevels);
LESSTHAN(_internalFormat,rhs._internalFormat);
LESSTHAN(_width,rhs._width);
LESSTHAN(_height,rhs._height);
LESSTHAN(_depth,rhs._depth);
FINALLESSTHAN(_border, rhs._border);
}
bool operator == (const TextureProfile& rhs) const
{
return _target == rhs._target &&
_numMipmapLevels == rhs._numMipmapLevels &&
_internalFormat == rhs._internalFormat &&
_width == rhs._width &&
_height == rhs._height &&
_depth == rhs._depth &&
_border == rhs._border;
}
inline void set(GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border)
{
_numMipmapLevels = numMipmapLevels;
_internalFormat = internalFormat;
_width = width;
_height = height;
_depth = depth;
_border = border;
}
inline bool match(GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border)
{
return (_target == target) &&
(_numMipmapLevels == numMipmapLevels) &&
(_internalFormat == internalFormat) &&
(_width == width) &&
(_height == height) &&
(_depth == depth) &&
(_border == border);
}
GLenum _target;
GLint _numMipmapLevels;
GLenum _internalFormat;
GLsizei _width;
GLsizei _height;
GLsizei _depth;
GLint _border;
};
// forward declare
class TextureObjectSet;
class TextureObjectManager;
class TextureObject : public osg::Referenced
{
public:
inline TextureObject(Texture* texture, GLuint id, GLenum target):
_id(id),
_profile(target),
_set(0),
_previous(0),
_next(0),
_texture(texture),
_allocated(false),
_timeStamp(0) {}
inline TextureObject(GLuint id,
inline TextureObject(Texture* texture, GLuint id, const TextureProfile& profile):
_id(id),
_profile(profile),
_set(0),
_previous(0),
_next(0),
_texture(texture),
_allocated(false),
_timeStamp(0) {}
inline TextureObject(Texture* texture,
GLuint id,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
@@ -823,16 +934,14 @@ class OSG_EXPORT Texture : public osg::StateAttribute
GLsizei depth,
GLint border):
_id(id),
_target(target),
_numMipmapLevels(numMipmapLevels),
_internalFormat(internalFormat),
_width(width),
_height(height),
_depth(depth),
_border(border),
_profile(target,numMipmapLevels,internalFormat,width,height,depth,border),
_set(0),
_previous(0),
_next(0),
_texture(texture),
_allocated(false),
_timeStamp(0) {}
inline bool match(GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
@@ -842,24 +951,22 @@ class OSG_EXPORT Texture : public osg::StateAttribute
GLint border)
{
return isReusable() &&
(_target == target) &&
(_numMipmapLevels == numMipmapLevels) &&
(_internalFormat == internalFormat) &&
(_width == width) &&
(_height == height) &&
(_depth == depth) &&
(_border == border);
}
inline void bind()
{
glBindTexture( _target, _id);
_profile.match(target,numMipmapLevels,internalFormat,width,height,depth,border);
}
void bind();
inline GLenum id() const { return _id; }
inline GLenum target() const { return _profile._target; }
inline void setTexture(Texture* texture) { _texture = texture; }
inline Texture* getTexture() const { return _texture; }
inline void setTimeStamp(double timestamp) { _timeStamp = timestamp; }
inline double getTimeStamp() const { return _timeStamp; }
inline void setAllocated(bool allocated=true) { _allocated = allocated; }
inline void setAllocated(GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
@@ -868,42 +975,101 @@ class OSG_EXPORT Texture : public osg::StateAttribute
GLint border)
{
_allocated=true;
_numMipmapLevels = numMipmapLevels;
_internalFormat = internalFormat;
_width = width;
_height = height;
_depth = depth;
_border = border;
_profile.set(numMipmapLevels,internalFormat,width,height,depth,border);
}
inline bool isAllocated() const { return _allocated; }
inline bool isReusable() const { return _allocated && _width!=0; }
inline bool isReusable() const { return _allocated && _profile._width!=0; }
GLuint _id;
GLenum _target;
GLint _numMipmapLevels;
GLenum _internalFormat;
GLsizei _width;
GLsizei _height;
GLsizei _depth;
GLint _border;
bool _allocated;
double _timeStamp;
GLuint _id;
TextureProfile _profile;
TextureObjectSet* _set;
TextureObject* _previous;
TextureObject* _next;
Texture* _texture;
bool _allocated;
double _timeStamp;
};
typedef std::list< ref_ptr<TextureObject> > TextureObjectList;
typedef osg::buffered_object<TextureObjectList> TextureObjectListMap;
/** Takes the active texture objects from the Texture and places them
* in the specified TextureObjectListMap. */
void takeTextureObjects(TextureObjectListMap& toblm);
static TextureObject* generateTextureObject(unsigned int contextID,GLenum target);
class TextureObjectSet : public Referenced
{
public:
TextureObjectSet(TextureObjectManager* parent, const TextureProfile& profile);
static TextureObject* generateTextureObject(unsigned int contextID,
void handlePendingOrphandedTextureObjects();
void flushAllDeletedTextureObjects();
void discardAllDeletedTextureObjects();
void flushDeletedTextureObjects(double currentTime, double& availableTime);
TextureObject* takeOrGenerate(Texture* texture);
void moveToBack(TextureObject* to);
void addToBack(TextureObject* to);
void orphan(TextureObject* to);
unsigned int size() const;
bool checkConsistency() const;
protected:
virtual ~TextureObjectSet();
OpenThreads::Mutex _mutex;
TextureObjectManager* _parent;
unsigned int _contextID;
TextureProfile _profile;
unsigned int _numOfTextureObjects;
TextureObjectList _orphanedTextureObjects;
TextureObjectList _pendingOrphanedTextureObjects;
TextureObject* _head;
TextureObject* _tail;
};
class TextureObjectManager : public osg::Referenced
{
public:
TextureObjectManager(unsigned int contextID);
unsigned int getContextID() const { return _contextID; }
void setTexturePoolSize(unsigned int size);
unsigned int getTexturePoolSize() const { return _texturePoolSize; }
TextureObject* generateTextureObject(const Texture* texture, GLenum target);
TextureObject* generateTextureObject(const Texture* texture,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border);
void handlePendingOrphandedTextureObjects();
void flushAllDeletedTextureObjects();
void discardAllDeletedTextureObjects();
void flushDeletedTextureObjects(double currentTime, double& availableTime);
void releaseTextureObject(TextureObject* to);
protected:
typedef std::map< TextureProfile, osg::ref_ptr<TextureObjectSet> > TextureSetMap;
unsigned int _contextID;
unsigned int _texturePoolSize;
TextureSetMap _textureSetMap;
};
static osg::ref_ptr<Texture::TextureObjectManager>& getTextureObjectManager(unsigned int contextID);
static TextureObject* generateTextureObject(const Texture* texture, unsigned int contextID,GLenum target);
static TextureObject* generateTextureObject(const Texture* texture,
unsigned int contextID,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
@@ -922,9 +1088,10 @@ class OSG_EXPORT Texture : public osg::StateAttribute
static void flushAllDeletedTextureObjects(unsigned int contextID);
static void discardAllDeletedTextureObjects(unsigned int contextID);
static void flushDeletedTextureObjects(unsigned int contextID,double currentTime, double& availableTime);
static void releaseTextureObject(unsigned int contextID, TextureObject* to);
protected: