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

Side by Side Diff: chrome/browser/android/vr_shell/vr_shell_gl.cc

Issue 2901213002: Add SlidingAverage to FPSMeter, use for WebVR prediction time (Closed)
Patch Set: Fix "Complex destructor has an inline body" for = default. Created 3 years, 6 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/android/vr_shell/vr_shell_gl.h ('k') | device/vr/android/gvr/gvr_delegate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/android/vr_shell/vr_shell_gl.h" 5 #include "chrome/browser/android/vr_shell/vr_shell_gl.h"
6 6
7 #include <chrono> 7 #include <chrono>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 75
76 // The GVR viewport list has two entries (left eye and right eye) for each 76 // The GVR viewport list has two entries (left eye and right eye) for each
77 // GVR buffer. 77 // GVR buffer.
78 static constexpr int kViewportListPrimaryOffset = 0; 78 static constexpr int kViewportListPrimaryOffset = 0;
79 static constexpr int kViewportListHeadlockedOffset = 2; 79 static constexpr int kViewportListHeadlockedOffset = 2;
80 80
81 // Buffer size large enough to handle the current backlog of poses which is 81 // Buffer size large enough to handle the current backlog of poses which is
82 // 2-3 frames. 82 // 2-3 frames.
83 static constexpr unsigned kPoseRingBufferSize = 8; 83 static constexpr unsigned kPoseRingBufferSize = 8;
84 84
85 // Number of frames to use for sliding averages for pose timings,
86 // as used for estimating prediction times.
87 static constexpr unsigned kWebVRSlidingAverageSize = 5;
88
85 // Criteria for considering holding the app button in combination with 89 // Criteria for considering holding the app button in combination with
86 // controller movement as a gesture. 90 // controller movement as a gesture.
87 static constexpr float kMinAppButtonGestureAngleRad = 0.25; 91 static constexpr float kMinAppButtonGestureAngleRad = 0.25;
88 92
89 static constexpr gfx::PointF kInvalidTargetPoint = 93 static constexpr gfx::PointF kInvalidTargetPoint =
90 gfx::PointF(std::numeric_limits<float>::max(), 94 gfx::PointF(std::numeric_limits<float>::max(),
91 std::numeric_limits<float>::max()); 95 std::numeric_limits<float>::max());
92 96
93 // Generate a quaternion representing the rotation from the negative Z axis 97 // Generate a quaternion representing the rotation from the negative Z axis
94 // (0, 0, -1) to a specified vector. This is an optimized version of a more 98 // (0, 0, -1) to a specified vector. This is an optimized version of a more
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 bool reprojected_rendering, 220 bool reprojected_rendering,
217 bool daydream_support, 221 bool daydream_support,
218 UiScene* scene) 222 UiScene* scene)
219 : web_vr_mode_(initially_web_vr), 223 : web_vr_mode_(initially_web_vr),
220 surfaceless_rendering_(reprojected_rendering), 224 surfaceless_rendering_(reprojected_rendering),
221 daydream_support_(daydream_support), 225 daydream_support_(daydream_support),
222 task_runner_(base::ThreadTaskRunnerHandle::Get()), 226 task_runner_(base::ThreadTaskRunnerHandle::Get()),
223 binding_(this), 227 binding_(this),
224 browser_(browser), 228 browser_(browser),
225 scene_(scene), 229 scene_(scene),
226 #if DCHECK_IS_ON()
227 fps_meter_(new FPSMeter()), 230 fps_meter_(new FPSMeter()),
228 #endif 231 webvr_js_time_(new SlidingAverage(kWebVRSlidingAverageSize)),
232 webvr_render_time_(new SlidingAverage(kWebVRSlidingAverageSize)),
229 weak_ptr_factory_(this) { 233 weak_ptr_factory_(this) {
230 GvrInit(gvr_api); 234 GvrInit(gvr_api);
231 } 235 }
232 236
233 VrShellGl::~VrShellGl() { 237 VrShellGl::~VrShellGl() {
234 vsync_task_.Cancel(); 238 vsync_task_.Cancel();
235 // TODO(mthiesse): Can we omit the Close() here? Concern is that if 239 // TODO(mthiesse): Can we omit the Close() here? Concern is that if
236 // both ends of the connection ever live in the same process for 240 // both ends of the connection ever live in the same process for
237 // some reason, we could receive another VSync request in response 241 // some reason, we could receive another VSync request in response
238 // to the closing message in the destructor but fail to respond to 242 // to the closing message in the destructor but fail to respond to
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 } 1070 }
1067 1071
1068 // Report rendering completion to WebVR so that it's permitted to submit 1072 // Report rendering completion to WebVR so that it's permitted to submit
1069 // a fresh frame. We could do this earlier, as soon as the frame got pulled 1073 // a fresh frame. We could do this earlier, as soon as the frame got pulled
1070 // off the transfer surface, but that appears to result in overstuffed 1074 // off the transfer surface, but that appears to result in overstuffed
1071 // buffers. 1075 // buffers.
1072 if (submit_client_) { 1076 if (submit_client_) {
1073 submit_client_->OnSubmitFrameRendered(); 1077 submit_client_->OnSubmitFrameRendered();
1074 } 1078 }
1075 1079
1076 #if DCHECK_IS_ON()
1077 // After saving the timestamp, fps will be available via GetFPS(). 1080 // After saving the timestamp, fps will be available via GetFPS().
1078 // TODO(vollick): enable rendering of this framerate in a HUD. 1081 // TODO(vollick): enable rendering of this framerate in a HUD.
1079 fps_meter_->AddFrame(current_time); 1082 fps_meter_->AddFrame(current_time);
1080 DVLOG(1) << "fps: " << fps_meter_->GetFPS(); 1083 DVLOG(1) << "fps: " << fps_meter_->GetFPS();
1081 #endif 1084 TRACE_COUNTER1("gpu", "WebVR FPS", fps_meter_->GetFPS());
1082 } 1085 }
1083 1086
1084 void VrShellGl::DrawWorldElements(const vr::Mat4f& head_pose) { 1087 void VrShellGl::DrawWorldElements(const vr::Mat4f& head_pose) {
1085 TRACE_EVENT0("gpu", "VrShellGl::DrawWorldElements"); 1088 TRACE_EVENT0("gpu", "VrShellGl::DrawWorldElements");
1086 1089
1087 if (ShouldDrawWebVr()) { 1090 if (ShouldDrawWebVr()) {
1088 // WebVR is incompatible with 3D world compositing since the 1091 // WebVR is incompatible with 3D world compositing since the
1089 // depth buffer was already populated with unknown scaling - the 1092 // depth buffer was already populated with unknown scaling - the
1090 // WebVR app has full control over zNear/zFar. Just leave the 1093 // WebVR app has full control over zNear/zFar. Just leave the
1091 // existing content in place in the primary buffer without 1094 // existing content in place in the primary buffer without
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 vsync_timebase_ += base::TimeDelta::FromMicroseconds(timebase_nanos / 1000); 1514 vsync_timebase_ += base::TimeDelta::FromMicroseconds(timebase_nanos / 1000);
1512 vsync_interval_ = base::TimeDelta::FromSecondsD(interval_seconds); 1515 vsync_interval_ = base::TimeDelta::FromSecondsD(interval_seconds);
1513 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this))); 1516 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this)));
1514 OnVSync(); 1517 OnVSync();
1515 } 1518 }
1516 1519
1517 void VrShellGl::ForceExitVr() { 1520 void VrShellGl::ForceExitVr() {
1518 browser_->ForceExitVr(); 1521 browser_->ForceExitVr();
1519 } 1522 }
1520 1523
1524 int64_t VrShellGl::GetPredictedFrameTimeNanos() {
1525 int64_t frame_time_micros = vsync_interval_.InMicroseconds();
1526 // If we aim to submit at vsync, that frame will start scanning out
1527 // one vsync later. Add a half frame to split the difference between
1528 // left and right eye.
1529 int64_t js_micros = webvr_js_time_->GetAverageOrDefault(frame_time_micros);
1530 int64_t render_micros =
1531 webvr_render_time_->GetAverageOrDefault(frame_time_micros);
1532 int64_t overhead_micros = frame_time_micros * 3 / 2;
1533 int64_t expected_frame_micros = js_micros + render_micros + overhead_micros;
1534 TRACE_COUNTER2("gpu", "WebVR frame time (ms)", "javascript",
1535 js_micros / 1000.0, "rendering", render_micros / 1000.0);
1536 TRACE_COUNTER1("gpu", "WebVR pose prediction (ms)",
1537 expected_frame_micros / 1000.0);
1538 return expected_frame_micros * 1000;
1539 }
1540
1521 void VrShellGl::SendVSync(base::TimeDelta time, 1541 void VrShellGl::SendVSync(base::TimeDelta time,
1522 const GetVSyncCallback& callback) { 1542 const GetVSyncCallback& callback) {
1523 uint8_t frame_index = frame_index_++; 1543 uint8_t frame_index = frame_index_++;
1524 1544
1525 TRACE_EVENT1("input", "VrShellGl::SendVSync", "frame", frame_index); 1545 TRACE_EVENT1("input", "VrShellGl::SendVSync", "frame", frame_index);
1526 1546
1547 int64_t prediction_nanos = GetPredictedFrameTimeNanos();
1548
1527 vr::Mat4f head_mat; 1549 vr::Mat4f head_mat;
1528 device::mojom::VRPosePtr pose = 1550 device::mojom::VRPosePtr pose =
1529 device::GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), &head_mat); 1551 device::GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), &head_mat,
1552 prediction_nanos);
1530 1553
1531 webvr_head_pose_[frame_index % kPoseRingBufferSize] = head_mat; 1554 webvr_head_pose_[frame_index % kPoseRingBufferSize] = head_mat;
1532 1555
1533 callback.Run(std::move(pose), time, frame_index, 1556 callback.Run(std::move(pose), time, frame_index,
1534 device::mojom::VRVSyncProvider::Status::SUCCESS); 1557 device::mojom::VRVSyncProvider::Status::SUCCESS);
1535 } 1558 }
1536 1559
1537 void VrShellGl::CreateVRDisplayInfo( 1560 void VrShellGl::CreateVRDisplayInfo(
1538 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, 1561 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback,
1539 uint32_t device_id) { 1562 uint32_t device_id) {
1540 // This assumes that the initial webvr_surface_size_ was set to the 1563 // This assumes that the initial webvr_surface_size_ was set to the
1541 // appropriate recommended render resolution as the default size during 1564 // appropriate recommended render resolution as the default size during
1542 // InitializeGl. Revisit if the initialization order changes. 1565 // InitializeGl. Revisit if the initialization order changes.
1543 device::mojom::VRDisplayInfoPtr info = 1566 device::mojom::VRDisplayInfoPtr info =
1544 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), 1567 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(),
1545 webvr_surface_size_, device_id); 1568 webvr_surface_size_, device_id);
1546 browser_->RunVRDisplayInfoCallback(callback, &info); 1569 browser_->RunVRDisplayInfoCallback(callback, &info);
1547 } 1570 }
1548 1571
1549 } // namespace vr_shell 1572 } // namespace vr_shell
OLDNEW
« no previous file with comments | « chrome/browser/android/vr_shell/vr_shell_gl.h ('k') | device/vr/android/gvr/gvr_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698