Commit 18091af3 authored by Klaus Weidner's avatar Klaus Weidner Committed by Commit Bot

VrShellGl: add ProcessWebVrFrame, refactor VSync logic

The WebVR frame lifecycle transition from "animating" to "processing" was
confusing due to use of deferred SubmitFrame. Add a new ProcessWebVrCall at
the end of SubmitFrame that can be deferred if needed. A frame counts as
"animating" until that executes.

Refactor VSync logic. WebVrCanAnimateFrame checks if all necessary resources
are available. All the places that provide resources call
WebVrTryStartAnimatingFrame which runs SendVSyncNow if CanAnimateFrame returns
true.

Resources include pending_vsync_ and get_vsync_callback_ along with the
ShouldSkipVSync heuristics and the ui_->CanSendWebVrVSync() check. It should be
generally equivalent, but with reduced wait time if not VSync aligned since it
now reschedules after webvr_deferred_start_processing_ becomes false instead of
waiting for the next OnVSync.

Change-Id: I32f920d3147b0032037b03f72b18df6cf7195751
Reviewed-on: https://chromium-review.googlesource.com/985652
Commit-Queue: Klaus Weidner <klausw@chromium.org>
Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Reviewed-by: default avatarBill Orr <billorr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#547821}
parent c8d3eed1
This diff is collapsed.
......@@ -189,16 +189,32 @@ class VrShellGl : public device::mojom::VRPresentationProvider {
void ForceExitVr();
bool ShouldSkipVSync();
void SendVSync(base::TimeTicks time, GetVSyncCallback callback);
// Checks if we're in a valid state for submitting a frame. Invalid states
// include mailbox_bridge_ready_ being false, or overlapping processing
// frames.
bool WebVrCanSubmitFrame();
// Call this after state changes that could result in WebVrCanSubmitFrame
// Sends a GetVSync response to the presentation client.
void SendVSync();
// Heuristics to avoid excessive backlogged frames.
bool WebVrHasSlowRenderingFrame();
bool WebVrHasOverstuffedBuffers();
// Checks if we're in a valid state for starting animation of a new frame.
// Invalid states include a previous animating frame that's not complete
// yet (including deferred processing not having started yet), or timing
// heuristics indicating that it should be retried later.
bool WebVrCanAnimateFrame(bool is_from_onvsync);
// Call this after state changes that could result in WebVrCanAnimateFrame
// becoming true.
void WebVrTryDeferredSubmit();
void WebVrTryStartAnimatingFrame(bool is_from_onvsync);
// Checks if we're in a valid state for processing the current animating
// frame. Invalid states include mailbox_bridge_ready_ being false, or an
// already existing processing frame that's not done yet.
bool WebVrCanProcessFrame();
// Call this after state changes that could result in WebVrCanProcessFrame
// becoming true.
void WebVrTryDeferredProcessing();
// Transition a frame from animating to processing.
void ProcessWebVrFrame(int16_t frame_index,
const gpu::MailboxHolder& mailbox);
void ClosePresentationBindings();
......@@ -280,16 +296,16 @@ class VrShellGl : public device::mojom::VRPresentationProvider {
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
// Attributes tracking WebVR rAF/VSync animation loop state. Blink schedules
// a callback using the GetVSync mojo call, and the callback is either passed
// to SendVSync immediately, or deferred until the next OnVSync call.
// a callback using the GetVSync mojo call which is stored in
// get_vsync_callback_. The callback is executed by SendVSync once
// WebVrCanAnimateFrame returns true.
//
// pending_vsync_ is set to true in OnVSync if there is no current
// outstanding callback, and this means that a future GetVSync is permitted
// to execute SendVSync immediately. If it is false, GetVSync must store the
// pending callback in callback_ for later execution.
// pending_vsync_ is set to true in OnVSync and false in SendVSync. It
// throttles animation to no faster than the VSync rate. The pending_time_ is
// updated in OnVSync and used as the rAF animation timer in SendVSync.
base::TimeTicks pending_time_;
bool pending_vsync_ = false;
GetVSyncCallback callback_;
GetVSyncCallback get_vsync_callback_;
mojo::Binding<device::mojom::VRPresentationProvider> binding_;
device::mojom::VRSubmitFrameClientPtr submit_client_;
......@@ -349,9 +365,9 @@ class VrShellGl : public device::mojom::VRPresentationProvider {
// for that timespan.
bool webvr_frame_processing_ = false;
// If we receive a new SubmitFrame when we're not ready, save it for
// later execution.
base::OnceClosure webvr_deferred_mojo_submit_;
// If we receive a new SubmitFrame when we're not ready, defer start of
// processing for later.
base::OnceClosure webvr_deferred_start_processing_;
std::vector<gvr::BufferSpec> specs_;
......@@ -363,7 +379,10 @@ class VrShellGl : public device::mojom::VRPresentationProvider {
std::unique_ptr<VrDialog> vr_dialog_;
bool showing_vr_dialog_ = false;
bool last_should_send_webvr_vsync_ = false;
// Used by WebVrCanAnimateFrame() to detect when ui_->CanSendWebVrVSync()
// transitions from false to true, as part of starting the incoming frame
// timeout.
bool last_ui_allows_sending_webvr_vsync_ = false;
base::WeakPtrFactory<VrShellGl> weak_ptr_factory_;
......
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