Commit bcb4c68d by Geoff Lang Committed by Commit Bot

StateManagerGL: Rework query tracking (again)

* Put the temporarily paused queries into a separate map, this should be separate functionality from the regular query tracking. * Pair down the number of functions that modify the current begin/end state. * Always pause all old queries and resume all new queries on context switch. BUG=805233 Change-Id: If37a9947b50feaa4e627070ce2a7895aa5034c0e Reviewed-on: https://chromium-review.googlesource.com/902426 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent a8fe18fc
......@@ -67,11 +67,17 @@ StandardQueryGL::StandardQueryGL(GLenum type,
StandardQueryGL::~StandardQueryGL()
{
mStateManager->deleteQuery(mActiveQuery);
mStateManager->onDeleteQueryObject(this);
if (mActiveQuery != 0)
{
mStateManager->endQuery(mType, this, mActiveQuery);
mFunctions->deleteQueries(1, &mActiveQuery);
mActiveQuery = 0;
}
while (!mPendingQueries.empty())
{
mStateManager->deleteQuery(mPendingQueries.front());
GLuint id = mPendingQueries.front();
mFunctions->deleteQueries(1, &id);
mPendingQueries.pop_front();
}
}
......@@ -79,7 +85,6 @@ StandardQueryGL::~StandardQueryGL()
gl::Error StandardQueryGL::begin()
{
mResultSum = 0;
mStateManager->onBeginQuery(this);
return resume();
}
......@@ -157,7 +162,7 @@ gl::Error StandardQueryGL::pause()
{
if (mActiveQuery != 0)
{
mStateManager->endQuery(mType, mActiveQuery);
mStateManager->endQuery(mType, this, mActiveQuery);
mPendingQueries.push_back(mActiveQuery);
mActiveQuery = 0;
......@@ -185,7 +190,7 @@ gl::Error StandardQueryGL::resume()
}
mFunctions->genQueries(1, &mActiveQuery);
mStateManager->beginQuery(mType, mActiveQuery);
mStateManager->beginQuery(mType, this, mActiveQuery);
}
return gl::NoError();
......@@ -222,7 +227,7 @@ gl::Error StandardQueryGL::flush(bool force)
mResultSum = MergeQueryResults(mType, mResultSum, static_cast<GLuint64>(result));
}
mStateManager->deleteQuery(id);
mFunctions->deleteQueries(1, &id);
mPendingQueries.pop_front();
}
......
......@@ -87,7 +87,6 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
mTransformFeedback(0),
mCurrentTransformFeedback(nullptr),
mQueries(),
mCurrentQueries(),
mPrevDrawContext(0),
mUnpackAlignment(4),
mUnpackRowLength(0),
......@@ -190,7 +189,8 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
for (GLenum queryType : QueryTypes)
{
mQueries[queryType] = 0;
mQueries[queryType] = nullptr;
mTemporaryPausedQueries[queryType] = nullptr;
}
// Initialize point sprite state for desktop GL
......@@ -364,22 +364,6 @@ void StateManagerGL::deleteTransformFeedback(GLuint transformFeedback)
}
}
void StateManagerGL::deleteQuery(GLuint query)
{
if (query != 0)
{
for (auto &activeQuery : mQueries)
{
GLuint activeQueryID = activeQuery.second;
if (activeQueryID == query)
{
GLenum type = activeQuery.first;
endQuery(type, query);
}
}
}
}
void StateManagerGL::useProgram(GLuint program)
{
if (mProgram != program)
......@@ -664,34 +648,25 @@ void StateManagerGL::onTransformFeedbackStateChange()
mLocalDirtyBits.set(gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
}
void StateManagerGL::beginQuery(GLenum type, GLuint query)
void StateManagerGL::beginQuery(GLenum type, QueryGL *queryObject, GLuint queryId)
{
// Make sure this is a valid query type and there is no current active query of this type
ASSERT(mQueries.find(type) != mQueries.end());
ASSERT(mQueries[type] == 0);
ASSERT(query != 0);
ASSERT(mQueries[type] == nullptr);
ASSERT(queryId != 0);
mQueries[type] = query;
mFunctions->beginQuery(type, query);
mQueries[type] = queryObject;
mFunctions->beginQuery(type, queryId);
}
void StateManagerGL::endQuery(GLenum type, GLuint query)
void StateManagerGL::endQuery(GLenum type, QueryGL *queryObject, GLuint queryId)
{
ASSERT(mQueries[type] == query);
mQueries[type] = 0;
ASSERT(queryObject != nullptr);
ASSERT(mQueries[type] == queryObject);
mQueries[type] = nullptr;
mFunctions->endQuery(type);
}
void StateManagerGL::onBeginQuery(QueryGL *query)
{
mCurrentQueries.insert(query);
}
void StateManagerGL::onDeleteQueryObject(QueryGL *query)
{
mCurrentQueries.erase(query);
}
gl::Error StateManagerGL::setDrawArraysState(const gl::Context *context,
GLint first,
GLsizei count,
......@@ -775,43 +750,60 @@ void StateManagerGL::pauseTransformFeedback()
gl::Error StateManagerGL::pauseAllQueries()
{
for (QueryGL *prevQuery : mCurrentQueries)
for (auto &prevQuery : mQueries)
{
ANGLE_TRY(prevQuery->pause());
if (prevQuery.second)
{
ANGLE_TRY(prevQuery.second->pause());
mTemporaryPausedQueries[prevQuery.first] = prevQuery.second;
prevQuery.second = nullptr;
}
}
return gl::NoError();
}
gl::Error StateManagerGL::pauseQuery(GLenum type)
{
for (QueryGL *prevQuery : mCurrentQueries)
ASSERT(mQueries.find(type) != mQueries.end());
ASSERT(mTemporaryPausedQueries.find(type) == mQueries.end());
QueryGL *prevQuery = mQueries[type];
if (prevQuery)
{
if (prevQuery->getType() == type)
{
ANGLE_TRY(prevQuery->pause());
}
ANGLE_TRY(prevQuery->pause());
mTemporaryPausedQueries[type] = prevQuery;
mQueries[type] = nullptr;
}
return gl::NoError();
}
gl::Error StateManagerGL::resumeAllQueries()
{
for (QueryGL *prevQuery : mCurrentQueries)
for (auto &pausedQuery : mTemporaryPausedQueries)
{
ANGLE_TRY(prevQuery->resume());
if (pausedQuery.second)
{
ASSERT(mQueries[pausedQuery.first] == nullptr);
ANGLE_TRY(pausedQuery.second->resume());
pausedQuery.second = nullptr;
}
}
return gl::NoError();
}
gl::Error StateManagerGL::resumeQuery(GLenum type)
{
for (QueryGL *prevQuery : mCurrentQueries)
ASSERT(mQueries.find(type) != mQueries.end());
ASSERT(mTemporaryPausedQueries.find(type) != mTemporaryPausedQueries.end());
QueryGL *pausedQuery = mTemporaryPausedQueries[type];
if (pausedQuery)
{
if (prevQuery->getType() == type)
{
ANGLE_TRY(prevQuery->resume());
}
ANGLE_TRY(pausedQuery->resume());
mTemporaryPausedQueries[type] = nullptr;
}
return gl::NoError();
}
......@@ -819,28 +811,38 @@ gl::Error StateManagerGL::onMakeCurrent(const gl::Context *context)
{
const gl::State &glState = context->getGLState();
// If the context has changed, pause the previous context's queries
auto contextID = context->getContextState().getContextID();
if (contextID != mPrevDrawContext)
#if defined(ANGLE_ENABLE_ASSERTS)
// Temporarily pausing queries during context switch is not supported
for (auto &pausedQuery : mTemporaryPausedQueries)
{
ANGLE_TRY(pauseAllQueries());
ASSERT(pausedQuery.second == nullptr);
}
mCurrentQueries.clear();
onTransformFeedbackStateChange();
mPrevDrawContext = contextID;
#endif
// Set the current query state
for (GLenum queryType : QueryTypes)
// If the context has changed, pause the previous context's queries
auto contextID = context->getContextState().getContextID();
if (contextID != mPrevDrawContext)
{
gl::Query *query = glState.getActiveQuery(queryType);
if (query != nullptr)
for (auto &currentQuery : mQueries)
{
QueryGL *queryGL = GetImplAs<QueryGL>(query);
ANGLE_TRY(queryGL->resume());
// Pause any old query object
if (currentQuery.second)
{
ANGLE_TRY(currentQuery.second->pause());
currentQuery.second = nullptr;
}
mCurrentQueries.insert(queryGL);
// Check if this new context needs to resume a query
gl::Query *newQuery = glState.getActiveQuery(currentQuery.first);
if (newQuery != nullptr)
{
QueryGL *queryGL = GetImplAs<QueryGL>(newQuery);
ANGLE_TRY(queryGL->resume());
}
}
}
onTransformFeedbackStateChange();
mPrevDrawContext = contextID;
// Seamless cubemaps are required for ES3 and higher contexts. It should be the cheapest to set
// this state here since MakeCurrent is expected to be called less frequently than draw calls.
......
......@@ -50,7 +50,6 @@ class StateManagerGL final : angle::NonCopyable
void deleteFramebuffer(GLuint fbo);
void deleteRenderbuffer(GLuint rbo);
void deleteTransformFeedback(GLuint transformFeedback);
void deleteQuery(GLuint query);
void useProgram(GLuint program);
void forceUseProgram(GLuint program);
......@@ -76,8 +75,8 @@ class StateManagerGL final : angle::NonCopyable
void bindRenderbuffer(GLenum type, GLuint renderbuffer);
void bindTransformFeedback(GLenum type, GLuint transformFeedback);
void onTransformFeedbackStateChange();
void beginQuery(GLenum type, GLuint query);
void endQuery(GLenum type, GLuint query);
void beginQuery(GLenum type, QueryGL *queryObject, GLuint queryId);
void endQuery(GLenum type, QueryGL *queryObject, GLuint queryId);
void onBeginQuery(QueryGL *query);
void setAttributeCurrentData(size_t index, const gl::VertexAttribCurrentValueData &data);
......@@ -154,8 +153,6 @@ class StateManagerGL final : angle::NonCopyable
void setPathRenderingProjectionMatrix(const GLfloat *m);
void setPathRenderingStencilState(GLenum func, GLint ref, GLuint mask);
void onDeleteQueryObject(QueryGL *query);
gl::Error setDrawArraysState(const gl::Context *context,
GLint first,
GLsizei count,
......@@ -255,8 +252,13 @@ class StateManagerGL final : angle::NonCopyable
GLuint mTransformFeedback;
TransformFeedbackGL *mCurrentTransformFeedback;
std::map<GLenum, GLuint> mQueries;
std::set<QueryGL *> mCurrentQueries;
// Queries that are currently running on the driver
std::map<GLenum, QueryGL *> mQueries;
// Queries that are temporarily in the paused state so that their results will not be affected
// by other operations
std::map<GLenum, QueryGL *> mTemporaryPausedQueries;
gl::ContextID mPrevDrawContext;
GLint mUnpackAlignment;
......
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