summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service/query_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/command_buffer/service/query_manager.cc')
-rw-r--r--gpu/command_buffer/service/query_manager.cc239
1 files changed, 194 insertions, 45 deletions
diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc
index 81f7747..09bad18 100644
--- a/gpu/command_buffer/service/query_manager.cc
+++ b/gpu/command_buffer/service/query_manager.cc
@@ -67,6 +67,8 @@ class AsyncPixelTransfersCompletedQuery
bool Begin() override;
bool End(base::subtle::Atomic32 submit_count) override;
bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+ void Pause() override;
+ void Resume() override;
bool Process(bool did_finish) override;
void Destroy(bool have_context) override;
@@ -82,9 +84,18 @@ AsyncPixelTransfersCompletedQuery::AsyncPixelTransfersCompletedQuery(
}
bool AsyncPixelTransfersCompletedQuery::Begin() {
+ MarkAsActive();
return true;
}
+void AsyncPixelTransfersCompletedQuery::Pause() {
+ MarkAsPaused();
+}
+
+void AsyncPixelTransfersCompletedQuery::Resume() {
+ MarkAsActive();
+}
+
bool AsyncPixelTransfersCompletedQuery::End(
base::subtle::Atomic32 submit_count) {
// Get the real shared memory since it might need to be duped to prevent
@@ -146,11 +157,12 @@ AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() {
class AllSamplesPassedQuery : public QueryManager::Query {
public:
AllSamplesPassedQuery(
- QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset,
- GLuint service_id);
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
bool Begin() override;
bool End(base::subtle::Atomic32 submit_count) override;
bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+ void Pause() override;
+ void Resume() override;
bool Process(bool did_finish) override;
void Destroy(bool have_context) override;
@@ -159,18 +171,26 @@ class AllSamplesPassedQuery : public QueryManager::Query {
private:
// Service side query id.
- GLuint service_id_;
+ std::vector<GLuint> service_ids_;
};
AllSamplesPassedQuery::AllSamplesPassedQuery(
- QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset,
- GLuint service_id)
- : Query(manager, target, shm_id, shm_offset),
- service_id_(service_id) {
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
+ : Query(manager, target, shm_id, shm_offset) {
+ GLuint service_id = 0;
+ glGenQueries(1, &service_id);
+ DCHECK_NE(0u, service_id);
+ service_ids_.push_back(service_id);
}
bool AllSamplesPassedQuery::Begin() {
- BeginQueryHelper(target(), service_id_);
+ MarkAsActive();
+ // Delete all but the first one when beginning a new query.
+ if (service_ids_.size() > 1) {
+ glDeleteQueries(service_ids_.size() - 1, &service_ids_[1]);
+ service_ids_.resize(1);
+ }
+ BeginQueryHelper(target(), service_ids_.back());
return true;
}
@@ -184,23 +204,41 @@ bool AllSamplesPassedQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
return false;
}
+void AllSamplesPassedQuery::Pause() {
+ MarkAsPaused();
+ EndQueryHelper(target());
+}
+
+void AllSamplesPassedQuery::Resume() {
+ MarkAsActive();
+
+ GLuint service_id = 0;
+ glGenQueries(1, &service_id);
+ DCHECK_NE(0u, service_id);
+ service_ids_.push_back(service_id);
+ BeginQueryHelper(target(), service_ids_.back());
+}
+
bool AllSamplesPassedQuery::Process(bool did_finish) {
GLuint available = 0;
glGetQueryObjectuiv(
- service_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
+ service_ids_.back(), GL_QUERY_RESULT_AVAILABLE_EXT, &available);
if (!available) {
return true;
}
- GLuint result = 0;
- glGetQueryObjectuiv(
- service_id_, GL_QUERY_RESULT_EXT, &result);
-
- return MarkAsCompleted(result != 0);
+ for (const GLuint& service_id : service_ids_) {
+ GLuint result = 0;
+ glGetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, &result);
+ if (result != 0)
+ return MarkAsCompleted(1);
+ }
+ return MarkAsCompleted(0);
}
void AllSamplesPassedQuery::Destroy(bool have_context) {
if (have_context && !IsDeleted()) {
- glDeleteQueries(1, &service_id_);
+ glDeleteQueries(service_ids_.size(), &service_ids_[0]);
+ service_ids_.clear();
MarkAsDeleted();
}
}
@@ -216,6 +254,8 @@ class CommandsIssuedQuery : public QueryManager::Query {
bool Begin() override;
bool End(base::subtle::Atomic32 submit_count) override;
bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+ void Pause() override;
+ void Resume() override;
bool Process(bool did_finish) override;
void Destroy(bool have_context) override;
@@ -232,12 +272,21 @@ CommandsIssuedQuery::CommandsIssuedQuery(
}
bool CommandsIssuedQuery::Begin() {
+ MarkAsActive();
begin_time_ = base::TimeTicks::Now();
return true;
}
+void CommandsIssuedQuery::Pause() {
+ MarkAsPaused();
+}
+
+void CommandsIssuedQuery::Resume() {
+ MarkAsActive();
+}
+
bool CommandsIssuedQuery::End(base::subtle::Atomic32 submit_count) {
- base::TimeDelta elapsed = base::TimeTicks::Now() - begin_time_;
+ const base::TimeDelta elapsed = base::TimeTicks::Now() - begin_time_;
MarkAsPending(submit_count);
return MarkAsCompleted(elapsed.InMicroseconds());
}
@@ -269,6 +318,8 @@ class CommandLatencyQuery : public QueryManager::Query {
bool Begin() override;
bool End(base::subtle::Atomic32 submit_count) override;
bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+ void Pause() override;
+ void Resume() override;
bool Process(bool did_finish) override;
void Destroy(bool have_context) override;
@@ -282,7 +333,16 @@ CommandLatencyQuery::CommandLatencyQuery(
}
bool CommandLatencyQuery::Begin() {
- return true;
+ MarkAsActive();
+ return true;
+}
+
+void CommandLatencyQuery::Pause() {
+ MarkAsPaused();
+}
+
+void CommandLatencyQuery::Resume() {
+ MarkAsActive();
}
bool CommandLatencyQuery::End(base::subtle::Atomic32 submit_count) {
@@ -321,6 +381,8 @@ class AsyncReadPixelsCompletedQuery
bool Begin() override;
bool End(base::subtle::Atomic32 submit_count) override;
bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+ void Pause() override;
+ void Resume() override;
bool Process(bool did_finish) override;
void Destroy(bool have_context) override;
@@ -329,21 +391,28 @@ class AsyncReadPixelsCompletedQuery
~AsyncReadPixelsCompletedQuery() override;
private:
- bool completed_;
bool complete_result_;
};
AsyncReadPixelsCompletedQuery::AsyncReadPixelsCompletedQuery(
QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
: Query(manager, target, shm_id, shm_offset),
- completed_(false),
complete_result_(false) {
}
bool AsyncReadPixelsCompletedQuery::Begin() {
+ MarkAsActive();
return true;
}
+void AsyncReadPixelsCompletedQuery::Pause() {
+ MarkAsPaused();
+}
+
+void AsyncReadPixelsCompletedQuery::Resume() {
+ MarkAsActive();
+}
+
bool AsyncReadPixelsCompletedQuery::End(base::subtle::Atomic32 submit_count) {
if (!AddToPendingQueue(submit_count)) {
return false;
@@ -362,12 +431,11 @@ bool AsyncReadPixelsCompletedQuery::QueryCounter(
}
void AsyncReadPixelsCompletedQuery::Complete() {
- completed_ = true;
complete_result_ = MarkAsCompleted(1);
}
bool AsyncReadPixelsCompletedQuery::Process(bool did_finish) {
- return !completed_ || complete_result_;
+ return !IsFinished() || complete_result_;
}
void AsyncReadPixelsCompletedQuery::Destroy(bool /* have_context */) {
@@ -388,6 +456,8 @@ class GetErrorQuery : public QueryManager::Query {
bool Begin() override;
bool End(base::subtle::Atomic32 submit_count) override;
bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+ void Pause() override;
+ void Resume() override;
bool Process(bool did_finish) override;
void Destroy(bool have_context) override;
@@ -403,9 +473,18 @@ GetErrorQuery::GetErrorQuery(
}
bool GetErrorQuery::Begin() {
+ MarkAsActive();
return true;
}
+void GetErrorQuery::Pause() {
+ MarkAsPaused();
+}
+
+void GetErrorQuery::Resume() {
+ MarkAsActive();
+}
+
bool GetErrorQuery::End(base::subtle::Atomic32 submit_count) {
MarkAsPending(submit_count);
return MarkAsCompleted(manager()->decoder()->GetErrorState()->GetGLError());
@@ -441,6 +520,8 @@ class CommandsCompletedQuery : public QueryManager::Query {
bool Begin() override;
bool End(base::subtle::Atomic32 submit_count) override;
bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+ void Pause() override;
+ void Resume() override;
bool Process(bool did_finish) override;
void Destroy(bool have_context) override;
@@ -459,10 +540,19 @@ CommandsCompletedQuery::CommandsCompletedQuery(QueryManager* manager,
: Query(manager, target, shm_id, shm_offset) {}
bool CommandsCompletedQuery::Begin() {
+ MarkAsActive();
begin_time_ = base::TimeTicks::Now();
return true;
}
+void CommandsCompletedQuery::Pause() {
+ MarkAsPaused();
+}
+
+void CommandsCompletedQuery::Resume() {
+ MarkAsActive();
+}
+
bool CommandsCompletedQuery::End(base::subtle::Atomic32 submit_count) {
fence_.reset(gfx::GLFence::Create());
DCHECK(fence_);
@@ -481,7 +571,7 @@ bool CommandsCompletedQuery::Process(bool did_finish) {
if (!did_finish && fence_ && !fence_->HasCompleted())
return true;
- base::TimeDelta elapsed = base::TimeTicks::Now() - begin_time_;
+ const base::TimeDelta elapsed = base::TimeTicks::Now() - begin_time_;
return MarkAsCompleted(elapsed.InMicroseconds());
}
@@ -505,6 +595,8 @@ class TimeElapsedQuery : public QueryManager::Query {
bool Begin() override;
bool End(base::subtle::Atomic32 submit_count) override;
bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+ void Pause() override;
+ void Resume() override;
bool Process(bool did_finish) override;
void Destroy(bool have_context) override;
@@ -520,9 +612,11 @@ TimeElapsedQuery::TimeElapsedQuery(QueryManager* manager,
int32 shm_id,
uint32 shm_offset)
: Query(manager, target, shm_id, shm_offset),
- gpu_timer_(manager->CreateGPUTimer(true)) {}
+ gpu_timer_(manager->CreateGPUTimer(true)) {
+}
bool TimeElapsedQuery::Begin() {
+ MarkAsActive();
gpu_timer_->Start();
return true;
}
@@ -537,20 +631,25 @@ bool TimeElapsedQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
return false;
}
+void TimeElapsedQuery::Pause() {
+ MarkAsPaused();
+}
+
+void TimeElapsedQuery::Resume() {
+ MarkAsActive();
+}
+
bool TimeElapsedQuery::Process(bool did_finish) {
if (!gpu_timer_->IsAvailable())
return true;
- const uint64_t nano_seconds =
- gpu_timer_->GetDeltaElapsed() * base::Time::kNanosecondsPerMicrosecond;
+ const uint64_t nano_seconds = gpu_timer_->GetDeltaElapsed() *
+ base::Time::kNanosecondsPerMicrosecond;
return MarkAsCompleted(nano_seconds);
}
void TimeElapsedQuery::Destroy(bool have_context) {
- if (gpu_timer_.get()) {
- gpu_timer_->Destroy(have_context);
- gpu_timer_.reset();
- }
+ gpu_timer_->Destroy(have_context);
}
TimeElapsedQuery::~TimeElapsedQuery() {}
@@ -566,6 +665,8 @@ class TimeStampQuery : public QueryManager::Query {
bool Begin() override;
bool End(base::subtle::Atomic32 submit_count) override;
bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+ void Pause() override;
+ void Resume() override;
bool Process(bool did_finish) override;
void Destroy(bool have_context) override;
@@ -593,7 +694,16 @@ bool TimeStampQuery::End(base::subtle::Atomic32 submit_count) {
return false;
}
+void TimeStampQuery::Pause() {
+ MarkAsPaused();
+}
+
+void TimeStampQuery::Resume() {
+ MarkAsActive();
+}
+
bool TimeStampQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
+ MarkAsActive();
gpu_timer_->QueryTimeStamp();
return AddToPendingQueue(submit_count);
}
@@ -692,11 +802,7 @@ QueryManager::Query* QueryManager::CreateQuery(
query = new TimeStampQuery(this, target, shm_id, shm_offset);
break;
default: {
- GLuint service_id = 0;
- glGenQueries(1, &service_id);
- DCHECK_NE(0u, service_id);
- query = new AllSamplesPassedQuery(
- this, target, shm_id, shm_offset, service_id);
+ query = new AllSamplesPassedQuery(this, target, shm_id, shm_offset);
break;
}
}
@@ -726,16 +832,30 @@ bool QueryManager::IsValidQuery(GLuint id) {
return it != generated_query_ids_.end();
}
-QueryManager::Query* QueryManager::GetQuery(
- GLuint client_id) {
+QueryManager::Query* QueryManager::GetQuery(GLuint client_id) {
QueryMap::iterator it = queries_.find(client_id);
- return it != queries_.end() ? it->second.get() : NULL;
+ return it != queries_.end() ? it->second.get() : nullptr;
+}
+
+QueryManager::Query* QueryManager::GetActiveQuery(GLenum target) {
+ ActiveQueryMap::iterator it = active_queries_.find(target);
+ return it != active_queries_.end() ? it->second.get() : nullptr;
}
void QueryManager::RemoveQuery(GLuint client_id) {
QueryMap::iterator it = queries_.find(client_id);
if (it != queries_.end()) {
Query* query = it->second.get();
+
+ // Remove from active query map if it is active.
+ ActiveQueryMap::iterator active_it = active_queries_.find(query->target());
+ bool is_active = (active_it != active_queries_.end() &&
+ query == active_it->second.get());
+ DCHECK(is_active == query->IsActive());
+ if (is_active)
+ active_queries_.erase(active_it);
+
+ query->Destroy(true);
RemovePendingQuery(query);
query->MarkAsDeleted();
queries_.erase(it);
@@ -790,7 +910,7 @@ QueryManager::Query::Query(
shm_id_(shm_id),
shm_offset_(shm_offset),
submit_count_(0),
- pending_(false),
+ query_state_(kQueryState_Initialize),
deleted_(false) {
DCHECK(manager);
manager_->StartTracking(this);
@@ -804,7 +924,7 @@ void QueryManager::Query::RunCallbacks() {
}
void QueryManager::Query::AddCallback(base::Closure callback) {
- if (pending_) {
+ if (query_state_ == kQueryState_Pending) {
callbacks_.push_back(callback);
} else {
callback.Run();
@@ -823,14 +943,13 @@ QueryManager::Query::~Query() {
}
bool QueryManager::Query::MarkAsCompleted(uint64 result) {
- DCHECK(pending_);
+ UnmarkAsPending();
QuerySync* sync = manager_->decoder_->GetSharedMemoryAs<QuerySync*>(
shm_id_, shm_offset_, sizeof(*sync));
if (!sync) {
return false;
}
- pending_ = false;
sync->result = result;
base::subtle::Release_Store(&sync->process_count, submit_count_);
@@ -843,7 +962,7 @@ bool QueryManager::ProcessPendingQueries(bool did_finish) {
if (!query->Process(did_finish)) {
return false;
}
- if (query->pending()) {
+ if (query->IsPending()) {
break;
}
query->RunCallbacks();
@@ -865,7 +984,7 @@ bool QueryManager::ProcessPendingTransferQueries() {
if (!query->Process(false)) {
return false;
}
- if (query->pending()) {
+ if (query->IsPending()) {
break;
}
query->RunCallbacks();
@@ -906,7 +1025,7 @@ bool QueryManager::AddPendingTransferQuery(
bool QueryManager::RemovePendingQuery(Query* query) {
DCHECK(query);
- if (query->pending()) {
+ if (query->IsPending()) {
// TODO(gman): Speed this up if this is a common operation. This would only
// happen if you do being/end begin/end on the same query without waiting
// for the first one to finish.
@@ -936,7 +1055,12 @@ bool QueryManager::BeginQuery(Query* query) {
if (!RemovePendingQuery(query)) {
return false;
}
- return query->Begin();
+ if (query->Begin()) {
+ active_queries_[query->target()] = query;
+ return true;
+ }
+
+ return false;
}
bool QueryManager::EndQuery(Query* query, base::subtle::Atomic32 submit_count) {
@@ -944,6 +1068,13 @@ bool QueryManager::EndQuery(Query* query, base::subtle::Atomic32 submit_count) {
if (!RemovePendingQuery(query)) {
return false;
}
+
+ // Remove from active query map if it is active.
+ ActiveQueryMap::iterator active_it = active_queries_.find(query->target());
+ DCHECK(active_it != active_queries_.end());
+ DCHECK(query == active_it->second.get());
+ active_queries_.erase(active_it);
+
return query->End(submit_count);
}
@@ -953,5 +1084,23 @@ bool QueryManager::QueryCounter(
return query->QueryCounter(submit_count);
}
+void QueryManager::PauseQueries() {
+ for (std::pair<const GLenum, scoped_refptr<Query> >& it : active_queries_) {
+ if (it.second->IsActive()) {
+ it.second->Pause();
+ DCHECK(it.second->IsPaused());
+ }
+ }
+}
+
+void QueryManager::ResumeQueries() {
+ for (std::pair<const GLenum, scoped_refptr<Query> >& it : active_queries_) {
+ if (it.second->IsPaused()) {
+ it.second->Resume();
+ DCHECK(it.second->IsActive());
+ }
+ }
+}
+
} // namespace gles2
} // namespace gpu