Commit a188d8cb authored by Aldo Culquicondor's avatar Aldo Culquicondor Committed by Commit Bot

VR: Add a BaseSchedulerDelegate

Extract platform independent code from the GvrSchedulerDelegate for
reusability and testing.

Bug: 875291
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:linux_vr;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: Iaa90b42ea7e81995c32344c9da083c96bdc55a71
Reviewed-on: https://chromium-review.googlesource.com/1195711
Commit-Queue: Aldo Culquicondor <acondor@chromium.org>
Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#590454}
parent 4f1ed2c0
...@@ -64,19 +64,20 @@ GvrSchedulerDelegate::GvrSchedulerDelegate(GlBrowserInterface* browser, ...@@ -64,19 +64,20 @@ GvrSchedulerDelegate::GvrSchedulerDelegate(GlBrowserInterface* browser,
SchedulerUiInterface* ui, SchedulerUiInterface* ui,
gvr::GvrApi* gvr_api, gvr::GvrApi* gvr_api,
GvrGraphicsDelegate* graphics, GvrGraphicsDelegate* graphics,
bool start_in_web_xr_mode, bool start_in_webxr_mode,
bool cardboard_gamepad, bool cardboard_gamepad,
size_t sliding_time_size) size_t sliding_time_size)
: browser_(browser), : BaseSchedulerDelegate(ui,
start_in_webxr_mode,
kWebVrSpinnerTimeoutSeconds,
kWebVrInitialFrameTimeoutSeconds),
browser_(browser),
gvr_api_(gvr_api), gvr_api_(gvr_api),
ui_(ui),
webvr_vsync_align_( webvr_vsync_align_(
base::FeatureList::IsEnabled(features::kWebVrVsyncAlign)), base::FeatureList::IsEnabled(features::kWebVrVsyncAlign)),
web_xr_mode_(start_in_web_xr_mode),
cardboard_gamepad_(cardboard_gamepad), cardboard_gamepad_(cardboard_gamepad),
vsync_helper_(base::BindRepeating(&GvrSchedulerDelegate::OnVSync, vsync_helper_(base::BindRepeating(&GvrSchedulerDelegate::OnVSync,
base::Unretained(this))), base::Unretained(this))),
task_runner_(base::ThreadTaskRunnerHandle::Get()),
presentation_binding_(this), presentation_binding_(this),
frame_data_binding_(this), frame_data_binding_(this),
graphics_(graphics), graphics_(graphics),
...@@ -84,7 +85,7 @@ GvrSchedulerDelegate::GvrSchedulerDelegate(GlBrowserInterface* browser, ...@@ -84,7 +85,7 @@ GvrSchedulerDelegate::GvrSchedulerDelegate(GlBrowserInterface* browser,
webvr_js_time_(sliding_time_size), webvr_js_time_(sliding_time_size),
webvr_js_wait_time_(sliding_time_size), webvr_js_wait_time_(sliding_time_size),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
if (cardboard_gamepad_ && web_xr_mode_) if (cardboard_gamepad_ && webxr_mode())
browser_->ToggleCardboardGamepad(true); browser_->ToggleCardboardGamepad(true);
} }
...@@ -110,23 +111,17 @@ void GvrSchedulerDelegate::AddInputSourceState( ...@@ -110,23 +111,17 @@ void GvrSchedulerDelegate::AddInputSourceState(
void GvrSchedulerDelegate::OnPause() { void GvrSchedulerDelegate::OnPause() {
vsync_helper_.CancelVSyncRequest(); vsync_helper_.CancelVSyncRequest();
gvr_api_->PauseTracking(); gvr_api_->PauseTracking();
webvr_frame_timeout_.Cancel(); CancelWebXrFrameTimeout();
webvr_spinner_timeout_.Cancel();
} }
void GvrSchedulerDelegate::OnResume() { void GvrSchedulerDelegate::OnResume() {
gvr_api_->RefreshViewerProfile(); gvr_api_->RefreshViewerProfile();
gvr_api_->ResumeTracking(); gvr_api_->ResumeTracking();
OnVSync(base::TimeTicks::Now()); OnVSync(base::TimeTicks::Now());
if (web_xr_mode_) if (webxr_mode())
ScheduleOrCancelWebVrFrameTimeout(); ScheduleOrCancelWebVrFrameTimeout();
} }
void GvrSchedulerDelegate::OnExitPresent() {
webvr_frame_timeout_.Cancel();
webvr_spinner_timeout_.Cancel();
}
void GvrSchedulerDelegate::OnTriggerEvent(bool pressed) { void GvrSchedulerDelegate::OnTriggerEvent(bool pressed) {
if (pressed) { if (pressed) {
cardboard_trigger_pressed_ = true; cardboard_trigger_pressed_ = true;
...@@ -137,19 +132,12 @@ void GvrSchedulerDelegate::OnTriggerEvent(bool pressed) { ...@@ -137,19 +132,12 @@ void GvrSchedulerDelegate::OnTriggerEvent(bool pressed) {
} }
void GvrSchedulerDelegate::SetWebXrMode(bool enabled) { void GvrSchedulerDelegate::SetWebXrMode(bool enabled) {
web_xr_mode_ = enabled; BaseSchedulerDelegate::SetWebXrMode(enabled);
if (web_xr_mode_ && submit_client_) {
ScheduleOrCancelWebVrFrameTimeout();
} else {
webvr_frame_timeout_.Cancel();
webvr_frames_received_ = 0;
}
if (cardboard_gamepad_) if (cardboard_gamepad_)
browser_->ToggleCardboardGamepad(enabled); browser_->ToggleCardboardGamepad(enabled);
if (!web_xr_mode_) { if (!webxr_mode()) {
// Closing presentation bindings ensures we won't get any mojo calls such // Closing presentation bindings ensures we won't get any mojo calls such
// as SubmitFrame from this session anymore. This makes it legal to cancel // as SubmitFrame from this session anymore. This makes it legal to cancel
// an outstanding animating frame (if any). // an outstanding animating frame (if any).
...@@ -218,7 +206,8 @@ void GvrSchedulerDelegate::ConnectPresentingService( ...@@ -218,7 +206,8 @@ void GvrSchedulerDelegate::ConnectPresentingService(
session->submit_frame_sink = std::move(submit_frame_sink); session->submit_frame_sink = std::move(submit_frame_sink);
session->display_info = std::move(display_info); session->display_info = std::move(display_info);
ScheduleOrCancelWebVrFrameTimeout(); if (CanSendWebXrVSync())
ScheduleWebXrFrameTimeout();
browser_->SendRequestPresentReply(std::move(session)); browser_->SendRequestPresentReply(std::move(session));
} }
...@@ -360,7 +349,7 @@ void GvrSchedulerDelegate::OnWebXrFrameAvailable() { ...@@ -360,7 +349,7 @@ void GvrSchedulerDelegate::OnWebXrFrameAvailable() {
// due to an active exclusive UI such as a permission prompt, or after // due to an active exclusive UI such as a permission prompt, or after
// exiting a presentation session when a pending frame arrives late. // exiting a presentation session when a pending frame arrives late.
DVLOG(1) << __func__ << ": discarding frame, " DVLOG(1) << __func__ << ": discarding frame, "
<< (web_xr_mode_ ? "UI is active" : "not presenting"); << (webxr_mode() ? "UI is active" : "not presenting");
WebXrCancelProcessingFrameAfterTransfer(); WebXrCancelProcessingFrameAfterTransfer();
// We're no longer in processing state, unblock pending processing frames. // We're no longer in processing state, unblock pending processing frames.
webxr_.TryDeferredProcessing(); webxr_.TryDeferredProcessing();
...@@ -383,39 +372,16 @@ void GvrSchedulerDelegate::ScheduleOrCancelWebVrFrameTimeout() { ...@@ -383,39 +372,16 @@ void GvrSchedulerDelegate::ScheduleOrCancelWebVrFrameTimeout() {
// TODO(mthiesse): We should also timeout after the initial frame to prevent // TODO(mthiesse): We should also timeout after the initial frame to prevent
// bad experiences, but we have to be careful to handle things like splash // bad experiences, but we have to be careful to handle things like splash
// screens correctly. For now just ensure we receive a first frame. // screens correctly. For now just ensure we receive a first frame.
if (!web_xr_mode_ || webvr_frames_received_ > 0) { if (!webxr_mode() || webxr_frames_received() > 0) {
if (!webvr_frame_timeout_.IsCancelled()) CancelWebXrFrameTimeout();
webvr_frame_timeout_.Cancel();
if (!webvr_spinner_timeout_.IsCancelled())
webvr_spinner_timeout_.Cancel();
return; return;
} }
if (CanSendWebXrVSync() && submit_client_) { if (CanSendWebXrVSync() && submit_client_)
webvr_spinner_timeout_.Reset(base::BindOnce( ScheduleWebXrFrameTimeout();
&GvrSchedulerDelegate::OnWebXrTimeoutImminent, base::Unretained(this)));
task_runner_->PostDelayedTask(
FROM_HERE, webvr_spinner_timeout_.callback(),
base::TimeDelta::FromSeconds(kWebVrSpinnerTimeoutSeconds));
webvr_frame_timeout_.Reset(base::BindOnce(
&GvrSchedulerDelegate::OnWebXrFrameTimedOut, base::Unretained(this)));
task_runner_->PostDelayedTask(
FROM_HERE, webvr_frame_timeout_.callback(),
base::TimeDelta::FromSeconds(kWebVrInitialFrameTimeoutSeconds));
}
} }
bool GvrSchedulerDelegate::CanSendWebXrVSync() const { bool GvrSchedulerDelegate::CanSendWebXrVSync() const {
return web_xr_mode_ && !showing_vr_dialog_; return webxr_mode() && !showing_vr_dialog_;
}
void GvrSchedulerDelegate::OnWebXrFrameTimedOut() {
DCHECK(ui_);
ui_->OnWebXrTimedOut();
}
void GvrSchedulerDelegate::OnWebXrTimeoutImminent() {
DCHECK(ui_);
ui_->OnWebXrTimeoutImminent();
} }
void GvrSchedulerDelegate::OnVSync(base::TimeTicks frame_time) { void GvrSchedulerDelegate::OnVSync(base::TimeTicks frame_time) {
...@@ -468,7 +434,7 @@ void GvrSchedulerDelegate::DrawFrame(int16_t frame_index, ...@@ -468,7 +434,7 @@ void GvrSchedulerDelegate::DrawFrame(int16_t frame_index,
} }
DCHECK(browser_renderer_); DCHECK(browser_renderer_);
if (web_xr_mode_ && !ShouldDrawWebVr()) { if (webxr_mode() && !ShouldDrawWebVr()) {
// We're in a WebVR session, but don't want to draw WebVR frames, i.e. // We're in a WebVR session, but don't want to draw WebVR frames, i.e.
// because UI has taken over for a permissions prompt. Do state cleanup if // because UI has taken over for a permissions prompt. Do state cleanup if
// needed. // needed.
...@@ -597,7 +563,7 @@ void GvrSchedulerDelegate::SubmitDrawnFrame(bool is_webxr_frame) { ...@@ -597,7 +563,7 @@ void GvrSchedulerDelegate::SubmitDrawnFrame(bool is_webxr_frame) {
webxr_delayed_gvr_submit_.Reset( webxr_delayed_gvr_submit_.Reset(
base::BindRepeating(&GvrSchedulerDelegate::DrawFrameSubmitWhenReady, base::BindRepeating(&GvrSchedulerDelegate::DrawFrameSubmitWhenReady,
base::Unretained(this))); base::Unretained(this)));
task_runner_->PostTask( task_runner()->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(webxr_delayed_gvr_submit_.callback(), is_webxr_frame, base::BindOnce(webxr_delayed_gvr_submit_.callback(), is_webxr_frame,
submit_head_pose, base::Passed(&fence))); submit_head_pose, base::Passed(&fence)));
...@@ -632,13 +598,13 @@ void GvrSchedulerDelegate::DrawFrameSubmitWhenReady( ...@@ -632,13 +598,13 @@ void GvrSchedulerDelegate::DrawFrameSubmitWhenReady(
// avoids excessive waiting on devices which don't handle timeouts // avoids excessive waiting on devices which don't handle timeouts
// correctly. Downside is that the completion status is only detected // correctly. Downside is that the completion status is only detected
// with a delay of up to one polling interval. // with a delay of up to one polling interval.
task_runner_->PostDelayedTask( task_runner()->PostDelayedTask(
FROM_HERE, FROM_HERE,
base::BindOnce(webxr_delayed_gvr_submit_.callback(), is_webxr_frame, base::BindOnce(webxr_delayed_gvr_submit_.callback(), is_webxr_frame,
head_pose, base::Passed(&fence)), head_pose, base::Passed(&fence)),
kWebVRFenceCheckPollInterval); kWebVRFenceCheckPollInterval);
} else { } else {
task_runner_->PostTask( task_runner()->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(webxr_delayed_gvr_submit_.callback(), is_webxr_frame, base::BindOnce(webxr_delayed_gvr_submit_.callback(), is_webxr_frame,
head_pose, base::Passed(&fence))); head_pose, base::Passed(&fence)));
...@@ -771,7 +737,7 @@ bool GvrSchedulerDelegate::WebVrCanAnimateFrame(bool is_from_onvsync) { ...@@ -771,7 +737,7 @@ bool GvrSchedulerDelegate::WebVrCanAnimateFrame(bool is_from_onvsync) {
return false; return false;
} }
if (!web_xr_mode_) { if (!webxr_mode()) {
DVLOG(2) << __func__ << ": no active session, ignore"; DVLOG(2) << __func__ << ": no active session, ignore";
return false; return false;
} }
...@@ -835,7 +801,7 @@ void GvrSchedulerDelegate::WebXrTryStartAnimatingFrame(bool is_from_onvsync) { ...@@ -835,7 +801,7 @@ void GvrSchedulerDelegate::WebXrTryStartAnimatingFrame(bool is_from_onvsync) {
} }
bool GvrSchedulerDelegate::ShouldDrawWebVr() { bool GvrSchedulerDelegate::ShouldDrawWebVr() {
return web_xr_mode_ && !showing_vr_dialog_ && webvr_frames_received_ > 0; return webxr_mode() && !showing_vr_dialog_ && webxr_frames_received() > 0;
} }
void GvrSchedulerDelegate::WebXrCancelAnimatingFrame() { void GvrSchedulerDelegate::WebXrCancelAnimatingFrame() {
...@@ -1132,7 +1098,7 @@ GvrSchedulerDelegate::GetGazeInputSourceState() { ...@@ -1132,7 +1098,7 @@ GvrSchedulerDelegate::GetGazeInputSourceState() {
} }
void GvrSchedulerDelegate::ClosePresentationBindings() { void GvrSchedulerDelegate::ClosePresentationBindings() {
webvr_frame_timeout_.Cancel(); CancelWebXrFrameTimeout();
submit_client_.reset(); submit_client_.reset();
if (!get_frame_data_callback_.is_null()) { if (!get_frame_data_callback_.is_null()) {
// When this Presentation provider is going away we have to respond to // When this Presentation provider is going away we have to respond to
...@@ -1302,19 +1268,6 @@ bool GvrSchedulerDelegate::SubmitFrameCommon(int16_t frame_index, ...@@ -1302,19 +1268,6 @@ bool GvrSchedulerDelegate::SubmitFrameCommon(int16_t frame_index,
return true; return true;
} }
void GvrSchedulerDelegate::OnNewWebXrFrame() {
ui_->OnWebXrFrameAvailable();
if (web_xr_mode_) {
++webvr_frames_received_;
webxr_fps_meter_.AddFrame(base::TimeTicks::Now());
TRACE_COUNTER1("gpu", "WebVR FPS", webxr_fps_meter_.GetFPS());
}
ScheduleOrCancelWebVrFrameTimeout();
}
void GvrSchedulerDelegate::ProcessWebVrFrameFromMailbox( void GvrSchedulerDelegate::ProcessWebVrFrameFromMailbox(
int16_t frame_index, int16_t frame_index,
const gpu::MailboxHolder& mailbox) { const gpu::MailboxHolder& mailbox) {
......
...@@ -17,17 +17,12 @@ ...@@ -17,17 +17,12 @@
#include "chrome/browser/android/vr/android_vsync_helper.h" #include "chrome/browser/android/vr/android_vsync_helper.h"
#include "chrome/browser/android/vr/gvr_graphics_delegate.h" #include "chrome/browser/android/vr/gvr_graphics_delegate.h"
#include "chrome/browser/android/vr/web_xr_presentation_state.h" #include "chrome/browser/android/vr/web_xr_presentation_state.h"
#include "chrome/browser/vr/fps_meter.h" #include "chrome/browser/vr/base_scheduler_delegate.h"
#include "chrome/browser/vr/scheduler_delegate.h"
#include "chrome/browser/vr/sliding_average.h" #include "chrome/browser/vr/sliding_average.h"
#include "device/vr/public/mojom/vr_service.mojom.h" #include "device/vr/public/mojom/vr_service.mojom.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "ui/gfx/transform.h" #include "ui/gfx/transform.h"
namespace base {
class SingleThreadTaskRunner;
}
namespace gfx { namespace gfx {
class GpuFence; class GpuFence;
} }
...@@ -52,15 +47,15 @@ class SlidingTimeDeltaAverage; ...@@ -52,15 +47,15 @@ class SlidingTimeDeltaAverage;
// Apart from scheduling, this class implements the XR providers and the // Apart from scheduling, this class implements the XR providers and the
// transport logic. // transport logic.
class GvrSchedulerDelegate : public SchedulerDelegate, class GvrSchedulerDelegate : public BaseSchedulerDelegate,
device::mojom::XRPresentationProvider, public device::mojom::XRPresentationProvider,
device::mojom::XRFrameDataProvider { public device::mojom::XRFrameDataProvider {
public: public:
GvrSchedulerDelegate(GlBrowserInterface* browser, GvrSchedulerDelegate(GlBrowserInterface* browser,
SchedulerUiInterface* ui, SchedulerUiInterface* ui,
gvr::GvrApi* gvr_api, gvr::GvrApi* gvr_api,
GvrGraphicsDelegate* graphics, GvrGraphicsDelegate* graphics,
bool start_in_web_xr_mode, bool start_in_webxr_mode,
bool cardboard_gamepad, bool cardboard_gamepad,
size_t sliding_time_size); size_t sliding_time_size);
~GvrSchedulerDelegate() override; ~GvrSchedulerDelegate() override;
...@@ -73,7 +68,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate, ...@@ -73,7 +68,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate,
void AddInputSourceState(device::mojom::XRInputSourceStatePtr state) override; void AddInputSourceState(device::mojom::XRInputSourceStatePtr state) override;
void OnPause() override; void OnPause() override;
void OnResume() override; void OnResume() override;
void OnExitPresent() override;
void OnTriggerEvent(bool pressed) override; void OnTriggerEvent(bool pressed) override;
void SetWebXrMode(bool enabled) override; void SetWebXrMode(bool enabled) override;
void SetShowingVrDialog(bool showing) override; void SetShowingVrDialog(bool showing) override;
...@@ -86,8 +80,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate, ...@@ -86,8 +80,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate,
void GvrInit(); void GvrInit();
void ScheduleOrCancelWebVrFrameTimeout(); void ScheduleOrCancelWebVrFrameTimeout();
bool CanSendWebXrVSync() const; bool CanSendWebXrVSync() const;
void OnWebXrTimeoutImminent();
void OnWebXrFrameTimedOut();
void OnVSync(base::TimeTicks frame_time); void OnVSync(base::TimeTicks frame_time);
void DrawFrame(int16_t frame_index, base::TimeTicks current_time); void DrawFrame(int16_t frame_index, base::TimeTicks current_time);
void WebVrSendRenderNotification(bool was_rendered); void WebVrSendRenderNotification(bool was_rendered);
...@@ -164,7 +156,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate, ...@@ -164,7 +156,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate,
bool SubmitFrameCommon(int16_t frame_index, base::TimeDelta time_waited); bool SubmitFrameCommon(int16_t frame_index, base::TimeDelta time_waited);
bool IsSubmitFrameExpected(int16_t frame_index); bool IsSubmitFrameExpected(int16_t frame_index);
void OnNewWebXrFrame();
void OnWebXrTokenSignaled(int16_t frame_index, void OnWebXrTokenSignaled(int16_t frame_index,
std::unique_ptr<gfx::GpuFence> gpu_fence); std::unique_ptr<gfx::GpuFence> gpu_fence);
...@@ -179,14 +170,12 @@ class GvrSchedulerDelegate : public SchedulerDelegate, ...@@ -179,14 +170,12 @@ class GvrSchedulerDelegate : public SchedulerDelegate,
GlBrowserInterface* browser_; GlBrowserInterface* browser_;
gvr::GvrApi* gvr_api_; gvr::GvrApi* gvr_api_;
SchedulerUiInterface* ui_ = nullptr;
SchedulerBrowserRendererInterface* browser_renderer_ = nullptr; SchedulerBrowserRendererInterface* browser_renderer_ = nullptr;
// Set from feature flags. // Set from feature flags.
const bool webvr_vsync_align_; const bool webvr_vsync_align_;
WebXrPresentationState webxr_; WebXrPresentationState webxr_;
bool web_xr_mode_ = false;
bool showing_vr_dialog_ = false; bool showing_vr_dialog_ = false;
bool cardboard_gamepad_ = false; bool cardboard_gamepad_ = false;
// TODO(acondor): Move trigger data to controller delegate. // TODO(acondor): Move trigger data to controller delegate.
...@@ -202,10 +191,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate, ...@@ -202,10 +191,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate,
bool webxr_use_shared_buffer_draw_ = false; bool webxr_use_shared_buffer_draw_ = false;
AndroidVSyncHelper vsync_helper_; AndroidVSyncHelper vsync_helper_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::CancelableOnceClosure webvr_frame_timeout_;
base::CancelableOnceClosure webvr_spinner_timeout_;
gfx::Transform head_pose_; gfx::Transform head_pose_;
...@@ -214,7 +199,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate, ...@@ -214,7 +199,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate,
std::vector<device::mojom::XRInputSourceStatePtr> input_states_; std::vector<device::mojom::XRInputSourceStatePtr> input_states_;
device::mojom::XRPresentationClientPtr submit_client_; device::mojom::XRPresentationClientPtr submit_client_;
uint64_t webvr_frames_received_ = 0;
base::queue<uint16_t> pending_frames_; base::queue<uint16_t> pending_frames_;
base::queue<std::pair<WebXrPresentationState::FrameIndexType, WebVrBounds>> base::queue<std::pair<WebXrPresentationState::FrameIndexType, WebVrBounds>>
...@@ -252,7 +236,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate, ...@@ -252,7 +236,6 @@ class GvrSchedulerDelegate : public SchedulerDelegate,
std::unique_ptr<ScopedGpuTrace> gpu_trace_; std::unique_ptr<ScopedGpuTrace> gpu_trace_;
FPSMeter vr_ui_fps_meter_; FPSMeter vr_ui_fps_meter_;
FPSMeter webxr_fps_meter_;
// Render time is from JS submitFrame to estimated render completion. // Render time is from JS submitFrame to estimated render completion.
// This is an estimate when submitting incomplete frames to GVR. // This is an estimate when submitting incomplete frames to GVR.
......
...@@ -198,6 +198,8 @@ component("vr_common") { ...@@ -198,6 +198,8 @@ component("vr_common") {
sources = [ sources = [
"base_graphics_delegate.cc", "base_graphics_delegate.cc",
"base_graphics_delegate.h", "base_graphics_delegate.h",
"base_scheduler_delegate.cc",
"base_scheduler_delegate.h",
"browser_renderer.cc", "browser_renderer.cc",
"browser_renderer.h", "browser_renderer.h",
"browser_renderer_browser_interface.h", "browser_renderer_browser_interface.h",
......
// Copyright 2018 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 "chrome/browser/vr/base_scheduler_delegate.h"
#include "chrome/browser/vr/scheduler_ui_interface.h"
namespace vr {
BaseSchedulerDelegate::BaseSchedulerDelegate(SchedulerUiInterface* ui,
bool start_in_webxr_mode,
int webxr_spinner_timeout,
int webxr_initial_frame_timeout)
: ui_(ui),
webxr_mode_(start_in_webxr_mode),
webxr_spinner_timeout_seconds_(webxr_spinner_timeout),
webxr_initial_frame_timeout_seconds_(webxr_initial_frame_timeout),
task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
BaseSchedulerDelegate::~BaseSchedulerDelegate() = default;
void BaseSchedulerDelegate::OnExitPresent() {
CancelWebXrFrameTimeout();
}
void BaseSchedulerDelegate::SetWebXrMode(bool enabled) {
if (webxr_mode_ == enabled)
return;
webxr_mode_ = enabled;
if (webxr_mode_)
ResetWebXrFramesReceived();
else
CancelWebXrFrameTimeout();
}
void BaseSchedulerDelegate::ScheduleWebXrFrameTimeout() {
DCHECK(ui_);
webxr_spinner_timeout_closure_.Reset(base::BindOnce(
&SchedulerUiInterface::OnWebXrTimeoutImminent, base::Unretained(ui_)));
task_runner_->PostDelayedTask(
FROM_HERE, webxr_spinner_timeout_closure_.callback(),
base::TimeDelta::FromSeconds(webxr_spinner_timeout_seconds_));
webxr_frame_timeout_closure_.Reset(base::BindOnce(
&SchedulerUiInterface::OnWebXrTimedOut, base::Unretained(ui_)));
task_runner_->PostDelayedTask(
FROM_HERE, webxr_frame_timeout_closure_.callback(),
base::TimeDelta::FromSeconds(webxr_initial_frame_timeout_seconds_));
}
void BaseSchedulerDelegate::CancelWebXrFrameTimeout() {
if (!webxr_spinner_timeout_closure_.IsCancelled())
webxr_spinner_timeout_closure_.Cancel();
if (!webxr_frame_timeout_closure_.IsCancelled())
webxr_frame_timeout_closure_.Cancel();
}
void BaseSchedulerDelegate::OnNewWebXrFrame() {
ui_->OnWebXrFrameAvailable();
if (webxr_mode_) {
TickWebXrFramesReceived();
webxr_fps_meter_.AddFrame(base::TimeTicks::Now());
TRACE_COUNTER1("gpu", "WebVR FPS", webxr_fps_meter_.GetFPS());
}
CancelWebXrFrameTimeout();
}
} // namespace vr
// Copyright 2018 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.
#ifndef CHROME_BROWSER_VR_BASE_SCHEDULER_DELEGATE_H_
#define CHROME_BROWSER_VR_BASE_SCHEDULER_DELEGATE_H_
#include "base/cancelable_callback.h"
#include "chrome/browser/vr/fps_meter.h"
#include "chrome/browser/vr/scheduler_delegate.h"
#include "chrome/browser/vr/vr_export.h"
namespace base {
class TaskRunner;
}
namespace vr {
class SchedulerUiInterface;
class VR_EXPORT BaseSchedulerDelegate : public SchedulerDelegate {
public:
BaseSchedulerDelegate(SchedulerUiInterface* ui,
bool start_in_webxr_mode,
int webxr_spinner_timeout,
int webxr_initial_frame_timeout);
~BaseSchedulerDelegate() override;
// SchedulerDelegate implementations.
void OnExitPresent() override;
void SetWebXrMode(bool enabled) override;
protected:
void ScheduleWebXrFrameTimeout();
void CancelWebXrFrameTimeout();
void OnNewWebXrFrame();
bool webxr_mode() const { return webxr_mode_; }
uint64_t webxr_frames_received() const { return webxr_frames_received_; }
void TickWebXrFramesReceived() { ++webxr_frames_received_; }
void ResetWebXrFramesReceived() { webxr_frames_received_ = 0; }
base::TaskRunner* task_runner() { return task_runner_.get(); }
private:
SchedulerUiInterface* ui_;
bool webxr_mode_ = false;
int webxr_frames_received_ = 0;
int webxr_spinner_timeout_seconds_;
int webxr_initial_frame_timeout_seconds_;
FPSMeter webxr_fps_meter_;
base::CancelableOnceClosure webxr_frame_timeout_closure_;
base::CancelableOnceClosure webxr_spinner_timeout_closure_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
DISALLOW_COPY_AND_ASSIGN(BaseSchedulerDelegate);
};
} // namespace vr
#endif // CHROME_BROWSER_VR_BASE_SCHEDULER_DELEGATE_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment