Fix for leaking occlusion queries -- try not to hold onto so many stale occlusion query references.

meow-7.2.2
Dave Parks 2011-01-21 18:25:57 -06:00
parent 4fefb98cba
commit d7db673dc7
3 changed files with 61 additions and 5 deletions

View File

@ -64,6 +64,12 @@ const F32 SG_OCCLUSION_FUDGE = 0.25f;
static U32 sZombieGroups = 0;
U32 LLSpatialGroup::sNodeCount = 0;
#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0
std::set<GLuint> LLSpatialGroup::sPendingQueries;
BOOL LLSpatialGroup::sNoDelete = FALSE;
static F32 sLastMaxTexPriority = 1.f;
@ -81,6 +87,9 @@ protected:
virtual void releaseName(GLuint name)
{
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
LLSpatialGroup::sPendingQueries.erase(name);
#endif
glDeleteQueriesARB(1, &name);
}
};
@ -361,9 +370,15 @@ LLSpatialGroup::~LLSpatialGroup()
sNodeCount--;
if (gGLManager.mHasOcclusionQuery && mOcclusionQuery[LLViewerCamera::sCurCameraID])
if (gGLManager.mHasOcclusionQuery)
{
sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i)
{
if (mOcclusionQuery[i])
{
sQueryPool.release(mOcclusionQuery[i]);
}
}
}
mOcclusionVerts = NULL;
@ -1096,12 +1111,23 @@ void LLSpatialGroup::setOcclusionState(U32 state, S32 mode)
for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
{
mOcclusionState[i] |= state;
if ((state & DISCARD_QUERY) && mOcclusionQuery[i])
{
sQueryPool.release(mOcclusionQuery[i]);
mOcclusionQuery[i] = 0;
}
}
}
}
else
{
mOcclusionState[LLViewerCamera::sCurCameraID] |= state;
if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
{
sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
}
}
}
@ -1540,15 +1566,31 @@ void LLSpatialGroup::checkOcclusion()
{ //otherwise, if a query is pending, read it back
GLuint available = 0;
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
{
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
}
else
{
available = 1;
}
if (available)
{ //result is available, read it back, otherwise wait until next frame
GLuint res = 1;
if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
{
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res);
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
#endif
}
else if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
{ //delete the query to avoid holding onto hundreds of pending queries
sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
}
if (isOcclusionState(DISCARD_QUERY))
{
res = 2;
@ -1621,6 +1663,13 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
}
#if !LL_DARWIN
U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB;
#else
U32 mode = GL_SAMPLES_PASSED_ARB;
#endif
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
#endif
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
@ -1637,7 +1686,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
}
glEndQueryARB(mode);
#endif
if (use_depth_clamp)
{
glDisable(GL_DEPTH_CLAMP);

View File

@ -187,6 +187,7 @@ public:
return *this;
}
static std::set<GLuint> sPendingQueries; //pending occlusion queries
static U32 sNodeCount;
static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE

View File

@ -497,6 +497,12 @@ public:
ypos += y_inc;
if (!LLSpatialGroup::sPendingQueries.empty())
{
addText(xpos,ypos, llformat("%d Queries pending", LLSpatialGroup::sPendingQueries.size()));
ypos += y_inc;
}
addText(xpos,ypos, llformat("%d Avatars visible", LLVOAvatar::sNumVisibleAvatars));