Occlusion Queries Stuttering fix from upstream.

Thanks: Bret Curtis
parent fa5b1385
From: Alberto Luaces <aluaces@udc.es>
Date: Wed, 21 Sep 2016 20:51:59 +0200
Subject: Occlusion Queries Stuttering fix from upstream.
---
include/osg/OcclusionQueryNode | 4 +-
src/osg/OcclusionQueryNode.cpp | 105 +++++++++++++++++++++++------------------
2 files changed, 60 insertions(+), 49 deletions(-)
diff --git a/include/osg/OcclusionQueryNode b/include/osg/OcclusionQueryNode
index 07285f8..2b68e4c 100644
--- a/include/osg/OcclusionQueryNode
+++ b/include/osg/OcclusionQueryNode
@@ -40,7 +40,7 @@ osg::StateSet* initOQDebugState();
class TestResult : public osg::Referenced
{
public:
- TestResult() : _init( false ), _id( 0 ), _contextID( 0 ), _active( false ), _numPixels( 0 ) {}
+ TestResult() : _init( false ), _id( 0 ), _contextID( 0 ), _active( false ), _numPixels( 0 ) {setThreadSafeRefUnref(true);}
~TestResult() {}
bool _init;
@@ -81,7 +81,7 @@ public:
static void discardDeletedQueryObjects( unsigned int contextID );
protected:
- typedef std::map< const osg::Camera*, TestResult > ResultMap;
+ typedef std::map< const osg::Camera*, osg::ref_ptr<osg::TestResult> > ResultMap;
mutable ResultMap _results;
mutable OpenThreads::Mutex _mapMutex;
diff --git a/src/osg/OcclusionQueryNode.cpp b/src/osg/OcclusionQueryNode.cpp
index 1deaf8c..b95f86a 100644
--- a/src/osg/OcclusionQueryNode.cpp
+++ b/src/osg/OcclusionQueryNode.cpp
@@ -97,7 +97,7 @@ StateSet* initOQDebugState()
struct RetrieveQueriesCallback : public osg::Camera::DrawCallback
{
- typedef std::vector<osg::TestResult*> ResultsVector;
+ typedef std::vector<osg::ref_ptr<osg::TestResult> > ResultsVector;
ResultsVector _results;
RetrieveQueriesCallback( osg::GLExtensions* ext=NULL )
@@ -143,7 +143,7 @@ struct RetrieveQueriesCallback : public osg::Camera::DrawCallback
ResultsVector::const_iterator it = _results.begin();
while (it != _results.end())
{
- osg::TestResult* tr = const_cast<osg::TestResult*>( *it );
+ osg::TestResult* tr = const_cast<osg::TestResult*>( (*it).get() );
if (!tr->_active || !tr->_init)
{
@@ -159,31 +159,20 @@ struct RetrieveQueriesCallback : public osg::Camera::DrawCallback
OSG_DEBUG <<
"osgOQ: RQCB: Retrieving..." << std::endl;
-#ifdef FORCE_QUERY_RESULT_AVAILABLE_BEFORE_RETRIEVAL
-
- // Should not need to do this, but is required on some platforms to
- // work aroung issues in the device driver. For example, without this
- // code, we've seen crashes on 64-bit Mac/Linux NVIDIA systems doing
- // multithreaded, multipipe rendering (as in a CAVE).
- // Tried with ATI and verified this workaround is not needed; the
- // problem is specific to NVIDIA.
- GLint ready( 0 );
- while( !ready )
+ GLint ready = 0;
+ ext->glGetQueryObjectiv( tr->_id, GL_QUERY_RESULT_AVAILABLE, &ready );
+ if (ready)
{
- // Apparently, must actually sleep here to avoid issues w/ NVIDIA Quadro.
- OpenThreads::Thread::microSleep( 5 );
- ext->glGetQueryObjectiv( tr->_id, GL_QUERY_RESULT_AVAILABLE, &ready );
- };
-#endif
-
- ext->glGetQueryObjectiv( tr->_id, GL_QUERY_RESULT, &(tr->_numPixels) );
- if (tr->_numPixels < 0)
- OSG_WARN << "osgOQ: RQCB: " <<
- "glGetQueryObjectiv returned negative value (" << tr->_numPixels << ")." << std::endl;
-
- // Either retrieve last frame's results, or ignore it because the
- // camera is inside the view. In either case, _active is now false.
- tr->_active = false;
+ ext->glGetQueryObjectiv( tr->_id, GL_QUERY_RESULT, &(tr->_numPixels) );
+ if (tr->_numPixels < 0)
+ OSG_WARN << "osgOQ: RQCB: " <<
+ "glGetQueryObjectiv returned negative value (" << tr->_numPixels << ")." << std::endl;
+
+ // Either retrieve last frame's results, or ignore it because the
+ // camera is inside the view. In either case, _active is now false.
+ tr->_active = false;
+ }
+ // else: query result not available yet, try again next frame
it++;
count++;
@@ -196,7 +185,13 @@ struct RetrieveQueriesCallback : public osg::Camera::DrawCallback
void reset()
{
- _results.clear();
+ for (ResultsVector::iterator it = _results.begin(); it != _results.end();)
+ {
+ if (!(*it)->_active || !(*it)->_init) // remove results that have already been retrieved or their query objects deleted.
+ it = _results.erase(it);
+ else
+ ++it;
+ }
}
void add( osg::TestResult* tr )
@@ -264,9 +259,9 @@ QueryGeometry::reset()
ResultMap::iterator it = _results.begin();
while (it != _results.end())
{
- TestResult& tr = it->second;
- if (tr._init)
- QueryGeometry::deleteQueryObject( tr._contextID, tr._id );
+ osg::ref_ptr<TestResult> tr = it->second;
+ if (tr->_init)
+ QueryGeometry::deleteQueryObject( tr->_contextID, tr->_id );
it++;
}
_results.clear();
@@ -294,10 +289,30 @@ QueryGeometry::drawImplementation( osg::RenderInfo& renderInfo ) const
}
// Get TestResult from Camera map
- TestResult* tr;
+ osg::ref_ptr<osg::TestResult> tr;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock( _mapMutex );
- tr = &( _results[ cam ] );
+ tr = ( _results[ cam ] );
+ if (!tr.valid())
+ {
+ tr = new osg::TestResult;
+ _results[ cam ] = tr;
+ }
+ }
+
+
+ // Issue query
+ if (!tr->_init)
+ {
+ ext->glGenQueries( 1, &(tr->_id) );
+ tr->_contextID = contextID;
+ tr->_init = true;
+ }
+
+ if (tr->_active)
+ {
+ // last query hasn't been retrieved yet
+ return;
}
// Add TestResult to RQCB.
@@ -310,15 +325,6 @@ QueryGeometry::drawImplementation( osg::RenderInfo& renderInfo ) const
}
rqcb->add( tr );
-
- // Issue query
- if (!tr->_init)
- {
- ext->glGenQueries( 1, &(tr->_id) );
- tr->_contextID = contextID;
- tr->_init = true;
- }
-
OSG_DEBUG <<
"osgOQ: QG: Querying for: " << _oqnName << std::endl;
@@ -349,12 +355,17 @@ QueryGeometry::drawImplementation( osg::RenderInfo& renderInfo ) const
unsigned int
QueryGeometry::getNumPixels( const osg::Camera* cam )
{
- TestResult tr;
+ osg::ref_ptr<osg::TestResult> tr;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock( _mapMutex );
tr = _results[ cam ];
+ if (!tr.valid())
+ {
+ tr = new osg::TestResult;
+ _results[ cam ] = tr;
+ }
}
- return tr._numPixels;
+ return tr->_numPixels;
}
@@ -375,11 +386,11 @@ QueryGeometry::releaseGLObjects( osg::State* state ) const
ResultMap::iterator it = _results.begin();
while (it != _results.end())
{
- TestResult& tr = it->second;
- if (tr._contextID == contextID)
+ osg::ref_ptr<osg::TestResult> tr = it->second;
+ if (tr->_contextID == contextID)
{
- QueryGeometry::deleteQueryObject( contextID, tr._id );
- tr._init = false;
+ QueryGeometry::deleteQueryObject( contextID, tr->_id );
+ tr->_init = false;
}
it++;
}
......@@ -3,3 +3,4 @@ check__FreeBSD_kernel__
no-xine-malloc-aligned.diff
ffmpeg_2.9.patch
0005-Bas-Couwenberg-s-patches-for-Hurd.patch
0006-Occlusion-Queries-Stuttering-fix-from-upstream.patch
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment