Various updates to support the new GraphicsThread class.

This commit is contained in:
Robert Osfield
2005-08-18 20:17:51 +00:00
parent 717a6dcf14
commit 51faa7e43a
9 changed files with 82 additions and 100 deletions

View File

@@ -15,10 +15,7 @@
#define OSG_GRAPHICSCONTEXT 1
#include <osg/State>
#include <OpenThreads/Thread>
#include <list>
#include <osg/GraphicsThread>
namespace osg {
@@ -144,57 +141,44 @@ class OSG_EXPORT GraphicsContext : public Referenced
/** Return true if the graphics context has been realised and is ready to use.*/
virtual bool isRealized() const = 0;
/** Release the graphics context.*/
virtual void release() = 0;
/** close the graphics context.*/
virtual void close() = 0;
/** Make this graphics context current.*/
virtual void makeCurrent() = 0;
/** Make this graphics context current.
* Implementated by first aquiring a lock of the GraphicsContext mutex, and then doing a call to makeCurrentImplementation(). */
void makeCurrent();
/** Make this graphics context current with specified read context.*/
virtual void makeContextCurrent(GraphicsContext* readContext) = 0;
/** Make this graphics context current with specified read context.
* Implementated by first aquiring a lock of the GraphicsContext mutex, and then doing a call to makeContextCurrentImplementation(). */
void makeContextCurrent(GraphicsContext* readContext);
virtual void releaseContext() = 0;
/** Release the graphics context by unlocking the GraphicsContext mutex.*/
void releaseContext();
/** Return true if the current thread has this OpenGL graphics context.*/
inline bool isCurrent() const { return _threadOfLastMakeCurrent == OpenThreads::Thread::CurrentThread(); }
/** Make this graphics context current.*/
virtual void makeCurrentImplementation() = 0;
/** Make this graphics context current with specified read context.*/
virtual void makeContextCurrentImplementation(GraphicsContext* readContext) = 0;
/** Bind the graphics context to associated texture.*/
virtual void bindPBufferToTexture(GLenum buffer) = 0;
/** swap the front and back buffers.*/
virtual void swapBuffers() = 0;
public:
struct GraphicsOperation : public Referenced
{
virtual void operator () (GraphicsContext& context) {}
};
class GraphicsThread : public Referenced, OpenThreads::Thread
{
public:
GraphicsThread() {}
typedef std::list< ref_ptr<GraphicsOperation> > OperationList;
void add(GraphicsOperation* operation);
virtual void run();
protected:
virtual ~GraphicsThread() {}
OpenThreads::Mutex _runListMutex;
OperationList _operations;
};
/** Assign a graphics thread to the graphics context, so that the thread handles all OpenGL operations.*/
void setGraphicsThread(GraphicsThread* gt) { _graphicsThread = gt; }
/** Get the graphics thread assigned the graphics context.*/
GraphicsThread* getGraphicsThread() { return _graphicsThread.get(); }
/** Get the const graphics thread assigned the graphics context.*/
const GraphicsThread* getGraphicsThread() const { return _graphicsThread.get(); }
protected:
@@ -205,6 +189,7 @@ class OSG_EXPORT GraphicsContext : public Referenced
ref_ptr<Traits> _traits;
ref_ptr<State> _state;
OpenThreads::Mutex _mutex;
OpenThreads::Thread* _threadOfLastMakeCurrent;
ref_ptr<GraphicsThread> _graphicsThread;

View File

@@ -18,6 +18,7 @@
#include <osg/Group>
#include <osg/PagedLOD>
#include <osg/Drawable>
#include <osg/GraphicsThread>
#include <OpenThreads/Thread>
#include <OpenThreads/Mutex>
@@ -32,54 +33,6 @@
namespace osgDB {
class Block: public osg::Referenced {
public:
Block():_released(false) {}
inline void block()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> mutlock(_mut);
if( !_released )
_cond.wait(&_mut);
}
inline void release()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> mutlock(_mut);
if (!_released)
{
_released = true;
_cond.broadcast();
}
}
inline void reset()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> mutlock(_mut);
_released = false;
}
inline void set(bool doRelease)
{
if (doRelease!=_released)
{
if (doRelease) release();
else reset();
}
}
protected:
~Block()
{
release();
}
private:
OpenThreads::Mutex _mut;
OpenThreads::Condition _cond;
bool _released;
};
/** Database paging class which manages the loading of files in a background thread,
* and syncronizing of loaded models with the main scene graph.*/
@@ -125,7 +78,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
/** Get the whether UseFrameBlock is on or off.*/
bool getUseFrameBlock() const { return _useFrameBlock; }
Block* getFrameBlock() { return _frameBlock.get(); }
osg::Block* getFrameBlock() { return _frameBlock.get(); }
/** Set the priority of the database pager thread during the frame (i.e. while cull and draw are running.)*/
void setThreadPriorityDuringFrame(ThreadPriority duringFrame) { _threadPriorityDuringFrame = duringFrame; }
@@ -313,7 +266,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
bool _startThreadCalled;
osg::ref_ptr<Block> _databasePagerThreadBlock;
osg::ref_ptr<osg::Block> _databasePagerThreadBlock;
inline void updateDatabasePagerThreadBlock()
{
@@ -345,7 +298,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
bool _useFrameBlock;
int _numFramesActive;
mutable OpenThreads::Mutex _numFramesActiveMutex;
osg::ref_ptr<Block> _frameBlock;
osg::ref_ptr<osg::Block> _frameBlock;
int _frameNumber;
ThreadPriority _threadPriorityDuringFrame;

View File

@@ -51,13 +51,13 @@ class OSGPRODUCER_EXPORT GraphicsContextImplementation : public osg::GraphicsCon
virtual bool isRealized() const { return _rs.valid() && _rs->isRealized(); }
/** Release the graphics context.*/
virtual void release();
virtual void close();
/** Make this graphics context current.*/
virtual void makeCurrent();
virtual void makeCurrentImplementation();
/** Make this graphics context current with specified read context.*/
virtual void makeContextCurrent(GraphicsContext* readContext);
virtual void makeContextCurrentImplementation(GraphicsContext* readContext);
/** Bind the graphics context to associated texture.*/
virtual void bindPBufferToTexture(GLenum buffer);

View File

@@ -45,6 +45,7 @@ CXXFILES =\
Geometry.cpp\
GLExtensions.cpp\
GraphicsContext.cpp\
GraphicsThread.cpp\
Group.cpp\
Image.cpp\
ImageStream.cpp\

View File

@@ -125,3 +125,43 @@ GraphicsContext::~GraphicsContext()
}
}
void GraphicsContext::makeCurrent()
{
ReleaseContext_Block_MakeCurrentOperation* rcbmco = 0;
if (_graphicsThread.valid() &&
_threadOfLastMakeCurrent == _graphicsThread.get())
{
// create a relase contex, block and make current operation to stop the graphics thread while we use the graphics context for ourselves
rcbmco = new ReleaseContext_Block_MakeCurrentOperation;
_graphicsThread->add(rcbmco);
}
if (!isCurrent()) _mutex.lock();
makeCurrentImplementation();
_threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread();
if (rcbmco)
{
// Let the "relase contex, block and make current operation" proceed, which will now move on to trying to aquire the graphics
// contex itself with a makeCurrent(), this will then block on the GraphicsContext mutex till releaseContext() releases it.
rcbmco->release();
}
}
void GraphicsContext::makeContextCurrent(GraphicsContext* readContext)
{
if (!isCurrent()) _mutex.lock();
makeContextCurrentImplementation(readContext);
_threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread();
}
void GraphicsContext::releaseContext()
{
_mutex.unlock();
}

View File

@@ -37,8 +37,8 @@ DatabasePager::DatabasePager()
_useFrameBlock = false;
_numFramesActive = 0;
_frameNumber = 0;
_frameBlock = new Block;
_databasePagerThreadBlock = new Block;
_frameBlock = new osg::Block;
_databasePagerThreadBlock = new osg::Block;
_threadPriorityDuringFrame = THREAD_PRIORITY_MIN;
_threadPriorityOutwithFrame = THREAD_PRIORITY_MIN;

View File

@@ -159,7 +159,7 @@ GraphicsContextImplementation::GraphicsContextImplementation(Producer::RenderSur
GraphicsContextImplementation::~GraphicsContextImplementation()
{
release();
close();
}
bool GraphicsContextImplementation::realize()
@@ -184,7 +184,7 @@ bool GraphicsContextImplementation::realize()
}
}
void GraphicsContextImplementation::makeCurrent()
void GraphicsContextImplementation::makeCurrentImplementation()
{
if (!_rs) return;
@@ -193,7 +193,7 @@ void GraphicsContextImplementation::makeCurrent()
_rs->makeCurrent();
}
void GraphicsContextImplementation::makeContextCurrent(GraphicsContext* readContext)
void GraphicsContextImplementation::makeContextCurrentImplementation(GraphicsContext* readContext)
{
if (!_rs) return;
@@ -207,7 +207,7 @@ void GraphicsContextImplementation::makeContextCurrent(GraphicsContext* readCont
_rs->makeCurrent();
}
void GraphicsContextImplementation::release()
void GraphicsContextImplementation::close()
{
if (!_rs) return;

View File

@@ -684,8 +684,7 @@ void Viewer::update()
// create an event to signal the new frame.
osg::ref_ptr<osgProducer::EventAdapter> frame_event = new osgProducer::EventAdapter;
// frame_event->adaptFrame(__frameStamp->getReferenceTime());
frame_event->adaptFrame(_kbmcb->getTime());
frame_event->adaptFrame(_frameStamp->getReferenceTime());
queue.push_back(frame_event);
if (_eventVisitor.valid())

View File

@@ -160,6 +160,10 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
if (_graphicsContext.valid() && _graphicsContext != callingContext)
{
// show we release the context so that others can use it?? will do so right
// now as an experiment.
callingContext->releaseContext();
useState = _graphicsContext->getState();
useContext = _graphicsContext.get();
useContext->makeCurrent();