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

VR: Extract update UI logic to RenderLoop

Also performing the UI update after obtaining a frame.

Bonus: replace __FUNCTION__ by __func__ to comply to styleguide.

Bug: 767282
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: I88f59a2991f8fed1ce7d9842781d2d63d8b351fa
Reviewed-on: https://chromium-review.googlesource.com/1162702
Commit-Queue: Aldo Culquicondor <acondor@chromium.org>
Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#581375}
parent cd12c8a7
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/android/jni_weak_ref.h" #include "base/android/jni_weak_ref.h"
#include "chrome/browser/vr/assets_load_status.h" #include "chrome/browser/vr/assets_load_status.h"
#include "chrome/browser/vr/render_loop_browser_interface.h"
#include "chrome/browser/vr/ui_test_input.h" #include "chrome/browser/vr/ui_test_input.h"
#include "device/vr/android/gvr/gvr_gamepad_data_provider.h" #include "device/vr/android/gvr/gvr_gamepad_data_provider.h"
#include "device/vr/public/mojom/vr_service.mojom.h" #include "device/vr/public/mojom/vr_service.mojom.h"
...@@ -23,9 +24,9 @@ namespace vr { ...@@ -23,9 +24,9 @@ namespace vr {
// VrShellGl talks to VrShell through this interface. This could be split up if // VrShellGl talks to VrShell through this interface. This could be split up if
// VrShellGl is refactored into components. // VrShellGl is refactored into components.
class GlBrowserInterface { class GlBrowserInterface : public RenderLoopBrowserInterface {
public: public:
virtual ~GlBrowserInterface() = default; ~GlBrowserInterface() override = default;
virtual void ContentSurfaceCreated(jobject surface, virtual void ContentSurfaceCreated(jobject surface,
gl::SurfaceTexture* texture) = 0; gl::SurfaceTexture* texture) = 0;
...@@ -37,10 +38,7 @@ class GlBrowserInterface { ...@@ -37,10 +38,7 @@ class GlBrowserInterface {
virtual void DialogSurfaceCreated(jobject surface, virtual void DialogSurfaceCreated(jobject surface,
gl::SurfaceTexture* texture) = 0; gl::SurfaceTexture* texture) = 0;
virtual void UpdateGamepadData(device::GvrGamepadData) = 0; virtual void UpdateGamepadData(device::GvrGamepadData) = 0;
virtual void ForceExitVr() = 0;
virtual void ToggleCardboardGamepad(bool enabled) = 0; virtual void ToggleCardboardGamepad(bool enabled) = 0;
virtual void ReportUiActivityResultForTesting(
const VrUiTestActivityResult& result) = 0;
}; };
} // namespace vr } // namespace vr
......
...@@ -69,8 +69,11 @@ class VrGLThread : public base::android::JavaHandlerThread, ...@@ -69,8 +69,11 @@ class VrGLThread : public base::android::JavaHandlerThread,
void DialogSurfaceCreated(jobject surface, void DialogSurfaceCreated(jobject surface,
gl::SurfaceTexture* texture) override; gl::SurfaceTexture* texture) override;
void UpdateGamepadData(device::GvrGamepadData) override; void UpdateGamepadData(device::GvrGamepadData) override;
void ForceExitVr() override;
void ToggleCardboardGamepad(bool enabled) override; void ToggleCardboardGamepad(bool enabled) override;
// RenderLoopBrowserInterface implementation (RenderLoop calling to VrShell).
void ForceExitVr() override;
void ReportUiActivityResultForTesting(
const VrUiTestActivityResult& result) override;
// PlatformInputHandler // PlatformInputHandler
void ForwardEventToPlatformUi(std::unique_ptr<InputEvent> event) override; void ForwardEventToPlatformUi(std::unique_ptr<InputEvent> event) override;
...@@ -146,9 +149,6 @@ class VrGLThread : public base::android::JavaHandlerThread, ...@@ -146,9 +149,6 @@ class VrGLThread : public base::android::JavaHandlerThread,
void RemoveTab(int id, bool incognito) override; void RemoveTab(int id, bool incognito) override;
void RemoveAllTabs() override; void RemoveAllTabs() override;
void ReportUiActivityResultForTesting(
const VrUiTestActivityResult& result) override;
protected: protected:
void Init() override; void Init() override;
void CleanUp() override; void CleanUp() override;
......
This diff is collapsed.
...@@ -63,7 +63,6 @@ namespace vr { ...@@ -63,7 +63,6 @@ namespace vr {
class BrowserUiInterface; class BrowserUiInterface;
class FPSMeter; class FPSMeter;
class GlBrowserInterface; class GlBrowserInterface;
class GraphicsDelegate;
class MailboxToSurfaceBridge; class MailboxToSurfaceBridge;
class ScopedGpuTrace; class ScopedGpuTrace;
class SlidingTimeDeltaAverage; class SlidingTimeDeltaAverage;
...@@ -101,7 +100,7 @@ class VrShellGl : public RenderLoop, ...@@ -101,7 +100,7 @@ class VrShellGl : public RenderLoop,
public device::mojom::XRPresentationProvider, public device::mojom::XRPresentationProvider,
public device::mojom::XRFrameDataProvider { public device::mojom::XRFrameDataProvider {
public: public:
VrShellGl(GlBrowserInterface* browser_interface, VrShellGl(GlBrowserInterface* browser,
std::unique_ptr<UiInterface> ui, std::unique_ptr<UiInterface> ui,
gvr_context* gvr_api, gvr_context* gvr_api,
bool reprojected_rendering, bool reprojected_rendering,
...@@ -158,8 +157,6 @@ class VrShellGl : public RenderLoop, ...@@ -158,8 +157,6 @@ class VrShellGl : public RenderLoop,
void CancelToast(); void CancelToast();
void AcceptDoffPromptForTesting(); void AcceptDoffPromptForTesting();
void SetUiExpectingActivityForTesting(
UiTestActivityExpectation ui_expectation);
void PerformControllerActionForTesting(ControllerTestInput controller_input); void PerformControllerActionForTesting(ControllerTestInput controller_input);
private: private:
...@@ -192,15 +189,6 @@ class VrShellGl : public RenderLoop, ...@@ -192,15 +189,6 @@ class VrShellGl : public RenderLoop,
void DrawContentQuad(bool draw_overlay_texture); void DrawContentQuad(bool draw_overlay_texture);
bool WebVrPoseByteIsValid(int pose_index_byte); bool WebVrPoseByteIsValid(int pose_index_byte);
void UpdateController(const RenderInfo& render_info,
base::TimeTicks current_time);
void HandleControllerInput(const gfx::Point3F& laser_origin,
const RenderInfo& render_info,
base::TimeTicks current_time);
void HandleControllerAppButtonActivity(
const gfx::Vector3dF& controller_direction);
void OnContentFrameAvailable(); void OnContentFrameAvailable();
void OnContentOverlayFrameAvailable(); void OnContentOverlayFrameAvailable();
void OnUiFrameAvailable(); void OnUiFrameAvailable();
...@@ -241,8 +229,6 @@ class VrShellGl : public RenderLoop, ...@@ -241,8 +229,6 @@ class VrShellGl : public RenderLoop,
// Returns true if OK to proceed. // Returns true if OK to proceed.
bool SubmitFrameCommon(int16_t frame_index, base::TimeDelta time_waited); bool SubmitFrameCommon(int16_t frame_index, base::TimeDelta time_waited);
void ForceExitVr();
// Sends a GetFrameData response to the presentation client. // Sends a GetFrameData response to the presentation client.
void SendVSync(); void SendVSync();
...@@ -278,10 +264,6 @@ class VrShellGl : public RenderLoop, ...@@ -278,10 +264,6 @@ class VrShellGl : public RenderLoop,
device::mojom::XRInputSourceStatePtr GetGazeInputSourceState(); device::mojom::XRInputSourceStatePtr GetGazeInputSourceState();
void ReportUiStatusForTesting(const base::TimeTicks& current_time,
bool ui_updated);
void ReportUiActivityResultForTesting(VrUiTestActivityResult result);
std::unique_ptr<ControllerDelegate> controller_delegate_for_testing_; std::unique_ptr<ControllerDelegate> controller_delegate_for_testing_;
// samplerExternalOES texture data for WebVR content image. // samplerExternalOES texture data for WebVR content image.
...@@ -293,7 +275,6 @@ class VrShellGl : public RenderLoop, ...@@ -293,7 +275,6 @@ class VrShellGl : public RenderLoop,
bool webvr_vsync_align_; bool webvr_vsync_align_;
scoped_refptr<gl::GLSurface> surface_; scoped_refptr<gl::GLSurface> surface_;
std::unique_ptr<GraphicsDelegate> graphics_delegate_;
scoped_refptr<gl::SurfaceTexture> content_surface_texture_; scoped_refptr<gl::SurfaceTexture> content_surface_texture_;
scoped_refptr<gl::SurfaceTexture> content_overlay_surface_texture_; scoped_refptr<gl::SurfaceTexture> content_overlay_surface_texture_;
scoped_refptr<gl::SurfaceTexture> ui_surface_texture_; scoped_refptr<gl::SurfaceTexture> ui_surface_texture_;
...@@ -351,7 +332,6 @@ class VrShellGl : public RenderLoop, ...@@ -351,7 +332,6 @@ class VrShellGl : public RenderLoop,
WebXrPresentationState webxr_; WebXrPresentationState webxr_;
bool web_vr_mode_ = false; bool web_vr_mode_ = false;
bool paused_ = true;
const bool surfaceless_rendering_; const bool surfaceless_rendering_;
bool daydream_support_; bool daydream_support_;
bool content_paused_; bool content_paused_;
...@@ -403,9 +383,6 @@ class VrShellGl : public RenderLoop, ...@@ -403,9 +383,6 @@ class VrShellGl : public RenderLoop,
SlidingTimeDeltaAverage webvr_acquire_time_; SlidingTimeDeltaAverage webvr_acquire_time_;
SlidingTimeDeltaAverage webvr_submit_time_; SlidingTimeDeltaAverage webvr_submit_time_;
SlidingTimeDeltaAverage ui_processing_time_;
SlidingTimeDeltaAverage ui_controller_update_time_;
gfx::Point3F pointer_start_; gfx::Point3F pointer_start_;
RenderInfo render_info_; RenderInfo render_info_;
...@@ -424,14 +401,12 @@ class VrShellGl : public RenderLoop, ...@@ -424,14 +401,12 @@ class VrShellGl : public RenderLoop,
std::vector<gvr::BufferSpec> specs_; std::vector<gvr::BufferSpec> specs_;
bool content_frame_available_ = false;
gfx::Transform last_used_head_pose_; gfx::Transform last_used_head_pose_;
ControllerModel controller_model_; ControllerModel controller_model_;
std::unique_ptr<PlatformUiInputDelegate> vr_dialog_input_delegate_; std::unique_ptr<PlatformUiInputDelegate> vr_dialog_input_delegate_;
bool showing_vr_dialog_ = false; bool showing_vr_dialog_ = false;
std::unique_ptr<UiTestState> ui_test_state_;
bool using_controller_delegate_for_testing_ = false; bool using_controller_delegate_for_testing_ = false;
base::WeakPtrFactory<VrShellGl> weak_ptr_factory_; base::WeakPtrFactory<VrShellGl> weak_ptr_factory_;
......
...@@ -240,6 +240,7 @@ component("vr_common") { ...@@ -240,6 +240,7 @@ component("vr_common") {
"model/web_vr_model.h", "model/web_vr_model.h",
"render_loop.cc", "render_loop.cc",
"render_loop.h", "render_loop.h",
"render_loop_browser_interface.h",
"sample_queue.cc", "sample_queue.cc",
"sample_queue.h", "sample_queue.h",
"service/browser_xr_runtime.cc", "service/browser_xr_runtime.cc",
......
...@@ -7,26 +7,84 @@ ...@@ -7,26 +7,84 @@
#include <utility> #include <utility>
#include "base/time/time.h" #include "base/time/time.h"
#include "base/trace_event/common/trace_event_common.h"
#include "chrome/browser/vr/controller_delegate.h" #include "chrome/browser/vr/controller_delegate.h"
#include "chrome/browser/vr/graphics_delegate.h"
#include "chrome/browser/vr/input_event.h" #include "chrome/browser/vr/input_event.h"
#include "chrome/browser/vr/model/controller_model.h" #include "chrome/browser/vr/model/controller_model.h"
#include "chrome/browser/vr/render_loop_browser_interface.h"
#include "chrome/browser/vr/ui_interface.h" #include "chrome/browser/vr/ui_interface.h"
#include "chrome/browser/vr/ui_renderer.h"
#include "chrome/browser/vr/ui_test_input.h"
namespace vr { namespace vr {
RenderLoop::RenderLoop(std::unique_ptr<UiInterface> ui) : ui_(std::move(ui)) {} RenderLoop::RenderLoop(std::unique_ptr<UiInterface> ui,
RenderLoopBrowserInterface* browser,
size_t sliding_time_size)
: ui_(std::move(ui)),
browser_(browser),
ui_processing_time_(sliding_time_size),
ui_controller_update_time_(sliding_time_size) {}
RenderLoop::~RenderLoop() = default; RenderLoop::~RenderLoop() = default;
void RenderLoop::ProcessControllerInput(const RenderInfo& render_info, void RenderLoop::SetUiExpectingActivityForTesting(
base::TimeTicks current_time, UiTestActivityExpectation ui_expectation) {
bool is_webxr_frame) { DCHECK(ui_test_state_ == nullptr)
<< "Attempted to set a UI activity expectation with one in progress";
ui_test_state_ = std::make_unique<UiTestState>();
ui_test_state_->quiescence_timeout_ms =
base::TimeDelta::FromMilliseconds(ui_expectation.quiescence_timeout_ms);
}
void RenderLoop::UpdateUi(const RenderInfo& render_info,
base::TimeTicks current_time,
FrameType frame_type) {
TRACE_EVENT0("gpu", __func__);
DCHECK(graphics_delegate_);
// Update the render position of all UI elements.
base::TimeTicks timing_start = base::TimeTicks::Now();
bool ui_updated = ui_->OnBeginFrame(current_time, render_info.head_pose);
// WebXR handles controller input in OnVsync.
base::TimeDelta controller_time;
if (frame_type == kUiFrame)
controller_time =
ProcessControllerInput(render_info, current_time, kUiFrame);
if (ui_->SceneHasDirtyTextures()) {
if (!graphics_delegate_->MakeSkiaContextCurrent()) {
ForceExitVr();
return;
}
ui_->UpdateSceneTextures();
if (!graphics_delegate_->MakeMainContextCurrent()) {
ForceExitVr();
return;
}
ui_updated = true;
}
ReportUiStatusForTesting(timing_start, ui_updated);
base::TimeDelta scene_time = base::TimeTicks::Now() - timing_start;
// Don't double-count the controller time that was part of the scene time.
ui_processing_time_.AddSample(scene_time - controller_time);
TRACE_EVENT_END0("gpu", "SceneUpdate");
}
base::TimeDelta RenderLoop::ProcessControllerInput(
const RenderInfo& render_info,
base::TimeTicks current_time,
FrameType frame_type) {
TRACE_EVENT0("gpu", __func__);
DCHECK(controller_delegate_); DCHECK(controller_delegate_);
DCHECK(ui_); DCHECK(ui_);
base::TimeTicks timing_start = base::TimeTicks::Now();
controller_delegate_->UpdateController(render_info, current_time, controller_delegate_->UpdateController(render_info, current_time, frame_type);
is_webxr_frame);
auto input_event_list = controller_delegate_->GetGestures(current_time); auto input_event_list = controller_delegate_->GetGestures(current_time);
if (is_webxr_frame) { if (frame_type == kWebXrFrame) {
ui_->HandleMenuButtonEvents(&input_event_list); ui_->HandleMenuButtonEvents(&input_event_list);
} else { } else {
ReticleModel reticle_model; ReticleModel reticle_model;
...@@ -36,6 +94,44 @@ void RenderLoop::ProcessControllerInput(const RenderInfo& render_info, ...@@ -36,6 +94,44 @@ void RenderLoop::ProcessControllerInput(const RenderInfo& render_info,
&reticle_model, &input_event_list); &reticle_model, &input_event_list);
ui_->OnControllerUpdated(controller_model, reticle_model); ui_->OnControllerUpdated(controller_model, reticle_model);
} }
auto controller_time = base::TimeTicks::Now() - timing_start;
ui_controller_update_time_.AddSample(controller_time);
return controller_time;
}
void RenderLoop::ForceExitVr() {
browser_->ForceExitVr();
}
void RenderLoop::ReportUiStatusForTesting(const base::TimeTicks& current_time,
bool ui_updated) {
if (ui_test_state_ == nullptr)
return;
base::TimeDelta time_since_start = current_time - ui_test_state_->start_time;
if (ui_updated) {
ui_test_state_->activity_started = true;
if (time_since_start > ui_test_state_->quiescence_timeout_ms) {
// The UI is being updated, but hasn't reached a stable state in the
// given time -> report timeout.
ReportUiActivityResultForTesting(VrUiTestActivityResult::kTimeoutNoEnd);
}
} else {
if (ui_test_state_->activity_started) {
// The UI has been updated since the test requested notification of
// quiescence, but wasn't this frame -> report that the UI is quiescent.
ReportUiActivityResultForTesting(VrUiTestActivityResult::kQuiescent);
} else if (time_since_start > ui_test_state_->quiescence_timeout_ms) {
// The UI has never been updated and we've reached the timeout.
ReportUiActivityResultForTesting(VrUiTestActivityResult::kTimeoutNoStart);
}
}
}
void RenderLoop::ReportUiActivityResultForTesting(
VrUiTestActivityResult result) {
ui_test_state_ = nullptr;
browser_->ReportUiActivityResultForTesting(result);
} }
} // namespace vr } // namespace vr
...@@ -7,17 +7,25 @@ ...@@ -7,17 +7,25 @@
#include <memory> #include <memory>
#include "base/macros.h"
#include "chrome/browser/vr/sliding_average.h"
#include "chrome/browser/vr/vr_export.h" #include "chrome/browser/vr/vr_export.h"
namespace base { namespace base {
class TimeDelta;
class TimeTicks; class TimeTicks;
} }
namespace vr { namespace vr {
enum class VrUiTestActivityResult;
class ControllerDelegate; class ControllerDelegate;
class GraphicsDelegate;
class RenderLoopBrowserInterface;
class UiInterface; class UiInterface;
struct RenderInfo; struct RenderInfo;
struct UiTestActivityExpectation;
struct UiTestState;
// This abstract class handles all input/output activities during a frame. // This abstract class handles all input/output activities during a frame.
// This includes head movement, controller movement and input, audio output and // This includes head movement, controller movement and input, audio output and
...@@ -26,16 +34,49 @@ struct RenderInfo; ...@@ -26,16 +34,49 @@ struct RenderInfo;
// VrShellGl and make this class concrete (http://crbug.com/767282). // VrShellGl and make this class concrete (http://crbug.com/767282).
class VR_EXPORT RenderLoop { class VR_EXPORT RenderLoop {
public: public:
explicit RenderLoop(std::unique_ptr<UiInterface> ui); enum FrameType { kUiFrame, kWebXrFrame };
explicit RenderLoop(std::unique_ptr<UiInterface> ui,
RenderLoopBrowserInterface* browser,
size_t sliding_time_size);
virtual ~RenderLoop(); virtual ~RenderLoop();
void SetUiExpectingActivityForTesting(
UiTestActivityExpectation ui_expectation);
protected: protected:
void ProcessControllerInput(const RenderInfo& render_info, // Position, hide and/or show UI elements, process input and update textures.
base::TimeTicks current_time, // Returns true if the scene changed.
bool is_webxr_frame); void UpdateUi(const RenderInfo& render_info,
base::TimeTicks currrent_time,
FrameType frame_type);
base::TimeDelta ProcessControllerInput(const RenderInfo& render_info,
base::TimeTicks current_time,
FrameType frame_type);
void ForceExitVr();
const SlidingTimeDeltaAverage& ui_controller_update_time() const {
return ui_controller_update_time_;
}
const SlidingTimeDeltaAverage& ui_processing_time() const {
return ui_processing_time_;
}
std::unique_ptr<UiInterface> ui_; std::unique_ptr<UiInterface> ui_;
std::unique_ptr<ControllerDelegate> controller_delegate_; std::unique_ptr<ControllerDelegate> controller_delegate_;
std::unique_ptr<GraphicsDelegate> graphics_delegate_;
private:
void ReportUiStatusForTesting(const base::TimeTicks& current_time,
bool ui_updated);
void ReportUiActivityResultForTesting(VrUiTestActivityResult result);
RenderLoopBrowserInterface* browser_;
std::unique_ptr<UiTestState> ui_test_state_;
SlidingTimeDeltaAverage ui_processing_time_;
SlidingTimeDeltaAverage ui_controller_update_time_;
DISALLOW_COPY_AND_ASSIGN(RenderLoop);
}; };
} // namespace vr } // 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_RENDER_LOOP_BROWSER_INTERFACE_H_
#define CHROME_BROWSER_VR_RENDER_LOOP_BROWSER_INTERFACE_H_
#include "chrome/browser/vr/ui_test_input.h"
namespace vr {
// RenderLoop talks to the browser main thread through this interface.
class RenderLoopBrowserInterface {
public:
virtual ~RenderLoopBrowserInterface() = default;
virtual void ForceExitVr() = 0;
virtual void ReportUiActivityResultForTesting(
const VrUiTestActivityResult& result) = 0;
};
} // namespace vr
#endif // CHROME_BROWSER_VR_RENDER_LOOP_BROWSER_INTERFACE_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