diff options
Diffstat (limited to 'gpu/command_buffer/service/query_manager.cc')
-rw-r--r-- | gpu/command_buffer/service/query_manager.cc | 239 |
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 |