Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Unified Diff: gpu/command_buffer/service/query_manager.cc

Issue 9694025: Add support for GL_COMMANDS_ISSUED_CHROMIUM fence like query. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add cast for std::min Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gpu/command_buffer/service/query_manager.h ('k') | gpu/command_buffer/service/query_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gpu/command_buffer/service/query_manager.cc
diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc
index baad7f66f9c440743cf42ffcde90df828c1cae9f..c8f06a3e35ebb6551d5e8041e2373ffe9da04ede 100644
--- a/gpu/command_buffer/service/query_manager.cc
+++ b/gpu/command_buffer/service/query_manager.cc
@@ -5,14 +5,123 @@
#include "gpu/command_buffer/service/query_manager.h"
#include "base/atomicops.h"
#include "base/logging.h"
+#include "base/time.h"
#include "gpu/command_buffer/common/gles2_cmd_format.h"
#include "gpu/command_buffer/service/common_decoder.h"
namespace gpu {
namespace gles2 {
-QueryManager::QueryManager()
- : query_count_(0) {
+class AllSamplesPassedQuery : public QueryManager::Query {
+ public:
+ AllSamplesPassedQuery(
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset,
+ GLuint service_id);
+ virtual ~AllSamplesPassedQuery();
+ virtual bool Begin() OVERRIDE;
+ virtual bool End(uint32 submit_count) OVERRIDE;
+ virtual bool Process() OVERRIDE;
+ virtual void Destroy(bool have_context) OVERRIDE;
+
+ private:
+ // Service side query id.
+ GLuint service_id_;
+};
+
+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) {
+}
+
+AllSamplesPassedQuery::~AllSamplesPassedQuery() {
+}
+
+void AllSamplesPassedQuery::Destroy(bool have_context) {
+ if (have_context && !IsDeleted()) {
+ glDeleteQueriesARB(1, &service_id_);
+ MarkAsDeleted();
+ }
+}
+
+bool AllSamplesPassedQuery::Begin() {
+ BeginQueryHelper(target(), service_id_);
+ return true;
+}
+
+bool AllSamplesPassedQuery::End(uint32 submit_count) {
+ EndQueryHelper(target());
+ return AddToPendingQueue(submit_count);
+}
+
+bool AllSamplesPassedQuery::Process() {
+ GLuint available = 0;
+ glGetQueryObjectuivARB(
+ service_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
+ if (!available) {
+ return true;
+ }
+ GLuint result = 0;
+ glGetQueryObjectuivARB(
+ service_id_, GL_QUERY_RESULT_EXT, &result);
+
+ return MarkAsCompleted(result);
+}
+
+class CommandsIssuedQuery : public QueryManager::Query {
+ public:
+ CommandsIssuedQuery(
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
+ virtual ~CommandsIssuedQuery();
+
+ virtual bool Begin() OVERRIDE;
+ virtual bool End(uint32 submit_count) OVERRIDE;
+ virtual bool Process() OVERRIDE;
+ virtual void Destroy(bool have_context) OVERRIDE;
+
+ private:
+ base::TimeTicks begin_time_;
+};
+
+CommandsIssuedQuery::CommandsIssuedQuery(
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
+ : Query(manager, target, shm_id, shm_offset) {
+}
+
+CommandsIssuedQuery::~CommandsIssuedQuery() {
+}
+
+bool CommandsIssuedQuery::Process() {
+ NOTREACHED();
+ return true;
+}
+
+bool CommandsIssuedQuery::Begin() {
+ begin_time_ = base::TimeTicks::HighResNow();
+ return true;
+}
+
+bool CommandsIssuedQuery::End(uint32 submit_count) {
+ base::TimeDelta elapsed = base::TimeTicks::HighResNow() - begin_time_;
+ MarkAsPending(submit_count);
+ return MarkAsCompleted(
+ std::min(elapsed.InMicroseconds(), static_cast<int64>(0xFFFFFFFFL)));
+}
+
+void CommandsIssuedQuery::Destroy(bool /* have_context */) {
+ if (!IsDeleted()) {
+ MarkAsDeleted();
+ }
+}
+
+QueryManager::QueryManager(
+ CommonDecoder* decoder,
+ bool use_arb_occlusion_query2_for_occlusion_query_boolean)
+ : decoder_(decoder),
+ use_arb_occlusion_query2_for_occlusion_query_boolean_(
+ use_arb_occlusion_query2_for_occlusion_query_boolean),
+ query_count_(0) {
}
QueryManager::~QueryManager() {
@@ -27,21 +136,27 @@ void QueryManager::Destroy(bool have_context) {
pending_queries_.clear();
while (!queries_.empty()) {
Query* query = queries_.begin()->second;
- if (have_context) {
- if (!query->IsDeleted()) {
- GLuint service_id = query->service_id();
- glDeleteQueriesARB(1, &service_id);
- query->MarkAsDeleted();
- }
- }
+ query->Destroy(have_context);
queries_.erase(queries_.begin());
}
}
QueryManager::Query* QueryManager::CreateQuery(
- GLuint client_id,
- GLuint service_id) {
- Query::Ref query(new Query(this, service_id));
+ GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset) {
+ Query::Ref query;
+ switch (target) {
+ case GL_COMMANDS_ISSUED_CHROMIUM:
+ query = new CommandsIssuedQuery(this, target, shm_id, shm_offset);
+ break;
+ default: {
+ GLuint service_id = 0;
+ glGenQueriesARB(1, &service_id);
+ DCHECK_NE(0u, service_id);
+ query = new AllSamplesPassedQuery(
+ this, target, shm_id, shm_offset, service_id);
+ break;
+ }
+ }
std::pair<QueryMap::iterator, bool> result =
queries_.insert(std::make_pair(client_id, query));
DCHECK(result.second);
@@ -72,16 +187,33 @@ void QueryManager::StopTracking(QueryManager::Query* /* query */) {
--query_count_;
}
+void QueryManager::BeginQueryHelper(GLenum target, GLuint id) {
+ // ARB_occlusion_query2 does not have a GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
+ // target.
+ if (use_arb_occlusion_query2_for_occlusion_query_boolean_) {
+ target = GL_ANY_SAMPLES_PASSED_EXT;
+ }
+ glBeginQueryARB(target, id);
+}
+
+void QueryManager::EndQueryHelper(GLenum target) {
+ // ARB_occlusion_query2 does not have a GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
+ // target.
+ if (use_arb_occlusion_query2_for_occlusion_query_boolean_) {
+ target = GL_ANY_SAMPLES_PASSED_EXT;
+ }
+ glEndQueryARB(target);
+}
+
QueryManager::Query::Query(
- QueryManager* manager,
- GLuint service_id)
+ QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
: manager_(manager),
- service_id_(service_id),
- target_(0),
- shm_id_(0),
- shm_offset_(0),
+ target_(target),
+ shm_id_(shm_id),
+ shm_offset_(shm_offset),
submit_count_(0),
- pending_(false) {
+ pending_(false),
+ deleted_(false) {
DCHECK(manager);
manager_->StartTracking(this);
}
@@ -93,53 +225,33 @@ QueryManager::Query::~Query() {
}
}
-void QueryManager::Query::Initialize(
- GLenum target, int32 shm_id, uint32 shm_offset) {
- DCHECK(!IsInitialized());
- target_ = target;
- shm_id_ = shm_id;
- shm_offset_ = shm_offset;
-}
-
-bool QueryManager::GetClientId(GLuint service_id, GLuint* client_id) const {
- DCHECK(client_id);
- // This doesn't need to be fast. It's only used during slow queries.
- for (QueryMap::const_iterator it = queries_.begin();
- it != queries_.end(); ++it) {
- if (it->second->service_id() == service_id) {
- *client_id = it->first;
- return true;
- }
+bool QueryManager::Query::MarkAsCompleted(GLuint result) {
+ DCHECK(pending_);
+ QuerySync* sync = manager_->decoder_->GetSharedMemoryAs<QuerySync*>(
+ shm_id_, shm_offset_, sizeof(*sync));
+ if (!sync) {
+ return false;
}
- return false;
+
+ pending_ = false;
+ sync->result = result;
+ // Need a MemoryBarrier here so that sync->result is written before
+ // sync->process_count.
+ base::subtle::MemoryBarrier();
+ sync->process_count = submit_count_;
+
+ return true;
}
-bool QueryManager::ProcessPendingQueries(CommonDecoder* decoder) {
- DCHECK(decoder);
+bool QueryManager::ProcessPendingQueries() {
while (!pending_queries_.empty()) {
Query* query = pending_queries_.front().get();
- GLuint available = 0;
- glGetQueryObjectuivARB(
- query->service_id(), GL_QUERY_RESULT_AVAILABLE_EXT, &available);
- if (!available) {
- return true;
- }
- GLuint result = 0;
- glGetQueryObjectuivARB(
- query->service_id(), GL_QUERY_RESULT_EXT, &result);
- QuerySync* sync = decoder->GetSharedMemoryAs<QuerySync*>(
- query->shm_id(), query->shm_offset(), sizeof(*sync));
- if (!sync) {
+ if (!query->Process()) {
return false;
}
-
- sync->result = result;
- // Need a MemoryBarrier here so that sync->result is written before
- // sync->process_count.
- base::subtle::MemoryBarrier();
- sync->process_count = query->submit_count();
-
- query->MarkAsCompleted();
+ if (query->pending()) {
+ return true;
+ }
pending_queries_.pop_front();
}
@@ -150,16 +262,18 @@ bool QueryManager::HavePendingQueries() {
return !pending_queries_.empty();
}
-void QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
+bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
DCHECK(query);
- DCHECK(query->IsInitialized());
DCHECK(!query->IsDeleted());
- RemovePendingQuery(query);
+ if (!RemovePendingQuery(query)) {
+ return false;
+ }
query->MarkAsPending(submit_count);
pending_queries_.push_back(query);
+ return true;
}
-void QueryManager::RemovePendingQuery(Query* query) {
+bool QueryManager::RemovePendingQuery(Query* query) {
DCHECK(query);
if (query->pending()) {
// TODO(gman): Speed this up if this is a common operation. This would only
@@ -172,8 +286,27 @@ void QueryManager::RemovePendingQuery(Query* query) {
break;
}
}
- query->MarkAsCompleted();
+ if (!query->MarkAsCompleted(0)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool QueryManager::BeginQuery(Query* query) {
+ DCHECK(query);
+ if (!RemovePendingQuery(query)) {
+ return false;
+ }
+ return query->Begin();
+}
+
+bool QueryManager::EndQuery(Query* query, uint32 submit_count) {
+ DCHECK(query);
+ if (!RemovePendingQuery(query)) {
+ return false;
}
+ return query->End(submit_count);
}
} // namespace gles2
« no previous file with comments | « gpu/command_buffer/service/query_manager.h ('k') | gpu/command_buffer/service/query_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698