Add CommandLatencyQuery to the gpu command buffer

Increases query result size to be 64 bits.
Allows result to be used as input on the query begin.

BUG=


Review URL: https://chromiumcodereview.appspot.com/11235012

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163683 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 14d421f..f06c920 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -221,6 +221,7 @@
   AddExtensionString("GL_ANGLE_translated_shader_source");
   AddExtensionString("GL_CHROMIUM_bind_uniform_location");
   AddExtensionString("GL_CHROMIUM_command_buffer_query");
+  AddExtensionString("GL_CHROMIUM_command_buffer_latency_query");
   AddExtensionString("GL_CHROMIUM_copy_texture");
   AddExtensionString("GL_CHROMIUM_discard_framebuffer");
   AddExtensionString("GL_CHROMIUM_get_error_query");
diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h
index 5baff01..a7230314a 100644
--- a/gpu/command_buffer/service/gl_utils.h
+++ b/gpu/command_buffer/service/gl_utils.h
@@ -89,6 +89,9 @@
 /* GL_CHROMIUM_get_error_query */
 #define GL_GET_ERROR_QUERY_CHROMIUM            0x84F3
 
+/* GL_CHROMIUM_command_buffer_latency_query */
+#define GL_LATENCY_QUERY_CHROMIUM              0x84F4
+
 // GL_OES_texure_3D
 #define GL_SAMPLER_3D_OES                      0x8B5F
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 662c21c7..3504c8c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -8652,6 +8652,7 @@
 
   switch (target) {
     case GL_COMMANDS_ISSUED_CHROMIUM:
+    case GL_LATENCY_QUERY_CHROMIUM:
       break;
     default:
       if (!feature_info_->feature_flags().occlusion_query_boolean) {
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
index ad514774..48eb54e 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -281,6 +281,7 @@
   GL_ANY_SAMPLES_PASSED_EXT,
   GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
   GL_COMMANDS_ISSUED_CHROMIUM,
+  GL_LATENCY_QUERY_CHROMIUM,
 };
 
 static GLenum valid_read_pixel_format_table[] = {
diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc
index 0f94d46..45a3a56 100644
--- a/gpu/command_buffer/service/query_manager.cc
+++ b/gpu/command_buffer/service/query_manager.cc
@@ -102,8 +102,7 @@
 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)));
+  return MarkAsCompleted(elapsed.InMicroseconds());
 }
 
 bool CommandsIssuedQuery::Process() {
@@ -120,6 +119,49 @@
 CommandsIssuedQuery::~CommandsIssuedQuery() {
 }
 
+class CommandLatencyQuery : public QueryManager::Query {
+ public:
+  CommandLatencyQuery(
+      QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
+
+  virtual bool Begin() OVERRIDE;
+  virtual bool End(uint32 submit_count) OVERRIDE;
+  virtual bool Process() OVERRIDE;
+  virtual void Destroy(bool have_context) OVERRIDE;
+
+ protected:
+  virtual ~CommandLatencyQuery();
+};
+
+CommandLatencyQuery::CommandLatencyQuery(
+      QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
+    : Query(manager, target, shm_id, shm_offset) {
+}
+
+bool CommandLatencyQuery::Begin() {
+    return true;
+}
+
+bool CommandLatencyQuery::End(uint32 submit_count) {
+    base::TimeDelta now = base::TimeTicks::HighResNow() - base::TimeTicks();
+    MarkAsPending(submit_count);
+    return MarkAsCompleted(now.InMicroseconds());
+}
+
+bool CommandLatencyQuery::Process() {
+  NOTREACHED();
+  return true;
+}
+
+void CommandLatencyQuery::Destroy(bool /* have_context */) {
+  if (!IsDeleted()) {
+    MarkAsDeleted();
+  }
+}
+
+CommandLatencyQuery::~CommandLatencyQuery() {
+}
+
 class GetErrorQuery : public QueryManager::Query {
  public:
   GetErrorQuery(
@@ -203,6 +245,9 @@
     case GL_COMMANDS_ISSUED_CHROMIUM:
       query = new CommandsIssuedQuery(this, target, shm_id, shm_offset);
       break;
+    case GL_LATENCY_QUERY_CHROMIUM:
+      query = new CommandLatencyQuery(this, target, shm_id, shm_offset);
+      break;
     case GL_GET_ERROR_QUERY_CHROMIUM:
       query = new GetErrorQuery(this, target, shm_id, shm_offset);
       break;
@@ -297,7 +342,7 @@
   }
 }
 
-bool QueryManager::Query::MarkAsCompleted(GLuint result) {
+bool QueryManager::Query::MarkAsCompleted(uint64 result) {
   DCHECK(pending_);
   QuerySync* sync = manager_->decoder_->GetSharedMemoryAs<QuerySync*>(
       shm_id_, shm_offset_, sizeof(*sync));
diff --git a/gpu/command_buffer/service/query_manager.h b/gpu/command_buffer/service/query_manager.h
index f6d3942..322c03d 100644
--- a/gpu/command_buffer/service/query_manager.h
+++ b/gpu/command_buffer/service/query_manager.h
@@ -81,7 +81,7 @@
     }
 
     // Returns false if shared memory for sync is invalid.
-    bool MarkAsCompleted(GLuint result);
+    bool MarkAsCompleted(uint64 result);
 
     void MarkAsPending(uint32 submit_count) {
       DCHECK(!pending_);