Aldo Culquicondor | cc004c7 | 2018-08-02 14:50:02 | [diff] [blame] | 1 | // Copyright 2018 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 5 | #include "chrome/browser/vr/browser_renderer.h" |
Aldo Culquicondor | cc004c7 | 2018-08-02 14:50:02 | [diff] [blame] | 6 | |
| 7 | #include <utility> |
| 8 | |
Sebastien Marchand | f1349f5 | 2019-01-25 03:16:41 | [diff] [blame] | 9 | #include "base/bind.h" |
Aldo Culquicondor | cc004c7 | 2018-08-02 14:50:02 | [diff] [blame] | 10 | #include "base/time/time.h" |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 11 | #include "base/trace_event/common/trace_event_common.h" |
James Cook | 500a245e | 2019-10-02 19:18:35 | [diff] [blame] | 12 | #include "base/trace_event/trace_event.h" |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 13 | #include "chrome/browser/vr/browser_renderer_browser_interface.h" |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 14 | #include "chrome/browser/vr/input_delegate_for_testing.h" |
Aldo Culquicondor | cc004c7 | 2018-08-02 14:50:02 | [diff] [blame] | 15 | #include "chrome/browser/vr/input_event.h" |
| 16 | #include "chrome/browser/vr/model/controller_model.h" |
Aldo Culquicondor | 3c315ea0 | 2018-08-13 20:45:09 | [diff] [blame] | 17 | #include "chrome/browser/vr/model/reticle_model.h" |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 18 | #include "chrome/browser/vr/platform_ui_input_delegate.h" |
Aldo Culquicondor | 3c315ea0 | 2018-08-13 20:45:09 | [diff] [blame] | 19 | #include "chrome/browser/vr/render_info.h" |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 20 | #include "chrome/browser/vr/scheduler_delegate.h" |
Aldo Culquicondor | cc004c7 | 2018-08-02 14:50:02 | [diff] [blame] | 21 | #include "chrome/browser/vr/ui_interface.h" |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 22 | #include "chrome/browser/vr/ui_test_input.h" |
Aldo Culquicondor | cc004c7 | 2018-08-02 14:50:02 | [diff] [blame] | 23 | |
| 24 | namespace vr { |
| 25 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 26 | BrowserRenderer::BrowserRenderer( |
| 27 | std::unique_ptr<UiInterface> ui, |
| 28 | std::unique_ptr<SchedulerDelegate> scheduler_delegate, |
| 29 | std::unique_ptr<GraphicsDelegate> graphics_delegate, |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 30 | std::unique_ptr<InputDelegate> input_delegate, |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 31 | BrowserRendererBrowserInterface* browser, |
| 32 | size_t sliding_time_size) |
Bill Orr | cee3abc | 2018-11-07 01:00:22 | [diff] [blame] | 33 | : scheduler_delegate_(std::move(scheduler_delegate)), |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 34 | graphics_delegate_(std::move(graphics_delegate)), |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 35 | input_delegate_(std::move(input_delegate)), |
Aldo Culquicondor | 173c0a1 | 2018-08-16 15:39:08 | [diff] [blame] | 36 | browser_(browser), |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 37 | ui_processing_time_(sliding_time_size), |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 38 | ui_controller_update_time_(sliding_time_size), |
Jeremy Roman | 495db68 | 2019-07-12 16:03:24 | [diff] [blame] | 39 | ui_(std::move(ui)) { |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 40 | scheduler_delegate_->SetBrowserRenderer(this); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 41 | } |
| 42 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 43 | BrowserRenderer::~BrowserRenderer() = default; |
Aldo Culquicondor | cc004c7 | 2018-08-02 14:50:02 | [diff] [blame] | 44 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 45 | void BrowserRenderer::DrawBrowserFrame(base::TimeTicks current_time) { |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 46 | Draw(kUiFrame, current_time, input_delegate_->GetHeadPose()); |
Aldo Culquicondor | b8985eb | 2018-09-06 22:27:44 | [diff] [blame] | 47 | } |
| 48 | |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 49 | void BrowserRenderer::DrawWebXrFrame(base::TimeTicks current_time, |
| 50 | const gfx::Transform& head_pose) { |
| 51 | Draw(kWebXrFrame, current_time, head_pose); |
Aldo Culquicondor | b8985eb | 2018-09-06 22:27:44 | [diff] [blame] | 52 | } |
| 53 | |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 54 | void BrowserRenderer::Draw(FrameType frame_type, |
| 55 | base::TimeTicks current_time, |
| 56 | const gfx::Transform& head_pose) { |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 57 | TRACE_EVENT1("gpu", __func__, "frame_type", frame_type); |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 58 | const auto& render_info = |
| 59 | graphics_delegate_->GetRenderInfo(frame_type, head_pose); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 60 | UpdateUi(render_info, current_time, frame_type); |
| 61 | ui_->OnProjMatrixChanged(render_info.left_eye_model.proj_matrix); |
| 62 | bool use_quad_layer = ui_->IsContentVisibleAndOpaque() && |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 63 | graphics_delegate_->IsContentQuadReady(); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 64 | ui_->SetContentUsesQuadLayer(use_quad_layer); |
| 65 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 66 | graphics_delegate_->InitializeBuffers(); |
bsheedy | fa3e442 | 2018-09-18 21:39:31 | [diff] [blame] | 67 | graphics_delegate_->SetFrameDumpFilepathBase( |
| 68 | frame_buffer_dump_filepath_base_); |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 69 | if (frame_type == kWebXrFrame) { |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 70 | DCHECK(!use_quad_layer); |
| 71 | DrawWebXr(); |
| 72 | if (ui_->HasWebXrOverlayElementsToDraw()) |
| 73 | DrawWebXrOverlay(render_info); |
| 74 | } else { |
| 75 | if (use_quad_layer) |
| 76 | DrawContentQuad(); |
| 77 | DrawBrowserUi(render_info); |
| 78 | } |
| 79 | |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 80 | TRACE_COUNTER2("gpu", "VR UI timing (us)", "scene update", |
| 81 | ui_processing_time_.GetAverage().InMicroseconds(), |
| 82 | "controller", |
| 83 | ui_controller_update_time_.GetAverage().InMicroseconds()); |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 84 | |
bsheedy | fa3e442 | 2018-09-18 21:39:31 | [diff] [blame] | 85 | ReportFrameBufferDumpForTesting(); |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 86 | scheduler_delegate_->SubmitDrawnFrame(frame_type, head_pose); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 87 | } |
| 88 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 89 | void BrowserRenderer::DrawWebXr() { |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 90 | TRACE_EVENT0("gpu", __func__); |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 91 | graphics_delegate_->PrepareBufferForWebXr(); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 92 | |
| 93 | int texture_id; |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 94 | GraphicsDelegate::Transform uv_transform; |
| 95 | graphics_delegate_->GetWebXrDrawParams(&texture_id, &uv_transform); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 96 | ui_->DrawWebXr(texture_id, uv_transform); |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 97 | graphics_delegate_->OnFinishedDrawingBuffer(); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 98 | } |
| 99 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 100 | void BrowserRenderer::DrawWebXrOverlay(const RenderInfo& render_info) { |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 101 | TRACE_EVENT0("gpu", __func__); |
| 102 | // Calculate optimized viewport and corresponding render info. |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 103 | const auto& recommended_fovs = graphics_delegate_->GetRecommendedFovs(); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 104 | const auto& fovs = ui_->GetMinimalFovForWebXrOverlayElements( |
| 105 | render_info.left_eye_model.view_matrix, recommended_fovs.first, |
| 106 | render_info.right_eye_model.view_matrix, recommended_fovs.second, |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 107 | graphics_delegate_->GetZNear()); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 108 | const auto& webxr_overlay_render_info = |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 109 | graphics_delegate_->GetOptimizedRenderInfoForFovs(fovs); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 110 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 111 | graphics_delegate_->PrepareBufferForWebXrOverlayElements(); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 112 | ui_->DrawWebVrOverlayForeground(webxr_overlay_render_info); |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 113 | graphics_delegate_->OnFinishedDrawingBuffer(); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 114 | } |
| 115 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 116 | void BrowserRenderer::DrawContentQuad() { |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 117 | TRACE_EVENT0("gpu", __func__); |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 118 | graphics_delegate_->PrepareBufferForContentQuadLayer( |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 119 | ui_->GetContentWorldSpaceTransform()); |
| 120 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 121 | GraphicsDelegate::Transform uv_transform; |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 122 | float border_x; |
| 123 | float border_y; |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 124 | graphics_delegate_->GetContentQuadDrawParams(&uv_transform, &border_x, |
| 125 | &border_y); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 126 | ui_->DrawContent(uv_transform, border_x, border_y); |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 127 | graphics_delegate_->OnFinishedDrawingBuffer(); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 128 | } |
| 129 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 130 | void BrowserRenderer::DrawBrowserUi(const RenderInfo& render_info) { |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 131 | TRACE_EVENT0("gpu", __func__); |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 132 | graphics_delegate_->PrepareBufferForBrowserUi(); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 133 | ui_->Draw(render_info); |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 134 | graphics_delegate_->OnFinishedDrawingBuffer(); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 135 | } |
| 136 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 137 | void BrowserRenderer::OnPause() { |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 138 | DCHECK(input_delegate_); |
| 139 | input_delegate_->OnPause(); |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 140 | scheduler_delegate_->OnPause(); |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 141 | ui_->OnPause(); |
| 142 | } |
| 143 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 144 | void BrowserRenderer::OnResume() { |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 145 | DCHECK(input_delegate_); |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 146 | scheduler_delegate_->OnResume(); |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 147 | input_delegate_->OnResume(); |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 148 | } |
| 149 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 150 | void BrowserRenderer::OnExitPresent() { |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 151 | scheduler_delegate_->OnExitPresent(); |
| 152 | } |
| 153 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 154 | void BrowserRenderer::OnTriggerEvent(bool pressed) { |
Aldo Culquicondor | 2df78d1 | 2018-09-18 19:50:47 | [diff] [blame] | 155 | input_delegate_->OnTriggerEvent(pressed); |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 156 | } |
| 157 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 158 | void BrowserRenderer::SetWebXrMode(bool enabled) { |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 159 | scheduler_delegate_->SetWebXrMode(enabled); |
| 160 | } |
| 161 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 162 | void BrowserRenderer::EnableAlertDialog(PlatformInputHandler* input_handler, |
| 163 | float width, |
| 164 | float height) { |
Aldo Culquicondor | b8985eb | 2018-09-06 22:27:44 | [diff] [blame] | 165 | scheduler_delegate_->SetShowingVrDialog(true); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 166 | vr_dialog_input_delegate_ = |
| 167 | std::make_unique<PlatformUiInputDelegate>(input_handler); |
| 168 | vr_dialog_input_delegate_->SetSize(width, height); |
Aldo Culquicondor | b8985eb | 2018-09-06 22:27:44 | [diff] [blame] | 169 | if (ui_->IsContentVisibleAndOpaque()) { |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 170 | auto content_width = graphics_delegate_->GetContentBufferWidth(); |
Aldo Culquicondor | b8985eb | 2018-09-06 22:27:44 | [diff] [blame] | 171 | DCHECK(content_width); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 172 | ui_->SetContentOverlayAlertDialogEnabled( |
| 173 | true, vr_dialog_input_delegate_.get(), width / content_width, |
| 174 | height / content_width); |
| 175 | } else { |
| 176 | ui_->SetAlertDialogEnabled(true, vr_dialog_input_delegate_.get(), width, |
| 177 | height); |
| 178 | } |
| 179 | } |
| 180 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 181 | void BrowserRenderer::DisableAlertDialog() { |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 182 | ui_->SetAlertDialogEnabled(false, nullptr, 0, 0); |
| 183 | vr_dialog_input_delegate_ = nullptr; |
Aldo Culquicondor | b8985eb | 2018-09-06 22:27:44 | [diff] [blame] | 184 | scheduler_delegate_->SetShowingVrDialog(false); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 185 | } |
| 186 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 187 | void BrowserRenderer::SetAlertDialogSize(float width, float height) { |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 188 | if (vr_dialog_input_delegate_) |
| 189 | vr_dialog_input_delegate_->SetSize(width, height); |
| 190 | // If not floating, dialogs are rendered with a fixed width, so that only the |
| 191 | // ratio matters. But, if they are floating, its size should be relative to |
| 192 | // the contents. During a WebXR presentation, the contents are not present |
| 193 | // but, in this case, the dialogs are never floating. |
Aldo Culquicondor | b8985eb | 2018-09-06 22:27:44 | [diff] [blame] | 194 | if (ui_->IsContentVisibleAndOpaque()) { |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 195 | auto content_width = graphics_delegate_->GetContentBufferWidth(); |
Aldo Culquicondor | b8985eb | 2018-09-06 22:27:44 | [diff] [blame] | 196 | DCHECK(content_width); |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 197 | ui_->SetContentOverlayAlertDialogEnabled( |
| 198 | true, vr_dialog_input_delegate_.get(), width / content_width, |
| 199 | height / content_width); |
| 200 | } else { |
| 201 | ui_->SetAlertDialogEnabled(true, vr_dialog_input_delegate_.get(), width, |
| 202 | height); |
| 203 | } |
| 204 | } |
| 205 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 206 | void BrowserRenderer::ResumeContentRendering() { |
| 207 | graphics_delegate_->ResumeContentRendering(); |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 208 | } |
| 209 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 210 | void BrowserRenderer::BufferBoundsChanged( |
| 211 | const gfx::Size& content_buffer_size, |
| 212 | const gfx::Size& overlay_buffer_size) { |
| 213 | graphics_delegate_->BufferBoundsChanged(content_buffer_size, |
| 214 | overlay_buffer_size); |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 215 | } |
| 216 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 217 | base::WeakPtr<BrowserUiInterface> BrowserRenderer::GetBrowserUiWeakPtr() { |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 218 | return ui_->GetBrowserUiWeakPtr(); |
| 219 | } |
| 220 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 221 | void BrowserRenderer::SetUiExpectingActivityForTesting( |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 222 | UiTestActivityExpectation ui_expectation) { |
| 223 | DCHECK(ui_test_state_ == nullptr) |
| 224 | << "Attempted to set a UI activity expectation with one in progress"; |
| 225 | ui_test_state_ = std::make_unique<UiTestState>(); |
| 226 | ui_test_state_->quiescence_timeout_ms = |
| 227 | base::TimeDelta::FromMilliseconds(ui_expectation.quiescence_timeout_ms); |
| 228 | } |
| 229 | |
bsheedy | fa3e442 | 2018-09-18 21:39:31 | [diff] [blame] | 230 | void BrowserRenderer::SaveNextFrameBufferToDiskForTesting( |
| 231 | std::string filepath_base) { |
| 232 | frame_buffer_dump_filepath_base_ = filepath_base; |
| 233 | } |
| 234 | |
bsheedy | dc7c6cb | 2018-11-05 20:48:45 | [diff] [blame] | 235 | void BrowserRenderer::WatchElementForVisibilityStatusForTesting( |
bsheedy | a2ff343 | 2018-10-02 18:16:58 | [diff] [blame] | 236 | VisibilityChangeExpectation visibility_expectation) { |
| 237 | DCHECK(ui_visibility_state_ == nullptr) << "Attempted to watch a UI element " |
| 238 | "for visibility changes with one " |
| 239 | "in progress"; |
| 240 | ui_visibility_state_ = std::make_unique<UiVisibilityState>(); |
| 241 | ui_visibility_state_->timeout_ms = |
| 242 | base::TimeDelta::FromMilliseconds(visibility_expectation.timeout_ms); |
| 243 | ui_visibility_state_->element_to_watch = visibility_expectation.element_name; |
bsheedy | dc7c6cb | 2018-11-05 20:48:45 | [diff] [blame] | 244 | ui_visibility_state_->expected_visibile = visibility_expectation.visibility; |
bsheedy | a2ff343 | 2018-10-02 18:16:58 | [diff] [blame] | 245 | } |
| 246 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 247 | void BrowserRenderer::AcceptDoffPromptForTesting() { |
Aldo Culquicondor | 5dc384bf | 2018-08-22 23:42:36 | [diff] [blame] | 248 | ui_->AcceptDoffPromptForTesting(); |
| 249 | } |
| 250 | |
bsheedy | acb0f35 | 2019-01-16 23:30:14 | [diff] [blame] | 251 | void BrowserRenderer::SetBrowserRendererBrowserInterfaceForTesting( |
Eric Lawrence | 138de76f | 2019-01-17 19:15:06 | [diff] [blame] | 252 | BrowserRendererBrowserInterface* interface_ptr) { |
| 253 | browser_ = interface_ptr; |
bsheedy | acb0f35 | 2019-01-16 23:30:14 | [diff] [blame] | 254 | } |
| 255 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 256 | void BrowserRenderer::UpdateUi(const RenderInfo& render_info, |
| 257 | base::TimeTicks current_time, |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 258 | FrameType frame_type) { |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 259 | TRACE_EVENT0("gpu", __func__); |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 260 | |
| 261 | // Update the render position of all UI elements. |
| 262 | base::TimeTicks timing_start = base::TimeTicks::Now(); |
| 263 | bool ui_updated = ui_->OnBeginFrame(current_time, render_info.head_pose); |
| 264 | |
| 265 | // WebXR handles controller input in OnVsync. |
| 266 | base::TimeDelta controller_time; |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 267 | if (frame_type == kUiFrame) |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 268 | controller_time = ProcessControllerInput(render_info, current_time); |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 269 | |
| 270 | if (ui_->SceneHasDirtyTextures()) { |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 271 | if (!graphics_delegate_->RunInSkiaContext(base::BindOnce( |
Aldo Culquicondor | 7e4d7965 | 2018-08-15 19:11:54 | [diff] [blame] | 272 | &UiInterface::UpdateSceneTextures, base::Unretained(ui_.get())))) { |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 273 | browser_->ForceExitVr(); |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 274 | return; |
| 275 | } |
| 276 | ui_updated = true; |
| 277 | } |
| 278 | ReportUiStatusForTesting(timing_start, ui_updated); |
bsheedy | a2ff343 | 2018-10-02 18:16:58 | [diff] [blame] | 279 | ReportElementVisibilityStatusForTesting(timing_start); |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 280 | |
| 281 | base::TimeDelta scene_time = base::TimeTicks::Now() - timing_start; |
| 282 | // Don't double-count the controller time that was part of the scene time. |
| 283 | ui_processing_time_.AddSample(scene_time - controller_time); |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 284 | } |
| 285 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 286 | void BrowserRenderer::ProcessControllerInputForWebXr( |
Klaus Weidner | d3e9434 | 2019-05-30 04:21:53 | [diff] [blame] | 287 | const gfx::Transform& head_pose, |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 288 | base::TimeTicks current_time) { |
Aldo Culquicondor | bede7f32 | 2018-09-12 21:21:06 | [diff] [blame] | 289 | TRACE_EVENT0("gpu", "Vr.ProcessControllerInputForWebXr"); |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 290 | DCHECK(input_delegate_); |
Aldo Culquicondor | cc004c7 | 2018-08-02 14:50:02 | [diff] [blame] | 291 | DCHECK(ui_); |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 292 | base::TimeTicks timing_start = base::TimeTicks::Now(); |
Aldo Culquicondor | cc004c7 | 2018-08-02 14:50:02 | [diff] [blame] | 293 | |
Klaus Weidner | d3e9434 | 2019-05-30 04:21:53 | [diff] [blame] | 294 | input_delegate_->UpdateController(head_pose, current_time, true); |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 295 | auto input_event_list = input_delegate_->GetGestures(current_time); |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 296 | ui_->HandleMenuButtonEvents(&input_event_list); |
| 297 | |
| 298 | ui_controller_update_time_.AddSample(base::TimeTicks::Now() - timing_start); |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 299 | |
| 300 | scheduler_delegate_->AddInputSourceState( |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 301 | input_delegate_->GetInputSourceState()); |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 302 | } |
| 303 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 304 | void BrowserRenderer::ConnectPresentingService( |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 305 | device::mojom::VRDisplayInfoPtr display_info, |
| 306 | device::mojom::XRRuntimeSessionOptionsPtr options) { |
Aldo Culquicondor | b8985eb | 2018-09-06 22:27:44 | [diff] [blame] | 307 | scheduler_delegate_->ConnectPresentingService(std::move(display_info), |
| 308 | std::move(options)); |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 309 | } |
| 310 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 311 | base::TimeDelta BrowserRenderer::ProcessControllerInput( |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 312 | const RenderInfo& render_info, |
| 313 | base::TimeTicks current_time) { |
Aldo Culquicondor | bede7f32 | 2018-09-12 21:21:06 | [diff] [blame] | 314 | TRACE_EVENT0("gpu", "Vr.ProcessControllerInput"); |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 315 | DCHECK(input_delegate_); |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 316 | DCHECK(ui_); |
| 317 | base::TimeTicks timing_start = base::TimeTicks::Now(); |
| 318 | |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 319 | input_delegate_->UpdateController(render_info.head_pose, current_time, false); |
| 320 | auto input_event_list = input_delegate_->GetGestures(current_time); |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 321 | ReticleModel reticle_model; |
| 322 | ControllerModel controller_model = |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 323 | input_delegate_->GetControllerModel(render_info.head_pose); |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 324 | ui_->HandleInput(current_time, render_info, controller_model, &reticle_model, |
| 325 | &input_event_list); |
Brandon Jones | 6e4b5ec | 2018-11-30 20:57:37 | [diff] [blame] | 326 | std::vector<ControllerModel> controller_models; |
| 327 | controller_models.push_back(controller_model); |
| 328 | ui_->OnControllersUpdated(controller_models, reticle_model); |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 329 | |
| 330 | auto controller_time = base::TimeTicks::Now() - timing_start; |
| 331 | ui_controller_update_time_.AddSample(controller_time); |
| 332 | return controller_time; |
| 333 | } |
| 334 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 335 | void BrowserRenderer::PerformControllerActionForTesting( |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 336 | ControllerTestInput controller_input) { |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 337 | DCHECK(input_delegate_); |
bsheedy | fa3e442 | 2018-09-18 21:39:31 | [diff] [blame] | 338 | if (controller_input.action == VrControllerTestAction::kRevertToRealInput) { |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 339 | if (using_input_delegate_for_testing_) { |
| 340 | DCHECK(static_cast<InputDelegateForTesting*>(input_delegate_.get()) |
| 341 | ->IsQueueEmpty()) |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 342 | << "Attempted to revert to using real controller with actions still " |
| 343 | "queued"; |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 344 | using_input_delegate_for_testing_ = false; |
| 345 | input_delegate_for_testing_.swap(input_delegate_); |
bsheedy | b3cc34d8 | 2018-11-15 22:20:40 | [diff] [blame] | 346 | ui_->SetUiInputManagerForTesting(false); |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 347 | } |
| 348 | return; |
| 349 | } |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 350 | if (!using_input_delegate_for_testing_) { |
| 351 | using_input_delegate_for_testing_ = true; |
| 352 | if (!input_delegate_for_testing_) |
| 353 | input_delegate_for_testing_ = |
| 354 | std::make_unique<InputDelegateForTesting>(ui_.get()); |
| 355 | input_delegate_for_testing_.swap(input_delegate_); |
bsheedy | b3cc34d8 | 2018-11-15 22:20:40 | [diff] [blame] | 356 | ui_->SetUiInputManagerForTesting(true); |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 357 | } |
bsheedy | fa3e442 | 2018-09-18 21:39:31 | [diff] [blame] | 358 | if (controller_input.action != VrControllerTestAction::kEnableMockedInput) { |
Aldo Culquicondor | b915d1ef | 2018-09-11 23:10:35 | [diff] [blame] | 359 | static_cast<InputDelegateForTesting*>(input_delegate_.get()) |
Aldo Culquicondor | 880ba3d | 2018-08-08 19:35:14 | [diff] [blame] | 360 | ->QueueControllerActionForTesting(controller_input); |
| 361 | } |
| 362 | } |
| 363 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 364 | void BrowserRenderer::ReportUiStatusForTesting( |
| 365 | const base::TimeTicks& current_time, |
| 366 | bool ui_updated) { |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 367 | if (ui_test_state_ == nullptr) |
| 368 | return; |
| 369 | base::TimeDelta time_since_start = current_time - ui_test_state_->start_time; |
| 370 | if (ui_updated) { |
| 371 | ui_test_state_->activity_started = true; |
| 372 | if (time_since_start > ui_test_state_->quiescence_timeout_ms) { |
| 373 | // The UI is being updated, but hasn't reached a stable state in the |
| 374 | // given time -> report timeout. |
bsheedy | a2ff343 | 2018-10-02 18:16:58 | [diff] [blame] | 375 | ReportUiActivityResultForTesting(UiTestOperationResult::kTimeoutNoEnd); |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 376 | } |
| 377 | } else { |
| 378 | if (ui_test_state_->activity_started) { |
| 379 | // The UI has been updated since the test requested notification of |
| 380 | // quiescence, but wasn't this frame -> report that the UI is quiescent. |
bsheedy | a2ff343 | 2018-10-02 18:16:58 | [diff] [blame] | 381 | ReportUiActivityResultForTesting(UiTestOperationResult::kQuiescent); |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 382 | } else if (time_since_start > ui_test_state_->quiescence_timeout_ms) { |
| 383 | // The UI has never been updated and we've reached the timeout. |
bsheedy | a2ff343 | 2018-10-02 18:16:58 | [diff] [blame] | 384 | ReportUiActivityResultForTesting(UiTestOperationResult::kTimeoutNoStart); |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 385 | } |
| 386 | } |
| 387 | } |
| 388 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 389 | base::WeakPtr<BrowserRenderer> BrowserRenderer::GetWeakPtr() { |
Aldo Culquicondor | 764626c | 2018-08-23 20:14:47 | [diff] [blame] | 390 | return weak_ptr_factory_.GetWeakPtr(); |
| 391 | } |
| 392 | |
Aldo Culquicondor | 34610c1d | 2018-09-07 21:03:13 | [diff] [blame] | 393 | void BrowserRenderer::ReportUiActivityResultForTesting( |
bsheedy | a2ff343 | 2018-10-02 18:16:58 | [diff] [blame] | 394 | UiTestOperationResult result) { |
Aldo Culquicondor | 4153241 | 2018-08-07 22:36:44 | [diff] [blame] | 395 | ui_test_state_ = nullptr; |
bsheedy | fa3e442 | 2018-09-18 21:39:31 | [diff] [blame] | 396 | browser_->ReportUiOperationResultForTesting( |
| 397 | UiTestOperationType::kUiActivityResult, result); |
| 398 | } |
| 399 | |
| 400 | void BrowserRenderer::ReportFrameBufferDumpForTesting() { |
| 401 | if (frame_buffer_dump_filepath_base_.empty()) |
| 402 | return; |
| 403 | |
| 404 | frame_buffer_dump_filepath_base_.clear(); |
| 405 | browser_->ReportUiOperationResultForTesting( |
| 406 | UiTestOperationType::kFrameBufferDumped, |
bsheedy | a2ff343 | 2018-10-02 18:16:58 | [diff] [blame] | 407 | UiTestOperationResult::kQuiescent /* unused */); |
| 408 | } |
| 409 | |
| 410 | void BrowserRenderer::ReportElementVisibilityStatusForTesting( |
| 411 | const base::TimeTicks& current_time) { |
| 412 | if (ui_visibility_state_ == nullptr) |
| 413 | return; |
| 414 | base::TimeDelta time_since_start = |
| 415 | current_time - ui_visibility_state_->start_time; |
| 416 | if (ui_->GetElementVisibilityForTesting( |
bsheedy | dc7c6cb | 2018-11-05 20:48:45 | [diff] [blame] | 417 | ui_visibility_state_->element_to_watch) == |
| 418 | ui_visibility_state_->expected_visibile) { |
bsheedy | a2ff343 | 2018-10-02 18:16:58 | [diff] [blame] | 419 | ReportElementVisibilityResultForTesting( |
bsheedy | dc7c6cb | 2018-11-05 20:48:45 | [diff] [blame] | 420 | UiTestOperationResult::kVisibilityMatch); |
bsheedy | a2ff343 | 2018-10-02 18:16:58 | [diff] [blame] | 421 | } else if (time_since_start > ui_visibility_state_->timeout_ms) { |
| 422 | ReportElementVisibilityResultForTesting( |
bsheedy | dc7c6cb | 2018-11-05 20:48:45 | [diff] [blame] | 423 | UiTestOperationResult::kTimeoutNoVisibilityMatch); |
bsheedy | a2ff343 | 2018-10-02 18:16:58 | [diff] [blame] | 424 | } |
| 425 | } |
| 426 | |
| 427 | void BrowserRenderer::ReportElementVisibilityResultForTesting( |
| 428 | UiTestOperationResult result) { |
| 429 | ui_visibility_state_ = nullptr; |
| 430 | browser_->ReportUiOperationResultForTesting( |
bsheedy | dc7c6cb | 2018-11-05 20:48:45 | [diff] [blame] | 431 | UiTestOperationType::kElementVisibilityStatus, result); |
Aldo Culquicondor | cc004c7 | 2018-08-02 14:50:02 | [diff] [blame] | 432 | } |
| 433 | |
| 434 | } // namespace vr |