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

Move head pose acquisition to InputDelegate

The ControllerDelegate was renamed to InputDelegate to reflect
that it handles more than just the controller raw input.

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: I7415806cf7ba52a7e49899843dcf93079333c8d3
Reviewed-on: https://chromium-review.googlesource.com/1213874
Commit-Queue: Aldo Culquicondor <acondor@chromium.org>
Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#590522}
parent 9fc3a5c2
......@@ -22,10 +22,10 @@ static_library("vr_android") {
"browser_renderer_factory.cc",
"browser_renderer_factory.h",
"gl_browser_interface.h",
"gvr_controller_delegate.cc",
"gvr_controller_delegate.h",
"gvr_graphics_delegate.cc",
"gvr_graphics_delegate.h",
"gvr_input_delegate.cc",
"gvr_input_delegate.h",
"gvr_keyboard_delegate.cc",
"gvr_keyboard_delegate.h",
"gvr_keyboard_shim.cc",
......
......@@ -7,7 +7,7 @@
#include <utility>
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/android/vr/gvr_controller_delegate.h"
#include "chrome/browser/android/vr/gvr_input_delegate.h"
#include "chrome/browser/android/vr/gvr_keyboard_delegate.h"
#include "chrome/browser/android/vr/gvr_scheduler_delegate.h"
#include "chrome/browser/android/vr/vr_gl_thread.h"
......@@ -63,8 +63,8 @@ std::unique_ptr<BrowserRenderer> BrowserRendererFactory::Create(
vr_gl_thread, vr_gl_thread, std::move(keyboard_delegate),
std::move(text_input_delegate), std::move(audio_delegate),
params->ui_initial_state);
auto controller_delegate =
std::make_unique<GvrControllerDelegate>(params->gvr_api, vr_gl_thread);
auto input_delegate =
std::make_unique<GvrInputDelegate>(params->gvr_api, vr_gl_thread);
auto graphics_delegate = std::make_unique<GvrGraphicsDelegate>(
vr_gl_thread,
base::BindOnce(&UiInterface::OnGlInitialized, base::Unretained(ui.get())),
......@@ -84,8 +84,8 @@ std::unique_ptr<BrowserRenderer> BrowserRendererFactory::Create(
params->ui_initial_state.in_web_vr));
auto browser_renderer = std::make_unique<BrowserRenderer>(
std::move(ui), std::move(scheduler_delegate),
std::move(graphics_delegate), std::move(controller_delegate),
vr_gl_thread, kSlidingAverageSize);
std::move(graphics_delegate), std::move(input_delegate), vr_gl_thread,
kSlidingAverageSize);
return browser_renderer;
}
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/android/vr/gvr_controller_delegate.h"
#include "chrome/browser/android/vr/gvr_input_delegate.h"
#include <utility>
......@@ -12,6 +12,7 @@
#include "chrome/browser/vr/model/controller_model.h"
#include "chrome/browser/vr/pose_util.h"
#include "chrome/browser/vr/render_info.h"
#include "device/vr/android/gvr/gvr_delegate.h"
namespace {
constexpr gfx::Vector3dF kForwardVector = {0.0f, 0.0f, -1.0f};
......@@ -19,15 +20,23 @@ constexpr gfx::Vector3dF kForwardVector = {0.0f, 0.0f, -1.0f};
namespace vr {
GvrControllerDelegate::GvrControllerDelegate(gvr::GvrApi* gvr_api,
GlBrowserInterface* browser)
: controller_(std::make_unique<VrController>(gvr_api)), browser_(browser) {}
GvrInputDelegate::GvrInputDelegate(gvr::GvrApi* gvr_api,
GlBrowserInterface* browser)
: controller_(std::make_unique<VrController>(gvr_api)),
gvr_api_(gvr_api),
browser_(browser) {}
GvrControllerDelegate::~GvrControllerDelegate() = default;
GvrInputDelegate::~GvrInputDelegate() = default;
void GvrControllerDelegate::UpdateController(const gfx::Transform& head_pose,
base::TimeTicks current_time,
bool is_webxr_frame) {
gfx::Transform GvrInputDelegate::GetHeadPose() {
gfx::Transform head_pose;
device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_, &head_pose);
return head_pose;
}
void GvrInputDelegate::UpdateController(const gfx::Transform& head_pose,
base::TimeTicks current_time,
bool is_webxr_frame) {
controller_->UpdateState(head_pose);
device::GvrGamepadData controller_data = controller_->GetGamepadData();
......@@ -36,7 +45,7 @@ void GvrControllerDelegate::UpdateController(const gfx::Transform& head_pose,
browser_->UpdateGamepadData(controller_data);
}
ControllerModel GvrControllerDelegate::GetModel(
ControllerModel GvrInputDelegate::GetControllerModel(
const gfx::Transform& head_pose) {
gfx::Vector3dF head_direction = GetForwardVector(head_pose);
......@@ -88,15 +97,13 @@ ControllerModel GvrControllerDelegate::GetModel(
return controller_model;
}
InputEventList GvrControllerDelegate::GetGestures(
base::TimeTicks current_time) {
InputEventList GvrInputDelegate::GetGestures(base::TimeTicks current_time) {
if (!controller_->IsConnected())
return {};
return gesture_detector_.DetectGestures(*controller_, current_time);
}
device::mojom::XRInputSourceStatePtr
GvrControllerDelegate::GetInputSourceState() {
device::mojom::XRInputSourceStatePtr GvrInputDelegate::GetInputSourceState() {
device::mojom::XRInputSourceStatePtr state =
device::mojom::XRInputSourceState::New();
state->description = device::mojom::XRInputSourceDescription::New();
......@@ -141,11 +148,11 @@ GvrControllerDelegate::GetInputSourceState() {
return state;
}
void GvrControllerDelegate::OnResume() {
void GvrInputDelegate::OnResume() {
controller_->OnResume();
}
void GvrControllerDelegate::OnPause() {
void GvrInputDelegate::OnPause() {
controller_->OnPause();
}
......
......@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ANDROID_VR_GVR_CONTROLLER_DELEGATE_H_
#define CHROME_BROWSER_ANDROID_VR_GVR_CONTROLLER_DELEGATE_H_
#ifndef CHROME_BROWSER_ANDROID_VR_GVR_INPUT_DELEGATE_H_
#define CHROME_BROWSER_ANDROID_VR_GVR_INPUT_DELEGATE_H_
#include <memory>
#include "base/macros.h"
#include "chrome/browser/android/vr/vr_controller.h"
#include "chrome/browser/vr/controller_delegate.h"
#include "chrome/browser/vr/input_delegate.h"
namespace gvr {
class GvrApi;
......@@ -20,16 +20,17 @@ namespace vr {
class GestureDetector;
class GlBrowserInterface;
class GvrControllerDelegate : public ControllerDelegate {
class GvrInputDelegate : public InputDelegate {
public:
GvrControllerDelegate(gvr::GvrApi* gvr_api, GlBrowserInterface* browser);
~GvrControllerDelegate() override;
GvrInputDelegate(gvr::GvrApi* gvr_api, GlBrowserInterface* browser);
~GvrInputDelegate() override;
// ControllerDelegate implementation.
// InputDelegate implementation.
gfx::Transform GetHeadPose() override;
void UpdateController(const gfx::Transform& head_pose,
base::TimeTicks current_time,
bool is_webxr_frame) override;
ControllerModel GetModel(const gfx::Transform& head_pose) override;
ControllerModel GetControllerModel(const gfx::Transform& head_pose) override;
InputEventList GetGestures(base::TimeTicks current_time) override;
device::mojom::XRInputSourceStatePtr GetInputSourceState() override;
void OnResume() override;
......@@ -38,13 +39,14 @@ class GvrControllerDelegate : public ControllerDelegate {
private:
std::unique_ptr<VrController> controller_;
GestureDetector gesture_detector_;
gvr::GvrApi* gvr_api_;
GlBrowserInterface* browser_;
bool was_select_button_down_ = false;
DISALLOW_COPY_AND_ASSIGN(GvrControllerDelegate);
DISALLOW_COPY_AND_ASSIGN(GvrInputDelegate);
};
} // namespace vr
#endif // CHROME_BROWSER_ANDROID_VR_GVR_CONTROLLER_DELEGATE_H_
#endif // CHROME_BROWSER_ANDROID_VR_GVR_INPUT_DELEGATE_H_
......@@ -99,10 +99,6 @@ void GvrSchedulerDelegate::SetBrowserRenderer(
browser_renderer_ = browser_renderer;
}
gfx::Transform GvrSchedulerDelegate::GetHeadPose() {
return head_pose_;
}
void GvrSchedulerDelegate::AddInputSourceState(
device::mojom::XRInputSourceStatePtr state) {
input_states_.push_back(std::move(state));
......@@ -406,16 +402,10 @@ void GvrSchedulerDelegate::OnVSync(base::TimeTicks frame_time) {
pending_time_ = frame_time;
WebXrTryStartAnimatingFrame(true);
if (ShouldDrawWebVr()) {
// When drawing WebVR, controller input doesn't need to be synchronized with
// rendering as WebVR uses the gamepad api. To ensure we always handle input
// like app button presses, process the controller here.
device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_, &head_pose_);
DCHECK(browser_renderer_);
if (ShouldDrawWebVr())
browser_renderer_->ProcessControllerInputForWebXr(frame_time);
} else {
else
DrawFrame(-1, frame_time);
}
}
void GvrSchedulerDelegate::DrawFrame(int16_t frame_index,
......@@ -458,20 +448,6 @@ void GvrSchedulerDelegate::DrawFrame(int16_t frame_index,
// of them.
DCHECK(!is_webxr_frame || webxr_.HaveProcessingFrame());
// When using async reprojection, we need to know which pose was
// used in the WebVR app for drawing this frame and supply it when
// submitting. Technically we don't need a pose if not reprojecting,
// but keeping it uninitialized seems likely to cause problems down
// the road. Copying it is cheaper than fetching a new one.
if (is_webxr_frame) {
// Copy into render info for overlay UI. WebVR doesn't use this.
DCHECK(webxr_.HaveProcessingFrame());
WebXrFrame* frame = webxr_.GetProcessingFrame();
head_pose_ = frame->head_pose;
} else {
device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_, &head_pose_);
}
graphics_->UpdateViewports();
if (is_webxr_frame) {
......@@ -485,12 +461,18 @@ void GvrSchedulerDelegate::DrawFrame(int16_t frame_index,
if (!graphics_->AcquireGvrFrame(frame_index))
return;
if (is_webxr_frame)
browser_renderer_->DrawWebXrFrame(current_time);
else
if (is_webxr_frame) {
// When using async reprojection, we need to know which pose was
// used in the WebVR app for drawing this frame and supply it when
// submitting. Technically we don't need a pose if not reprojecting,
// but keeping it uninitialized seems likely to cause problems down
// the road. Copying it is cheaper than fetching a new one.
DCHECK(webxr_.HaveProcessingFrame());
browser_renderer_->DrawWebXrFrame(current_time,
webxr_.GetProcessingFrame()->head_pose);
} else {
browser_renderer_->DrawBrowserFrame(current_time);
SubmitDrawnFrame(is_webxr_frame);
}
}
void GvrSchedulerDelegate::UpdatePendingBounds(int16_t frame_index) {
......@@ -525,19 +507,10 @@ void GvrSchedulerDelegate::UpdatePendingBounds(int16_t frame_index) {
}
}
void GvrSchedulerDelegate::SubmitDrawnFrame(bool is_webxr_frame) {
// GVR submit needs the exact head pose that was used for rendering.
gfx::Transform submit_head_pose;
if (is_webxr_frame) {
// Don't use render_info_.head_pose here, that may have been
// overwritten by OnVSync's controller handling. We need the pose that was
// sent to JS.
submit_head_pose = webxr_.GetProcessingFrame()->head_pose;
} else {
submit_head_pose = head_pose_;
}
void GvrSchedulerDelegate::SubmitDrawnFrame(FrameType frame_type,
const gfx::Transform& head_pose) {
std::unique_ptr<gl::GLFenceEGL> fence = nullptr;
if (is_webxr_frame && graphics_->DoesSurfacelessRendering()) {
if (frame_type == kWebXrFrame && graphics_->DoesSurfacelessRendering()) {
webxr_.GetProcessingFrame()->time_copied = base::TimeTicks::Now();
if (webxr_use_gpu_fence_) {
// Continue with submit once the previous frame's GL fence signals that
......@@ -564,21 +537,20 @@ void GvrSchedulerDelegate::SubmitDrawnFrame(bool is_webxr_frame) {
base::BindRepeating(&GvrSchedulerDelegate::DrawFrameSubmitWhenReady,
base::Unretained(this)));
task_runner()->PostTask(
FROM_HERE,
base::BindOnce(webxr_delayed_gvr_submit_.callback(), is_webxr_frame,
submit_head_pose, base::Passed(&fence)));
FROM_HERE, base::BindOnce(webxr_delayed_gvr_submit_.callback(),
frame_type, head_pose, base::Passed(&fence)));
} else {
// Continue with submit immediately.
DrawFrameSubmitNow(is_webxr_frame, submit_head_pose);
DrawFrameSubmitNow(frame_type, head_pose);
}
}
void GvrSchedulerDelegate::DrawFrameSubmitWhenReady(
bool is_webxr_frame,
FrameType frame_type,
const gfx::Transform& head_pose,
std::unique_ptr<gl::GLFenceEGL> fence) {
TRACE_EVENT1("gpu", __func__, "is_webxr_frame", is_webxr_frame);
DVLOG(2) << __func__ << ": is_webxr_frame=" << is_webxr_frame;
TRACE_EVENT1("gpu", __func__, "frame_type", frame_type);
DVLOG(2) << __func__ << ": frame_type=" << frame_type;
bool use_polling = webxr_.mailbox_bridge_ready() &&
mailbox_bridge_->IsGpuWorkaroundEnabled(
gpu::DONT_USE_EGLCLIENTWAITSYNC_WITH_TIMEOUT);
......@@ -600,13 +572,13 @@ void GvrSchedulerDelegate::DrawFrameSubmitWhenReady(
// with a delay of up to one polling interval.
task_runner()->PostDelayedTask(
FROM_HERE,
base::BindOnce(webxr_delayed_gvr_submit_.callback(), is_webxr_frame,
base::BindOnce(webxr_delayed_gvr_submit_.callback(), frame_type,
head_pose, base::Passed(&fence)),
kWebVRFenceCheckPollInterval);
} else {
task_runner()->PostTask(
FROM_HERE,
base::BindOnce(webxr_delayed_gvr_submit_.callback(), is_webxr_frame,
base::BindOnce(webxr_delayed_gvr_submit_.callback(), frame_type,
head_pose, base::Passed(&fence)));
}
return;
......@@ -620,7 +592,7 @@ void GvrSchedulerDelegate::DrawFrameSubmitWhenReady(
}
webxr_delayed_gvr_submit_.Cancel();
DrawFrameSubmitNow(is_webxr_frame, head_pose);
DrawFrameSubmitNow(frame_type, head_pose);
}
void GvrSchedulerDelegate::AddWebVrRenderTimeEstimate(
......@@ -636,14 +608,13 @@ void GvrSchedulerDelegate::AddWebVrRenderTimeEstimate(
}
}
void GvrSchedulerDelegate::DrawFrameSubmitNow(bool is_webxr_frame,
void GvrSchedulerDelegate::DrawFrameSubmitNow(FrameType frame_type,
const gfx::Transform& head_pose) {
TRACE_EVENT1("gpu", "GvrSchedulerDelegate::DrawFrameSubmitNow",
"is_webxr_frame", is_webxr_frame);
TRACE_EVENT1("gpu", "GvrSchedulerDelegate::DrawFrameSubmitNow", "frame_type",
frame_type);
{
std::unique_ptr<ScopedGpuTrace> browser_gpu_trace;
if (gl::GLFence::IsGpuFenceSupported() && is_webxr_frame) {
if (gl::GLFence::IsGpuFenceSupported() && frame_type == kWebXrFrame) {
// This fence instance is created for the tracing side effect. Insert it
// before GVR submit. Then replace the previous instance below after GVR
// submit completes, at which point the previous fence (if any) should be
......@@ -667,7 +638,7 @@ void GvrSchedulerDelegate::DrawFrameSubmitNow(bool is_webxr_frame,
// false for a WebVR frame. Ignore the ShouldDrawWebVr status to ensure we
// send render notifications while paused for exclusive UI mode. Skip the
// steps if we lost the processing state, that means presentation has ended.
if (is_webxr_frame && webxr_.HaveProcessingFrame()) {
if (frame_type == kWebXrFrame && webxr_.HaveProcessingFrame()) {
// Report rendering completion to the Renderer so that it's permitted to
// submit a fresh frame. We could do this earlier, as soon as the frame
// got pulled off the transfer surface, but that results in overstuffed
......@@ -697,7 +668,7 @@ void GvrSchedulerDelegate::DrawFrameSubmitNow(bool is_webxr_frame,
DVLOG(1) << "fps: " << vr_ui_fps_meter_.GetFPS();
TRACE_COUNTER1("gpu", "VR UI FPS", vr_ui_fps_meter_.GetFPS());
if (is_webxr_frame) {
if (frame_type == kWebXrFrame) {
// We finished processing a frame, this may make pending WebVR
// work eligible to proceed.
webxr_.TryDeferredProcessing();
......
......@@ -64,13 +64,14 @@ class GvrSchedulerDelegate : public BaseSchedulerDelegate,
private:
// SchedulerDelegate overrides.
gfx::Transform GetHeadPose() override;
void AddInputSourceState(device::mojom::XRInputSourceStatePtr state) override;
void OnPause() override;
void OnResume() override;
void OnTriggerEvent(bool pressed) override;
void SetWebXrMode(bool enabled) override;
void SetShowingVrDialog(bool showing) override;
void SubmitDrawnFrame(FrameType frame_type,
const gfx::Transform& head_pose) override;
void SetBrowserRenderer(
SchedulerBrowserRendererInterface* browser_renderer) override;
void ConnectPresentingService(
......@@ -84,11 +85,11 @@ class GvrSchedulerDelegate : public BaseSchedulerDelegate,
void DrawFrame(int16_t frame_index, base::TimeTicks current_time);
void WebVrSendRenderNotification(bool was_rendered);
void UpdatePendingBounds(int16_t frame_index);
void SubmitDrawnFrame(bool is_webxr_frame);
void DrawFrameSubmitWhenReady(bool is_webxr_frame,
void DrawFrameSubmitWhenReady(FrameType frame_type,
const gfx::Transform& head_pose,
std::unique_ptr<gl::GLFenceEGL> fence);
void DrawFrameSubmitNow(bool is_webxr_frame, const gfx::Transform& head_pose);
void DrawFrameSubmitNow(FrameType frame_type,
const gfx::Transform& head_pose);
// Used for discarding unwanted WebXR frames while UI is showing. We can't
// safely cancel frames from processing start until they show up in
......@@ -192,8 +193,6 @@ class GvrSchedulerDelegate : public BaseSchedulerDelegate,
AndroidVSyncHelper vsync_helper_;
gfx::Transform head_pose_;
mojo::Binding<device::mojom::XRPresentationProvider> presentation_binding_;
mojo::Binding<device::mojom::XRFrameDataProvider> frame_data_binding_;
......@@ -229,7 +228,7 @@ class GvrSchedulerDelegate : public BaseSchedulerDelegate,
// for later. If we exit WebVR before it is executed, we need to
// cancel it to avoid inconsistent state.
base::CancelableOnceCallback<
void(bool, const gfx::Transform&, std::unique_ptr<gl::GLFenceEGL>)>
void(FrameType, const gfx::Transform&, std::unique_ptr<gl::GLFenceEGL>)>
webxr_delayed_gvr_submit_;
std::unique_ptr<MailboxToSurfaceBridge> mailbox_bridge_;
......
......@@ -203,14 +203,15 @@ component("vr_common") {
"browser_renderer.cc",
"browser_renderer.h",
"browser_renderer_browser_interface.h",
"controller_delegate.h",
"controller_delegate_for_testing.cc",
"controller_delegate_for_testing.h",
"fps_meter.cc",
"fps_meter.h",
"frame_type.h",
"gesture_detector.cc",
"gesture_detector.h",
"graphics_delegate.h",
"input_delegate.h",
"input_delegate_for_testing.cc",
"input_delegate_for_testing.h",
"platform_controller.h",
"sample_queue.cc",
"sample_queue.h",
......
......@@ -9,7 +9,7 @@
#include "base/time/time.h"
#include "base/trace_event/common/trace_event_common.h"
#include "chrome/browser/vr/browser_renderer_browser_interface.h"
#include "chrome/browser/vr/controller_delegate_for_testing.h"
#include "chrome/browser/vr/input_delegate_for_testing.h"
#include "chrome/browser/vr/input_event.h"
#include "chrome/browser/vr/model/controller_model.h"
#include "chrome/browser/vr/model/reticle_model.h"
......@@ -26,13 +26,13 @@ BrowserRenderer::BrowserRenderer(
std::unique_ptr<UiInterface> ui,
std::unique_ptr<SchedulerDelegate> scheduler_delegate,
std::unique_ptr<GraphicsDelegate> graphics_delegate,
std::unique_ptr<ControllerDelegate> controller_delegate,
std::unique_ptr<InputDelegate> input_delegate,
BrowserRendererBrowserInterface* browser,
size_t sliding_time_size)
: ui_(std::move(ui)),
scheduler_delegate_(std::move(scheduler_delegate)),
graphics_delegate_(std::move(graphics_delegate)),
controller_delegate_(std::move(controller_delegate)),
input_delegate_(std::move(input_delegate)),
browser_(browser),
ui_processing_time_(sliding_time_size),
ui_controller_update_time_(sliding_time_size),
......@@ -43,18 +43,20 @@ BrowserRenderer::BrowserRenderer(
BrowserRenderer::~BrowserRenderer() = default;
void BrowserRenderer::DrawBrowserFrame(base::TimeTicks current_time) {
Draw(GraphicsDelegate::kUiFrame, current_time);
Draw(kUiFrame, current_time, input_delegate_->GetHeadPose());
}
void BrowserRenderer::DrawWebXrFrame(base::TimeTicks current_time) {
Draw(GraphicsDelegate::kWebXrFrame, current_time);
void BrowserRenderer::DrawWebXrFrame(base::TimeTicks current_time,
const gfx::Transform& head_pose) {
Draw(kWebXrFrame, current_time, head_pose);
}
void BrowserRenderer::Draw(GraphicsDelegate::FrameType frame_type,
base::TimeTicks current_time) {
void BrowserRenderer::Draw(FrameType frame_type,
base::TimeTicks current_time,
const gfx::Transform& head_pose) {
TRACE_EVENT1("gpu", __func__, "frame_type", frame_type);
const auto& render_info = graphics_delegate_->GetRenderInfo(
frame_type, scheduler_delegate_->GetHeadPose());
const auto& render_info =
graphics_delegate_->GetRenderInfo(frame_type, head_pose);
UpdateUi(render_info, current_time, frame_type);
ui_->OnProjMatrixChanged(render_info.left_eye_model.proj_matrix);
bool use_quad_layer = ui_->IsContentVisibleAndOpaque() &&
......@@ -62,7 +64,7 @@ void BrowserRenderer::Draw(GraphicsDelegate::FrameType frame_type,
ui_->SetContentUsesQuadLayer(use_quad_layer);
graphics_delegate_->InitializeBuffers();
if (frame_type == GraphicsDelegate::kWebXrFrame) {
if (frame_type == kWebXrFrame) {
DCHECK(!use_quad_layer);
DrawWebXr();
if (ui_->HasWebXrOverlayElementsToDraw())
......@@ -77,6 +79,8 @@ void BrowserRenderer::Draw(GraphicsDelegate::FrameType frame_type,
ui_processing_time_.GetAverage().InMicroseconds(),
"controller",
ui_controller_update_time_.GetAverage().InMicroseconds());
scheduler_delegate_->SubmitDrawnFrame(frame_type, head_pose);
}
void BrowserRenderer::DrawWebXr() {
......@@ -128,16 +132,16 @@ void BrowserRenderer::DrawBrowserUi(const RenderInfo& render_info) {
}
void BrowserRenderer::OnPause() {
DCHECK(controller_delegate_);
controller_delegate_->OnPause();
DCHECK(input_delegate_);
input_delegate_->OnPause();
scheduler_delegate_->OnPause();
ui_->OnPause();
}
void BrowserRenderer::OnResume() {
DCHECK(controller_delegate_);
DCHECK(input_delegate_);
scheduler_delegate_->OnResume();
controller_delegate_->OnResume();
input_delegate_->OnResume();
}
void BrowserRenderer::OnExitPresent() {
......@@ -251,7 +255,7 @@ void BrowserRenderer::AcceptDoffPromptForTesting() {
void BrowserRenderer::UpdateUi(const RenderInfo& render_info,
base::TimeTicks current_time,
GraphicsDelegate::FrameType frame_type) {
FrameType frame_type) {
TRACE_EVENT0("gpu", __func__);
// Update the render position of all UI elements.
......@@ -260,7 +264,7 @@ void BrowserRenderer::UpdateUi(const RenderInfo& render_info,
// WebXR handles controller input in OnVsync.
base::TimeDelta controller_time;
if (frame_type == GraphicsDelegate::kUiFrame)
if (frame_type == kUiFrame)
controller_time = ProcessControllerInput(render_info, current_time);
if (ui_->SceneHasDirtyTextures()) {
......@@ -281,19 +285,19 @@ void BrowserRenderer::UpdateUi(const RenderInfo& render_info,
void BrowserRenderer::ProcessControllerInputForWebXr(
base::TimeTicks current_time) {
TRACE_EVENT0("gpu", __func__);
DCHECK(controller_delegate_);
DCHECK(input_delegate_);
DCHECK(ui_);
base::TimeTicks timing_start = base::TimeTicks::Now();
controller_delegate_->UpdateController(scheduler_delegate_->GetHeadPose(),
current_time, true);
auto input_event_list = controller_delegate_->GetGestures(current_time);
// No transform required for input handling while in WebXR.
input_delegate_->UpdateController(gfx::Transform(), current_time, true);
auto input_event_list = input_delegate_->GetGestures(current_time);
ui_->HandleMenuButtonEvents(&input_event_list);
ui_controller_update_time_.AddSample(base::TimeTicks::Now() - timing_start);
scheduler_delegate_->AddInputSourceState(
controller_delegate_->GetInputSourceState());
input_delegate_->GetInputSourceState());
}
void BrowserRenderer::ConnectPresentingService(
......@@ -307,16 +311,15 @@ base::TimeDelta BrowserRenderer::ProcessControllerInput(
const RenderInfo& render_info,
base::TimeTicks current_time) {
TRACE_EVENT0("gpu", __func__);
DCHECK(controller_delegate_);
DCHECK(input_delegate_);
DCHECK(ui_);
base::TimeTicks timing_start = base::TimeTicks::Now();
controller_delegate_->UpdateController(render_info.head_pose, current_time,
false);
auto input_event_list = controller_delegate_->GetGestures(current_time);
input_delegate_->UpdateController(render_info.head_pose, current_time, false);
auto input_event_list = input_delegate_->GetGestures(current_time);
ReticleModel reticle_model;
ControllerModel controller_model =
controller_delegate_->GetModel(render_info.head_pose);
input_delegate_->GetControllerModel(render_info.head_pose);
ui_->HandleInput(current_time, render_info, controller_model, &reticle_model,
&input_event_list);
ui_->OnControllerUpdated(controller_model, reticle_model);
......@@ -328,30 +331,29 @@ base::TimeDelta BrowserRenderer::ProcessControllerInput(
void BrowserRenderer::PerformControllerActionForTesting(
ControllerTestInput controller_input) {
DCHECK(controller_delegate_);
DCHECK(input_delegate_);
if (controller_input.action ==
VrControllerTestAction::kRevertToRealController) {
if (using_controller_delegate_for_testing_) {
DCHECK(
static_cast<ControllerDelegateForTesting*>(controller_delegate_.get())
->IsQueueEmpty())
if (using_input_delegate_for_testing_) {
DCHECK(static_cast<InputDelegateForTesting*>(input_delegate_.get())
->IsQueueEmpty())
<< "Attempted to revert to using real controller with actions still "
"queued";
using_controller_delegate_for_testing_ = false;
controller_delegate_for_testing_.swap(controller_delegate_);
using_input_delegate_for_testing_ = false;
input_delegate_for_testing_.swap(input_delegate_);
}
return;
}
if (!using_controller_delegate_for_testing_) {
using_controller_delegate_for_testing_ = true;
if (!controller_delegate_for_testing_)
controller_delegate_for_testing_ =
std::make_unique<ControllerDelegateForTesting>(ui_.get());
controller_delegate_for_testing_.swap(controller_delegate_);
if (!using_input_delegate_for_testing_) {
using_input_delegate_for_testing_ = true;
if (!input_delegate_for_testing_)
input_delegate_for_testing_ =
std::make_unique<InputDelegateForTesting>(ui_.get());
input_delegate_for_testing_.swap(input_delegate_);
}
if (controller_input.action !=
VrControllerTestAction::kEnableMockedController) {
static_cast<ControllerDelegateForTesting*>(controller_delegate_.get())
static_cast<InputDelegateForTesting*>(input_delegate_.get())
->QueueControllerActionForTesting(controller_input);
}
}
......
......@@ -26,7 +26,7 @@ namespace vr {
enum class VrUiTestActivityResult;
class BrowserUiInterface;
class ControllerDelegate;
class InputDelegate;
class PlatformInputHandler;
class PlatformUiInputDelegate;
class BrowserRendererBrowserInterface;
......@@ -45,7 +45,7 @@ class VR_EXPORT BrowserRenderer : public SchedulerBrowserRendererInterface {
BrowserRenderer(std::unique_ptr<UiInterface> ui,
std::unique_ptr<SchedulerDelegate> scheduler_delegate,
std::unique_ptr<GraphicsDelegate> graphics_delegate,
std::unique_ptr<ControllerDelegate> controller_delegate,
std::unique_ptr<InputDelegate> input_delegate,
BrowserRendererBrowserInterface* browser,
size_t sliding_time_size);
~BrowserRenderer() override;
......@@ -82,20 +82,22 @@ class VR_EXPORT BrowserRenderer : public SchedulerBrowserRendererInterface {
device::mojom::VRDisplayInfoPtr display_info,
device::mojom::XRRuntimeSessionOptionsPtr options);
private:
// SchedulerBrowserRendererInterface implementation.
void DrawBrowserFrame(base::TimeTicks current_time) override;
void DrawWebXrFrame(base::TimeTicks current_time) override;
void DrawWebXrFrame(base::TimeTicks current_time,
const gfx::Transform& head_pose) override;
void ProcessControllerInputForWebXr(base::TimeTicks current_time) override;
private:
void Draw(GraphicsDelegate::FrameType frame_type,
base::TimeTicks current_time);
void Draw(FrameType frame_type,
base::TimeTicks current_time,
const gfx::Transform& head_pose);
// Position, hide and/or show UI elements, process input and update textures.
// Returns true if the scene changed.
void UpdateUi(const RenderInfo& render_info,
base::TimeTicks currrent_time,
GraphicsDelegate::FrameType frame_type);
FrameType frame_type);
void DrawWebXr();
void DrawWebXrOverlay(const RenderInfo& render_info);
void DrawContentQuad();
......@@ -110,9 +112,9 @@ class VR_EXPORT BrowserRenderer : public SchedulerBrowserRendererInterface {
std::unique_ptr<UiInterface> ui_;
std::unique_ptr<SchedulerDelegate> scheduler_delegate_;
std::unique_ptr<GraphicsDelegate> graphics_delegate_;
std::unique_ptr<ControllerDelegate> controller_delegate_;
std::unique_ptr<ControllerDelegate> controller_delegate_for_testing_;
bool using_controller_delegate_for_testing_ = false;
std::unique_ptr<InputDelegate> input_delegate_;
std::unique_ptr<InputDelegate> input_delegate_for_testing_;
bool using_input_delegate_for_testing_ = false;
std::unique_ptr<PlatformUiInputDelegate> vr_dialog_input_delegate_;
......
// 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_FRAME_TYPE_H_
#define CHROME_BROWSER_VR_FRAME_TYPE_H_
namespace vr {
enum FrameType { kUiFrame, kWebXrFrame };
} // namespace vr
#endif // CHROME_BROWSER_VR_FRAME_TYPE_H_
......@@ -7,6 +7,7 @@
#include "base/callback.h"
#include "chrome/browser/vr/fov_rectangle.h"
#include "chrome/browser/vr/frame_type.h"
#include "chrome/browser/vr/gl_texture_location.h"
#include "chrome/browser/vr/vr_export.h"
......@@ -29,7 +30,6 @@ struct RenderInfo;
class VR_EXPORT GraphicsDelegate {
public:
using Transform = float[16];
enum FrameType { kUiFrame, kWebXrFrame };
using SkiaContextCallback = base::OnceCallback<void()>;
using TexturesInitializedCallback = base::OnceCallback<
void(GlTextureLocation, unsigned int, unsigned int, unsigned int)>;
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_VR_CONTROLLER_DELEGATE_H_
#define CHROME_BROWSER_VR_CONTROLLER_DELEGATE_H_
#ifndef CHROME_BROWSER_VR_INPUT_DELEGATE_H_
#define CHROME_BROWSER_VR_INPUT_DELEGATE_H_
#include <memory>
#include <vector>
......@@ -22,16 +22,17 @@ struct ControllerModel;
using InputEventList = std::vector<std::unique_ptr<InputEvent>>;
// Communicates with the PlatformController to update it and obtain input and
// movement information.
class ControllerDelegate {
// Obtains input from the controller and head poses from the headset.
class InputDelegate {
public:
virtual ~ControllerDelegate() {}
virtual ~InputDelegate() {}
virtual gfx::Transform GetHeadPose() = 0;
virtual void UpdateController(const gfx::Transform& head_pose,
base::TimeTicks current_time,
bool is_webxr_frame) = 0;
virtual ControllerModel GetModel(const gfx::Transform& head_pose) = 0;
virtual ControllerModel GetControllerModel(
const gfx::Transform& head_pose) = 0;
virtual InputEventList GetGestures(base::TimeTicks current_time) = 0;
virtual device::mojom::XRInputSourceStatePtr GetInputSourceState() = 0;
virtual void OnResume() = 0;
......@@ -40,4 +41,4 @@ class ControllerDelegate {
} // namespace vr
#endif // CHROME_BROWSER_VR_CONTROLLER_DELEGATE_H_
#endif // CHROME_BROWSER_VR_INPUT_DELEGATE_H_
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/vr/controller_delegate_for_testing.h"
#include "chrome/browser/vr/input_delegate_for_testing.h"
#include "chrome/browser/vr/input_event.h"
#include "chrome/browser/vr/ui_interface.h"
......@@ -34,15 +34,18 @@ void SetOriginAndTransform(vr::ControllerModel* model) {
namespace vr {
ControllerDelegateForTesting::ControllerDelegateForTesting(UiInterface* ui)
: ui_(ui) {
InputDelegateForTesting::InputDelegateForTesting(UiInterface* ui) : ui_(ui) {
cached_controller_model_.laser_direction = kForwardVector;
SetOriginAndTransform(&cached_controller_model_);
}
ControllerDelegateForTesting::~ControllerDelegateForTesting() = default;
InputDelegateForTesting::~InputDelegateForTesting() = default;
void ControllerDelegateForTesting::QueueControllerActionForTesting(
gfx::Transform InputDelegateForTesting::GetHeadPose() {
return gfx::Transform();
}
void InputDelegateForTesting::QueueControllerActionForTesting(
ControllerTestInput controller_input) {
DCHECK_NE(controller_input.action,
VrControllerTestAction::kRevertToRealController);
......@@ -92,14 +95,13 @@ void ControllerDelegateForTesting::QueueControllerActionForTesting(
}
}
bool ControllerDelegateForTesting::IsQueueEmpty() const {
bool InputDelegateForTesting::IsQueueEmpty() const {
return controller_model_queue_.empty();
}
void ControllerDelegateForTesting::UpdateController(
const gfx::Transform& head_pose,
base::TimeTicks current_time,
bool is_webxr_frame) {
void InputDelegateForTesting::UpdateController(const gfx::Transform& head_pose,
base::TimeTicks current_time,
bool is_webxr_frame) {
if (!controller_model_queue_.empty()) {
cached_controller_model_ = controller_model_queue_.front();
controller_model_queue_.pop();
......@@ -108,18 +110,18 @@ void ControllerDelegateForTesting::UpdateController(
cached_controller_model_.last_button_timestamp = current_time;
}
ControllerModel ControllerDelegateForTesting::GetModel(
ControllerModel InputDelegateForTesting::GetControllerModel(
const gfx::Transform& head_pose) {
return cached_controller_model_;
}
InputEventList ControllerDelegateForTesting::GetGestures(
InputEventList InputDelegateForTesting::GetGestures(
base::TimeTicks current_time) {
return InputEventList();
}
device::mojom::XRInputSourceStatePtr
ControllerDelegateForTesting::GetInputSourceState() {
InputDelegateForTesting::GetInputSourceState() {
auto state = device::mojom::XRInputSourceState::New();
state->description = device::mojom::XRInputSourceDescription::New();
state->source_id = 1;
......@@ -130,8 +132,8 @@ ControllerDelegateForTesting::GetInputSourceState() {
return state;
}
void ControllerDelegateForTesting::OnResume() {}
void InputDelegateForTesting::OnResume() {}
void ControllerDelegateForTesting::OnPause() {}
void InputDelegateForTesting::OnPause() {}
} // namespace vr
......@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_VR_CONTROLLER_DELEGATE_FOR_TESTING_H_
#define CHROME_BROWSER_VR_CONTROLLER_DELEGATE_FOR_TESTING_H_
#ifndef CHROME_BROWSER_VR_INPUT_DELEGATE_FOR_TESTING_H_
#define CHROME_BROWSER_VR_INPUT_DELEGATE_FOR_TESTING_H_
#include <queue>
#include "base/macros.h"
#include "chrome/browser/vr/controller_delegate.h"
#include "chrome/browser/vr/input_delegate.h"
#include "chrome/browser/vr/model/controller_model.h"
namespace vr {
......@@ -16,19 +16,20 @@ namespace vr {
class UiInterface;
struct ControllerTestInput;
class ControllerDelegateForTesting : public ControllerDelegate {
class InputDelegateForTesting : public InputDelegate {
public:
explicit ControllerDelegateForTesting(UiInterface* ui);
~ControllerDelegateForTesting() override;
explicit InputDelegateForTesting(UiInterface* ui);
~InputDelegateForTesting() override;
void QueueControllerActionForTesting(ControllerTestInput controller_input);
bool IsQueueEmpty() const;
// ControllerDelegate implementation.
// InputDelegate implementation.
gfx::Transform GetHeadPose() override;
void UpdateController(const gfx::Transform& head_pose,
base::TimeTicks current_time,
bool is_webxr_frame) override;
ControllerModel GetModel(const gfx::Transform& head_pose) override;
ControllerModel GetControllerModel(const gfx::Transform& head_pose) override;
InputEventList GetGestures(base::TimeTicks current_time) override;
device::mojom::XRInputSourceStatePtr GetInputSourceState() override;
void OnResume() override;
......@@ -39,9 +40,9 @@ class ControllerDelegateForTesting : public ControllerDelegate {
std::queue<ControllerModel> controller_model_queue_;
ControllerModel cached_controller_model_;
DISALLOW_COPY_AND_ASSIGN(ControllerDelegateForTesting);
DISALLOW_COPY_AND_ASSIGN(InputDelegateForTesting);
};
} // namespace vr
#endif // CHROME_BROWSER_VR_CONTROLLER_DELEGATE_FOR_TESTING_H_
#endif // CHROME_BROWSER_VR_INPUT_DELEGATE_FOR_TESTING_H_
......@@ -9,13 +9,19 @@ namespace base {
class TimeTicks;
}
namespace gfx {
class Transform;
}
namespace vr {
class SchedulerBrowserRendererInterface {
public:
virtual ~SchedulerBrowserRendererInterface() {}
virtual void DrawBrowserFrame(base::TimeTicks current_time) = 0;
virtual void DrawWebXrFrame(base::TimeTicks current_time) = 0;
// Pass the same head_pose used to render the submitted WebXR frame.
virtual void DrawWebXrFrame(base::TimeTicks current_time,
const gfx::Transform& head_pose) = 0;
virtual void ProcessControllerInputForWebXr(base::TimeTicks current_time) = 0;
};
......
......@@ -7,6 +7,7 @@
#include "base/callback.h"
#include "base/time/time.h"
#include "chrome/browser/vr/frame_type.h"
#include "chrome/browser/vr/vr_export.h"
#include "device/vr/public/mojom/isolated_xr_service.mojom.h"
#include "device/vr/public/mojom/vr_service.mojom.h"
......@@ -21,9 +22,7 @@ class SchedulerBrowserRendererInterface;
// The SchedulerDelegate is responsible for starting the draw calls of the
// BrowserRenderer, given different signals, such as WebXR frames submitted or
// VSync events. It also provides head poses, obtained from the underlaying
// platform.
// TODO(acondor): Move head pose logic to the ControllerDelegate.
// VSync events.
class VR_EXPORT SchedulerDelegate {
public:
virtual ~SchedulerDelegate() {}
......@@ -31,13 +30,14 @@ class VR_EXPORT SchedulerDelegate {
virtual void OnPause() = 0;
virtual void OnResume() = 0;
virtual gfx::Transform GetHeadPose() = 0;
virtual void OnExitPresent() = 0;
virtual void OnTriggerEvent(bool pressed) = 0;
virtual void SetWebXrMode(bool enabled) = 0;
virtual void SetShowingVrDialog(bool showing) = 0;
virtual void SetBrowserRenderer(
SchedulerBrowserRendererInterface* browser_renderer) = 0;
virtual void SubmitDrawnFrame(FrameType frame_type,
const gfx::Transform& transform) = 0;
virtual void AddInputSourceState(
device::mojom::XRInputSourceStatePtr state) = 0;
virtual void ConnectPresentingService(
......
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