Update from https://crrev.com/316786

List of manually-modified files:
gpu/command_buffer/service/in_process_command_buffer.cc
examples/sample_app/BUILD.gn
examples/sample_app/spinning_cube.cc
mojo/android/javatests/src/org/chromium/mojo/MojoTestCase.java
mojo/cc/context_provider_mojo.cc
mojo/cc/context_provider_mojo.h
mojo/common/trace_controller_impl.cc
mojo/gles2/command_buffer_client_impl.cc
mojo/gles2/command_buffer_client_impl.h
services/gles2/gpu_impl.cc
shell/android/apk/src/org/chromium/mojo/shell/MojoShellApplication.java
sky/engine/core/dom/Node.cpp
sky/shell/apk/src/org/domokit/sky/shell/SkyShellApplication.java
ui/events/latency_info.cc
ui/gfx/transform.cc
ui/gfx/transform.h
ui/gfx/transform_util.cc
ui/gfx/transform_util.h

Review URL: https://codereview.chromium.org/935333002
diff --git a/gpu/command_buffer/service/gpu_timing.cc b/gpu/command_buffer/service/gpu_timing.cc
new file mode 100644
index 0000000..8716448
--- /dev/null
+++ b/gpu/command_buffer/service/gpu_timing.cc
@@ -0,0 +1,145 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/gpu_timing.h"
+
+#include "base/time/time.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_version_info.h"
+
+namespace gpu {
+
+GPUTimer::GPUTimer(GPUTiming* gpu_timing) : gpu_timing_(gpu_timing) {
+  DCHECK(gpu_timing_);
+  memset(queries_, 0, sizeof(queries_));
+  glGenQueriesARB(2, queries_);
+}
+
+GPUTimer::~GPUTimer() {
+  glDeleteQueriesARB(2, queries_);
+}
+
+void GPUTimer::Start() {
+  // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value.
+  glQueryCounter(queries_[0], GL_TIMESTAMP);
+  offset_ = gpu_timing_->CalculateTimerOffset();
+}
+
+void GPUTimer::End() {
+  end_requested_ = true;
+  glQueryCounter(queries_[1], GL_TIMESTAMP);
+}
+
+bool GPUTimer::IsAvailable() {
+  if (!gpu_timing_->IsAvailable() || !end_requested_) {
+    return false;
+  }
+  GLint done = 0;
+  glGetQueryObjectivARB(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done);
+  return done != 0;
+}
+
+void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) {
+  DCHECK(start && end);
+  DCHECK(IsAvailable());
+  GLuint64 begin_stamp = 0;
+  GLuint64 end_stamp = 0;
+  // TODO(dsinclair): It's possible for the timer to wrap during the start/end.
+  // We need to detect if the end is less then the start and correct for the
+  // wrapping.
+  glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp);
+  glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp);
+
+  *start = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
+  *end = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
+}
+
+int64 GPUTimer::GetDeltaElapsed() {
+  int64 start = 0;
+  int64 end = 0;
+  GetStartEndTimestamps(&start, &end);
+  return end - start;
+}
+
+GPUTiming::GPUTiming() : cpu_time_for_testing_() {
+}
+
+GPUTiming::~GPUTiming() {
+}
+
+bool GPUTiming::Initialize(gfx::GLContext* gl_context) {
+  DCHECK(gl_context);
+  DCHECK_EQ(kTimerTypeInvalid, timer_type_);
+
+  const gfx::GLVersionInfo* version_info = gl_context->GetVersionInfo();
+  DCHECK(version_info);
+  if (version_info->is_es3 &&  // glGetInteger64v is supported under ES3.
+      gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) {
+    timer_type_ = kTimerTypeDisjoint;
+    return true;
+  } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) {
+    timer_type_ = kTimerTypeARB;
+    return true;
+  }
+  return false;
+}
+
+bool GPUTiming::IsAvailable() {
+  return timer_type_ != kTimerTypeInvalid;
+}
+
+const char* GPUTiming::GetTimerTypeName() const {
+  switch (timer_type_) {
+    case kTimerTypeDisjoint:
+      return "GL_EXT_disjoint_timer_query";
+    case kTimerTypeARB:
+      return "GL_ARB_timer_query";
+    default:
+      return "Unknown";
+  }
+}
+
+bool GPUTiming::CheckAndResetTimerErrors() {
+  if (timer_type_ == kTimerTypeDisjoint) {
+    GLint disjoint_value = 0;
+    glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
+    return disjoint_value != 0;
+  } else {
+    return false;
+  }
+}
+
+int64 GPUTiming::CalculateTimerOffset() {
+  if (!offset_valid_) {
+    GLint64 gl_now = 0;
+    glGetInteger64v(GL_TIMESTAMP, &gl_now);
+    int64 now =
+        cpu_time_for_testing_.is_null()
+            ? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue()
+            : cpu_time_for_testing_.Run();
+    offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond;
+    offset_valid_ = timer_type_ == kTimerTypeARB;
+  }
+  return offset_;
+}
+
+void GPUTiming::InvalidateTimerOffset() {
+  offset_valid_ = false;
+}
+
+void GPUTiming::SetCpuTimeForTesting(
+    const base::Callback<int64(void)>& cpu_time) {
+  cpu_time_for_testing_ = cpu_time;
+}
+
+void GPUTiming::SetOffsetForTesting(int64 offset, bool cache_it) {
+  offset_ = offset;
+  offset_valid_ = cache_it;
+}
+
+void GPUTiming::SetTimerTypeForTesting(TimerType type) {
+  timer_type_ = type;
+}
+
+}  // namespace gpu