diff --git a/DEPS b/DEPS index 720f9edc..7bd4eca 100644 --- a/DEPS +++ b/DEPS
@@ -63,7 +63,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '51e240033771b0e8f504d3eb401c781d5908fe39', + 'v8_revision': 'ea01f412c74e35d547b39bedebf5d0338fb060e4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -83,7 +83,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '994f20cfb76f4902491a94c4ef61f55705fc124d', + 'pdfium_revision': '3fff90a670d860a7b0319aa0edf8628917d0a122', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other.
diff --git a/chrome/browser/android/vr_shell/vr_controller.cc b/chrome/browser/android/vr_shell/vr_controller.cc index 3a6fc86..ac340626 100644 --- a/chrome/browser/android/vr_shell/vr_controller.cc +++ b/chrome/browser/android/vr_shell/vr_controller.cc
@@ -196,16 +196,6 @@ gfx::ScaleVector3d(pointer_direction, kLaserStartDisplacement); } -vr::VrControllerModel::State VrController::GetModelState() const { - if (ButtonState(gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) - return vr::VrControllerModel::TOUCHPAD; - if (ButtonState(gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) - return vr::VrControllerModel::APP; - if (ButtonState(gvr::ControllerButton::GVR_CONTROLLER_BUTTON_HOME)) - return vr::VrControllerModel::SYSTEM; - return vr::VrControllerModel::IDLE; -} - bool VrController::TouchDownHappened() { return controller_state_->GetTouchDown(); }
diff --git a/chrome/browser/android/vr_shell/vr_controller.h b/chrome/browser/android/vr_shell/vr_controller.h index a499ad6..fb833f3 100644 --- a/chrome/browser/android/vr_shell/vr_controller.h +++ b/chrome/browser/android/vr_shell/vr_controller.h
@@ -10,7 +10,7 @@ #include "base/macros.h" #include "base/time/time.h" -#include "chrome/browser/vr/vr_controller_model.h" +#include "chrome/browser/vr/controller_mesh.h" #include "device/vr/android/gvr/gvr_gamepad_data_provider.h" #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h" #include "ui/gfx/geometry/point3_f.h" @@ -68,8 +68,6 @@ float GetOpacity() const; gfx::Point3F GetPointerStart() const; - vr::VrControllerModel::State GetModelState() const; - bool TouchDownHappened(); bool TouchUpHappened();
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc index 2813fefcf..b26d054 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.cc +++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/android/vr_shell/vr_usage_monitor.h" #include "chrome/browser/vr/elements/ui_element.h" #include "chrome/browser/vr/fps_meter.h" +#include "chrome/browser/vr/model/model.h" #include "chrome/browser/vr/ui.h" #include "chrome/browser/vr/ui_interface.h" #include "chrome/browser/vr/ui_scene.h" @@ -169,14 +170,14 @@ rect.top - rect.bottom); } -void LoadControllerModelTask( +void LoadControllerMeshTask( base::WeakPtr<VrShellGl> weak_vr_shell_gl, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { - auto controller_model = vr::VrControllerModel::LoadFromResources(); - if (controller_model) { + auto controller_mesh = vr::ControllerMesh::LoadFromResources(); + if (controller_mesh) { task_runner->PostTask( - FROM_HERE, base::Bind(&VrShellGl::SetControllerModel, weak_vr_shell_gl, - base::Passed(&controller_model))); + FROM_HERE, base::Bind(&VrShellGl::SetControllerMesh, weak_vr_shell_gl, + base::Passed(&controller_mesh))); } } @@ -279,7 +280,7 @@ if (daydream_support_ && !reinitializing) { base::PostTaskWithTraits( FROM_HERE, {base::TaskPriority::BACKGROUND}, - base::Bind(LoadControllerModelTask, weak_ptr_factory_.GetWeakPtr(), + base::Bind(LoadControllerMeshTask, weak_ptr_factory_.GetWeakPtr(), task_runner_)); } @@ -544,17 +545,18 @@ gvr::Mat4f gvr_head_pose; TransformToGvrMat(head_pose, &gvr_head_pose); controller_->UpdateState(gvr_head_pose); - controller_info_.laser_origin = controller_->GetPointerStart(); + gfx::Point3F laser_origin = controller_->GetPointerStart(); device::GvrGamepadData controller_data = controller_->GetGamepadData(); if (!ShouldDrawWebVr()) controller_data.connected = false; browser_->UpdateGamepadData(controller_data); - HandleControllerInput(GetForwardVector(head_pose)); + HandleControllerInput(laser_origin, GetForwardVector(head_pose)); } -void VrShellGl::HandleControllerInput(const gfx::Vector3dF& head_direction) { +void VrShellGl::HandleControllerInput(const gfx::Point3F& laser_origin, + const gfx::Vector3dF& head_direction) { if (is_exiting_) { // When we're exiting, we don't show the reticle and the only input // processing we do is to handle immediate exits. @@ -583,30 +585,34 @@ if (ShouldDrawWebVr()) return; - controller_->GetTransform(&controller_info_.transform); + vr::ControllerModel controller_model; + controller_->GetTransform(&controller_model.transform); std::unique_ptr<GestureList> gesture_list_ptr = controller_->DetectGestures(); GestureList& gesture_list = *gesture_list_ptr; - controller_info_.touchpad_button_state = vr::UiInputManager::ButtonState::UP; + controller_model.touchpad_button_state = vr::UiInputManager::ButtonState::UP; DCHECK(!(controller_->ButtonUpHappened(gvr::kControllerButtonClick) && controller_->ButtonDownHappened(gvr::kControllerButtonClick))) << "Cannot handle a button down and up event within one frame."; if (controller_->ButtonState(gvr::kControllerButtonClick)) { - controller_info_.touchpad_button_state = + controller_model.touchpad_button_state = vr::UiInputManager::ButtonState::DOWN; } - controller_info_.app_button_state = + controller_model.app_button_state = controller_->ButtonState(gvr::kControllerButtonApp) ? vr::UiInputManager::ButtonState::DOWN : vr::UiInputManager::ButtonState::UP; - controller_info_.home_button_state = + controller_model.home_button_state = controller_->ButtonState(gvr::kControllerButtonHome) ? vr::UiInputManager::ButtonState::DOWN : vr::UiInputManager::ButtonState::UP; - controller_info_.opacity = controller_->GetOpacity(); - ui_->input_manager()->HandleInput( - controller_direction, controller_info_.laser_origin, - controller_info_.touchpad_button_state, &gesture_list, - &controller_info_.target_point, &controller_info_.reticle_render_target); + controller_model.opacity = controller_->GetOpacity(); + controller_model.laser_direction = controller_direction; + controller_model.laser_origin = laser_origin; + + vr::ReticleModel reticle_model; + ui_->input_manager()->HandleInput(controller_model, &reticle_model, + &gesture_list); + ui_->OnControllerUpdated(controller_model, reticle_model); } std::unique_ptr<blink::WebMouseEvent> VrShellGl::MakeMouseEvent( @@ -1006,7 +1012,7 @@ // At this point, we draw non-WebVR content that could, potentially, fill the // viewport. NB: this is not just 2d browsing stuff, we may have a splash // screen showing in WebVR mode that must also fill the screen. - ui_->ui_renderer()->Draw(render_info_primary_, controller_info_); + ui_->ui_renderer()->Draw(render_info_primary_); content_frame_available_ = false; acquired_frame_.Unbind(); @@ -1064,8 +1070,8 @@ kViewportListWebVrBrowserUiOffset, render_size_webvr_ui_, &render_info_webvr_browser_ui); - ui_->ui_renderer()->DrawWebVrOverlayForeground(render_info_webvr_browser_ui, - controller_info_); + ui_->ui_renderer()->DrawWebVrOverlayForeground( + render_info_webvr_browser_ui); acquired_frame_.Unbind(); } @@ -1231,9 +1237,8 @@ return ui_->GetBrowserUiWeakPtr(); } -void VrShellGl::SetControllerModel( - std::unique_ptr<vr::VrControllerModel> model) { - ui_->vr_shell_renderer()->GetControllerRenderer()->SetUp(std::move(model)); +void VrShellGl::SetControllerMesh(std::unique_ptr<vr::ControllerMesh> mesh) { + ui_->vr_shell_renderer()->GetControllerRenderer()->SetUp(std::move(mesh)); } void VrShellGl::OnVSync(base::TimeTicks frame_time) {
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.h b/chrome/browser/android/vr_shell/vr_shell_gl.h index 2f4a7ba..d6c601c 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.h +++ b/chrome/browser/android/vr_shell/vr_shell_gl.h
@@ -18,9 +18,9 @@ #include "chrome/browser/android/vr_shell/android_vsync_helper.h" #include "chrome/browser/android/vr_shell/vr_controller.h" #include "chrome/browser/vr/content_input_delegate.h" +#include "chrome/browser/vr/controller_mesh.h" #include "chrome/browser/vr/ui_input_manager.h" #include "chrome/browser/vr/ui_renderer.h" -#include "chrome/browser/vr/vr_controller_model.h" #include "device/vr/vr_service.mojom.h" #include "mojo/public/cpp/bindings/binding.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" @@ -108,7 +108,7 @@ void UIPhysicalBoundsChanged(int width, int height); base::WeakPtr<VrShellGl> GetWeakPtr(); - void SetControllerModel(std::unique_ptr<vr::VrControllerModel> model); + void SetControllerMesh(std::unique_ptr<vr::ControllerMesh> mesh); void ConnectPresentingService( device::mojom::VRSubmitFrameClientPtrInfo submit_client_info, @@ -165,7 +165,8 @@ const gfx::PointF& normalized_hit_point) override; void SendImmediateExitRequestIfNecessary(); - void HandleControllerInput(const gfx::Vector3dF& head_direction); + void HandleControllerInput(const gfx::Point3F& laser_origin, + const gfx::Vector3dF& head_direction); void HandleControllerAppButtonActivity( const gfx::Vector3dF& controller_direction); void SendGestureToContent(std::unique_ptr<blink::WebInputEvent> event); @@ -280,7 +281,6 @@ gfx::Point3F pointer_start_; - vr::ControllerInfo controller_info_; vr::RenderInfo render_info_primary_; AndroidVSyncHelper vsync_helper_;
diff --git a/chrome/browser/browser_encoding_browsertest.cc b/chrome/browser/browser_encoding_browsertest.cc index 9f39368..5a9d9511 100644 --- a/chrome/browser/browser_encoding_browsertest.cc +++ b/chrome/browser/browser_encoding_browsertest.cc
@@ -4,21 +4,21 @@ #include <stddef.h> -#include "base/bind.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" +#include "base/path_service.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" -#include "chrome/browser/net/url_request_mock_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/prefs/pref_service.h" -#include "content/public/browser/browser_thread.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/notification_service.h" @@ -27,7 +27,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/test/download_test_observer.h" #include "content/public/test/test_navigation_observer.h" -#include "net/test/url_request/url_request_mock_http_job.h" +#include "net/test/embedded_test_server/embedded_test_server.h" namespace { @@ -71,8 +71,6 @@ } // namespace -using content::BrowserThread; - static const base::FilePath::CharType* kTestDir = FILE_PATH_LITERAL("encoding_tests"); @@ -85,7 +83,8 @@ // Saves the current page and verifies that the output matches the expected // result. void SaveAndCompare(const char* filename_to_write, - const base::FilePath& expected) { + const base::FilePath& expected, + const GURL& url) { // Dump the page, the content of dump page should be identical to the // expected result file. base::FilePath full_file_name = save_dir_.AppendASCII(filename_to_write); @@ -105,19 +104,32 @@ base::FilePath expected_file_name = ui_test_utils::GetTestFilePath( base::FilePath(kTestDir), expected); - EXPECT_TRUE(base::ContentsEqual(full_file_name, expected_file_name)) << - "generated_file = " << full_file_name.AsUTF8Unsafe() << - ", expected_file = " << expected_file_name.AsUTF8Unsafe(); + std::string actual_contents; + std::string expected_contents; + + { + base::ScopedAllowBlockingForTesting allow_blocking; + ASSERT_TRUE(base::ReadFileToString(full_file_name, &actual_contents)); + ASSERT_TRUE( + base::ReadFileToString(expected_file_name, &expected_contents)); + } + + // Add "Mark of the Web" path with source URL. + expected_contents = base::StringPrintf( + expected_contents.c_str(), url.spec().length(), url.spec().c_str()); + + EXPECT_EQ(expected_contents, actual_contents); } void SetUpOnMainThread() override { + base::FilePath test_data_dir; + ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); + embedded_test_server()->ServeFilesFromDirectory(test_data_dir); + ASSERT_TRUE(embedded_test_server()->Start()); + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); save_dir_ = temp_dir_.GetPath(); temp_sub_resource_dir_ = save_dir_.AppendASCII("sub_resource_files"); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); } base::ScopedTempDir temp_dir_; @@ -140,7 +152,7 @@ GetParam().file_name); GURL url = - net::URLRequestMockHTTPJob::GetMockUrl(test_file_path.MaybeAsASCII()); + embedded_test_server()->GetURL("/" + test_file_path.MaybeAsASCII()); ui_test_utils::NavigateToURL(browser(), url); EXPECT_EQ(GetParam().encoding_name, browser()->tab_strip_model()->GetActiveWebContents()-> @@ -232,7 +244,7 @@ base::FilePath test_file_path(test_dir_path); test_file_path = test_file_path.AppendASCII(kTestDatas[i].test_file_name); GURL url = - net::URLRequestMockHTTPJob::GetMockUrl(test_file_path.MaybeAsASCII()); + embedded_test_server()->GetURL("/" + test_file_path.MaybeAsASCII()); ui_test_utils::NavigateToURL(browser(), url); // Get the encoding of page. It should return the real encoding now. @@ -244,6 +256,7 @@ base::FilePath().AppendASCII(kAutoDetectDir). AppendASCII(kExpectedResultDir). AppendASCII(kTestDatas[i].expected_result); - SaveAndCompare(kTestDatas[i].test_file_name, expected_result_file_name); + SaveAndCompare(kTestDatas[i].test_file_name, expected_result_file_name, + url); } }
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn index e51b53e..c29c525 100644 --- a/chrome/browser/vr/BUILD.gn +++ b/chrome/browser/vr/BUILD.gn
@@ -20,6 +20,8 @@ "browser_ui_interface.h", "color_scheme.cc", "color_scheme.h", + "controller_mesh.cc", + "controller_mesh.h", "databinding/binding.h", "databinding/binding_base.cc", "databinding/binding_base.h", @@ -31,6 +33,8 @@ "elements/button_texture.h", "elements/content_element.cc", "elements/content_element.h", + "elements/controller.cc", + "elements/controller.h", "elements/draw_phase.h", "elements/exclusive_screen_toast.cc", "elements/exclusive_screen_toast.h", @@ -50,12 +54,16 @@ "elements/grid.h", "elements/invisible_hit_target.cc", "elements/invisible_hit_target.h", + "elements/laser.cc", + "elements/laser.h", "elements/linear_layout.cc", "elements/linear_layout.h", "elements/rect.cc", "elements/rect.h", "elements/render_text_wrapper.cc", "elements/render_text_wrapper.h", + "elements/reticle.cc", + "elements/reticle.h", "elements/simple_textured_element.h", "elements/spinner.cc", "elements/spinner.h", @@ -74,6 +82,7 @@ "elements/ui_element.cc", "elements/ui_element.h", "elements/ui_element_iterator.h", + "elements/ui_element_name.cc", "elements/ui_element_name.h", "elements/ui_element_transform_operations.cc", "elements/ui_element_transform_operations.h", @@ -102,10 +111,13 @@ "gltf_asset.h", "gltf_parser.cc", "gltf_parser.h", + "model/controller_model.h", "model/model.cc", "model/model.h", "model/omnibox_suggestions.cc", "model/omnibox_suggestions.h", + "model/reticle_model.h", + "model/web_vr_timeout_state.h", "service/vr_device_manager.cc", "service/vr_device_manager.h", "service/vr_display_host.cc", @@ -136,8 +148,6 @@ "ui_scene_manager.cc", "ui_scene_manager.h", "ui_unsupported_mode.h", - "vr_controller_model.cc", - "vr_controller_model.h", "vr_gl_util.cc", "vr_gl_util.h", "vr_shell_renderer.cc", @@ -146,12 +156,15 @@ "web_contents_event_forwarder.h", ] + public_deps = [ + "//chrome/browser/resources:vr_shell_resources", + ] + deps = [ "//base", "//cc/animation", "//cc/paint", "//chrome/app:generated_resources", - "//chrome/browser/resources:vr_shell_resources", "//chrome/browser/vr/vector_icons", "//chrome/common:constants", "//components/omnibox/browser", @@ -179,6 +192,7 @@ "databinding/vector_binding_unittest.cc", "elements/exit_prompt_unittest.cc", "elements/linear_layout_unittest.cc", + "elements/rect_unittest.cc", "elements/spinner_unittest.cc", "elements/throbber_unittest.cc", "elements/transient_element_unittest.cc",
diff --git a/chrome/browser/vr/vr_controller_model.cc b/chrome/browser/vr/controller_mesh.cc similarity index 76% rename from chrome/browser/vr/vr_controller_model.cc rename to chrome/browser/vr/controller_mesh.cc index cd3845f..e0c4e75d 100644 --- a/chrome/browser/vr/vr_controller_model.cc +++ b/chrome/browser/vr/controller_mesh.cc
@@ -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/vr_controller_model.h" +#include "chrome/browser/vr/controller_mesh.h" #include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" @@ -11,6 +11,7 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/core/SkSwizzle.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/codec/png_codec.h" @@ -35,25 +36,31 @@ sk_sp<SkImage> LoadPng(int resource_id) { base::StringPiece data = ui::ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id); + SkBitmap bitmap; bool decoded = gfx::PNGCodec::Decode(reinterpret_cast<const unsigned char*>(data.data()), data.size(), &bitmap); DCHECK(decoded); - DCHECK(bitmap.colorType() == kRGBA_8888_SkColorType); + if (bitmap.colorType() == kBGRA_8888_SkColorType) { + SkSwapRB(bitmap.getAddr32(0, 0), bitmap.getAddr32(0, 0), + bitmap.width() * bitmap.height()); + } else { + DCHECK(bitmap.colorType() == kRGBA_8888_SkColorType); + } return SkImage::MakeFromBitmap(bitmap); } } // namespace -VrControllerModel::VrControllerModel( +ControllerMesh::ControllerMesh( std::unique_ptr<vr::gltf::Asset> gltf_asset, std::vector<std::unique_ptr<vr::gltf::Buffer>> buffers) : gltf_asset_(std::move(gltf_asset)), buffers_(std::move(buffers)) {} -VrControllerModel::~VrControllerModel() = default; +ControllerMesh::~ControllerMesh() = default; -const GLvoid* VrControllerModel::ElementsBuffer() const { +const GLvoid* ControllerMesh::ElementsBuffer() const { const vr::gltf::BufferView* buffer_view = gltf_asset_->GetBufferView(ELEMENTS_BUFFER_ID); DCHECK(buffer_view && buffer_view->target == GL_ARRAY_BUFFER); @@ -61,14 +68,14 @@ return buffer ? buffer + buffer_view->byte_offset : nullptr; } -GLsizeiptr VrControllerModel::ElementsBufferSize() const { +GLsizeiptr ControllerMesh::ElementsBufferSize() const { const vr::gltf::BufferView* buffer_view = gltf_asset_->GetBufferView(ELEMENTS_BUFFER_ID); DCHECK(buffer_view && buffer_view->target == GL_ARRAY_BUFFER); return buffer_view->byte_length; } -const GLvoid* VrControllerModel::IndicesBuffer() const { +const GLvoid* ControllerMesh::IndicesBuffer() const { const vr::gltf::BufferView* buffer_view = gltf_asset_->GetBufferView(INDICES_BUFFER_ID); DCHECK(buffer_view && buffer_view->target == GL_ELEMENT_ARRAY_BUFFER); @@ -76,38 +83,38 @@ return buffer ? buffer + buffer_view->byte_offset : nullptr; } -GLsizeiptr VrControllerModel::IndicesBufferSize() const { +GLsizeiptr ControllerMesh::IndicesBufferSize() const { const vr::gltf::BufferView* buffer_view = gltf_asset_->GetBufferView(INDICES_BUFFER_ID); DCHECK(buffer_view && buffer_view->target == GL_ELEMENT_ARRAY_BUFFER); return buffer_view->byte_length; } -GLenum VrControllerModel::DrawMode() const { +GLenum ControllerMesh::DrawMode() const { const vr::gltf::Mesh* mesh = gltf_asset_->GetMesh(0); DCHECK(mesh && mesh->primitives.size()); return mesh->primitives[0]->mode; } -const vr::gltf::Accessor* VrControllerModel::IndicesAccessor() const { +const vr::gltf::Accessor* ControllerMesh::IndicesAccessor() const { const vr::gltf::Mesh* mesh = gltf_asset_->GetMesh(0); DCHECK(mesh && mesh->primitives.size()); return mesh->primitives[0]->indices; } -const vr::gltf::Accessor* VrControllerModel::PositionAccessor() const { +const vr::gltf::Accessor* ControllerMesh::PositionAccessor() const { return Accessor(kPosition); } -const vr::gltf::Accessor* VrControllerModel::TextureCoordinateAccessor() const { +const vr::gltf::Accessor* ControllerMesh::TextureCoordinateAccessor() const { return Accessor(kTexCoord); } -void VrControllerModel::SetBaseTexture(sk_sp<SkImage> image) { +void ControllerMesh::SetBaseTexture(sk_sp<SkImage> image) { base_texture_ = image; } -void VrControllerModel::SetTexture(int state, sk_sp<SkImage> patch) { +void ControllerMesh::SetTexture(int state, sk_sp<SkImage> patch) { DCHECK(state >= 0 && state < STATE_COUNT); if (!patch) { textures_[state] = base_texture_; @@ -124,18 +131,18 @@ textures_[state] = sk_sp<SkImage>(surface->makeImageSnapshot()); } -sk_sp<SkImage> VrControllerModel::GetTexture(int state) const { +sk_sp<SkImage> ControllerMesh::GetTexture(int state) const { DCHECK(state >= 0 && state < STATE_COUNT); return textures_[state]; } -const char* VrControllerModel::Buffer() const { +const char* ControllerMesh::Buffer() const { if (buffers_.empty()) return nullptr; return buffers_[0]->data(); } -const vr::gltf::Accessor* VrControllerModel::Accessor( +const vr::gltf::Accessor* ControllerMesh::Accessor( const std::string& key) const { const vr::gltf::Mesh* mesh = gltf_asset_->GetMesh(0); DCHECK(mesh && mesh->primitives.size()); @@ -144,8 +151,8 @@ return it->second; } -std::unique_ptr<VrControllerModel> VrControllerModel::LoadFromResources() { - TRACE_EVENT0("gpu", "VrControllerModel::LoadFromResources"); +std::unique_ptr<ControllerMesh> ControllerMesh::LoadFromResources() { + TRACE_EVENT0("gpu", "ControllerMesh::LoadFromResources"); std::vector<std::unique_ptr<vr::gltf::Buffer>> buffers; auto model_data = ui::ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_VR_SHELL_DDCONTROLLER_MODEL); @@ -154,11 +161,11 @@ DCHECK(asset); auto controller_model = - base::MakeUnique<VrControllerModel>(std::move(asset), std::move(buffers)); + base::MakeUnique<ControllerMesh>(std::move(asset), std::move(buffers)); sk_sp<SkImage> base_texture = LoadPng(IDR_VR_SHELL_DDCONTROLLER_IDLE_TEXTURE); controller_model->SetBaseTexture(std::move(base_texture)); - for (int i = 0; i < VrControllerModel::STATE_COUNT; i++) { + for (int i = 0; i < ControllerMesh::STATE_COUNT; i++) { if (kTexturePatchesResources[i] == -1) { controller_model->SetTexture(i, nullptr); } else {
diff --git a/chrome/browser/vr/vr_controller_model.h b/chrome/browser/vr/controller_mesh.h similarity index 82% rename from chrome/browser/vr/vr_controller_model.h rename to chrome/browser/vr/controller_mesh.h index 04bedef..149c5a64 100644 --- a/chrome/browser/vr/vr_controller_model.h +++ b/chrome/browser/vr/controller_mesh.h
@@ -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_VR_CONTROLLER_MODEL_H_ -#define CHROME_BROWSER_VR_VR_CONTROLLER_MODEL_H_ +#ifndef CHROME_BROWSER_VR_CONTROLLER_MESH_H_ +#define CHROME_BROWSER_VR_CONTROLLER_MESH_H_ #include <memory> @@ -14,7 +14,7 @@ namespace vr { -class VrControllerModel { +class ControllerMesh { public: enum State { IDLE = 0, @@ -25,10 +25,10 @@ STATE_COUNT, }; - explicit VrControllerModel( + explicit ControllerMesh( std::unique_ptr<vr::gltf::Asset> gltf_asset, std::vector<std::unique_ptr<vr::gltf::Buffer>> buffers); - ~VrControllerModel(); + ~ControllerMesh(); const GLvoid* ElementsBuffer() const; GLsizeiptr ElementsBufferSize() const; @@ -42,7 +42,7 @@ void SetTexture(int state, sk_sp<SkImage> patch); sk_sp<SkImage> GetTexture(int state) const; - static std::unique_ptr<VrControllerModel> LoadFromResources(); + static std::unique_ptr<ControllerMesh> LoadFromResources(); private: std::unique_ptr<vr::gltf::Asset> gltf_asset_; @@ -56,4 +56,4 @@ } // namespace vr -#endif // CHROME_BROWSER_VR_VR_CONTROLLER_MODEL_H_ +#endif // CHROME_BROWSER_VR_CONTROLLER_MESH_H_
diff --git a/chrome/browser/vr/elements/content_element.h b/chrome/browser/vr/elements/content_element.h index 38bdbb87..a027b5c 100644 --- a/chrome/browser/vr/elements/content_element.h +++ b/chrome/browser/vr/elements/content_element.h
@@ -46,6 +46,8 @@ unsigned int texture_id_ = 0; UiElementRenderer::TextureLocation texture_location_ = UiElementRenderer::kTextureLocationExternal; + + DISALLOW_COPY_AND_ASSIGN(ContentElement); }; } // namespace vr
diff --git a/chrome/browser/vr/elements/controller.cc b/chrome/browser/vr/elements/controller.cc new file mode 100644 index 0000000..e18bbd0d --- /dev/null +++ b/chrome/browser/vr/elements/controller.cc
@@ -0,0 +1,40 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/vr/elements/controller.h" + +#include "chrome/browser/vr/controller_mesh.h" +#include "chrome/browser/vr/ui_element_renderer.h" + +namespace vr { + +Controller::Controller() { + set_name(kController); + set_hit_testable(false); + SetVisible(true); +} + +Controller::~Controller() = default; + +void Controller::Render(UiElementRenderer* renderer, + const gfx::Transform& model_view_proj_matrix) const { + ControllerMesh::State state; + if (touchpad_button_pressed_) { + state = ControllerMesh::TOUCHPAD; + } else if (app_button_pressed_) { + state = ControllerMesh::APP; + } else if (home_button_pressed_) { + state = ControllerMesh::SYSTEM; + } else { + state = ControllerMesh::IDLE; + } + + renderer->DrawController(state, computed_opacity(), model_view_proj_matrix); +} + +gfx::Transform Controller::LocalTransform() const { + return local_transform_; +} + +} // namespace vr
diff --git a/chrome/browser/vr/elements/controller.h b/chrome/browser/vr/elements/controller.h new file mode 100644 index 0000000..d867d81 --- /dev/null +++ b/chrome/browser/vr/elements/controller.h
@@ -0,0 +1,47 @@ +// Copyright 2017 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_ELEMENTS_CONTROLLER_H_ +#define CHROME_BROWSER_VR_ELEMENTS_CONTROLLER_H_ + +#include "base/macros.h" +#include "chrome/browser/vr/elements/ui_element.h" + +namespace vr { + +// This represents the controller. +class Controller : public UiElement { + public: + Controller(); + ~Controller() override; + + void set_touchpad_button_pressed(bool pressed) { + touchpad_button_pressed_ = pressed; + } + + void set_app_button_pressed(bool pressed) { app_button_pressed_ = pressed; } + + void set_home_button_pressed(bool pressed) { home_button_pressed_ = pressed; } + + void set_local_transform(const gfx::Transform& transform) { + local_transform_ = transform; + } + + private: + void Render(UiElementRenderer* renderer, + const gfx::Transform& model_view_proj_matrix) const final; + + gfx::Transform LocalTransform() const override; + + bool touchpad_button_pressed_ = false; + bool app_button_pressed_ = false; + bool home_button_pressed_ = false; + gfx::Transform local_transform_; + + DISALLOW_COPY_AND_ASSIGN(Controller); +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_ELEMENTS_CONTROLLER_H_
diff --git a/chrome/browser/vr/elements/laser.cc b/chrome/browser/vr/elements/laser.cc new file mode 100644 index 0000000..650bc7c --- /dev/null +++ b/chrome/browser/vr/elements/laser.cc
@@ -0,0 +1,67 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/vr/elements/laser.h" + +#include "base/numerics/math_constants.h" +#include "chrome/browser/vr/model/model.h" +#include "chrome/browser/vr/ui_element_renderer.h" +#include "chrome/browser/vr/ui_scene_constants.h" + +namespace vr { + +Laser::Laser(Model* model) : model_(model) { + set_name(kLaser); + set_hit_testable(false); + SetVisible(true); +} + +Laser::~Laser() = default; + +void Laser::Render(UiElementRenderer* renderer, + const gfx::Transform& model_view_proj_matrix) const { + // Find the length of the beam (from hand to target). + const float laser_length = + std::sqrt(model_->controller.laser_origin.SquaredDistanceTo( + ScalePoint(model_->reticle.target_point, kReticleOffset))); + + // Build a beam, originating from the origin. + gfx::Transform mat; + + // Move the beam half its height so that its end sits on the origin. + mat.matrix().postTranslate(0.0f, 0.5f, 0.0f); + mat.matrix().postScale(kLaserWidth, laser_length, 1); + + // Tip back 90 degrees to flat, pointing at the scene. + const gfx::Quaternion quat(gfx::Vector3dF(1.0f, 0.0f, 0.0f), + -base::kPiDouble / 2); + gfx::Transform rotation_mat(quat); + mat = rotation_mat * mat; + + const gfx::Vector3dF beam_direction = + model_->reticle.target_point - model_->controller.laser_origin; + + gfx::Transform beam_direction_mat( + gfx::Quaternion(gfx::Vector3dF(0.0f, 0.0f, -1.0f), beam_direction)); + + // Render multiple faces to make the laser appear cylindrical. + const int faces = 4; + gfx::Transform face_transform; + gfx::Transform transform; + for (int i = 0; i < faces; i++) { + // Rotate around Z. + const float angle = base::kPiFloat * 2 * i / faces; + const gfx::Quaternion rot({0.0f, 0.0f, 1.0f}, angle); + face_transform = beam_direction_mat * gfx::Transform(rot) * mat; + + // Move the beam origin to the hand. + face_transform.matrix().postTranslate(model_->controller.laser_origin.x(), + model_->controller.laser_origin.y(), + model_->controller.laser_origin.z()); + transform = model_view_proj_matrix * face_transform; + renderer->DrawLaser(computed_opacity(), transform); + } +} + +} // namespace vr
diff --git a/chrome/browser/vr/elements/laser.h b/chrome/browser/vr/elements/laser.h new file mode 100644 index 0000000..fbfbdea --- /dev/null +++ b/chrome/browser/vr/elements/laser.h
@@ -0,0 +1,36 @@ +// Copyright 2017 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_ELEMENTS_LASER_H_ +#define CHROME_BROWSER_VR_ELEMENTS_LASER_H_ + +#include "chrome/browser/vr/elements/ui_element.h" +#include "ui/gfx/geometry/point3_f.h" + +namespace vr { + +struct Model; + +class Laser : public UiElement { + public: + explicit Laser(Model* model); + ~Laser() override; + + private: + void Render(UiElementRenderer* renderer, + const gfx::Transform& model_view_proj_matrix) const final; + + // Since the laser needs to render in response to model changes that occur + // after the scene update (i.e., after input), we cannot rely on the usual + // data binding flow since that would result in a frame of latency. Opacity + // changes, however, are not latency sensitive and are bound in the usual way + // (they also do not update due to input). + Model* model_; + + DISALLOW_COPY_AND_ASSIGN(Laser); +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_ELEMENTS_LASER_H_
diff --git a/chrome/browser/vr/elements/rect.cc b/chrome/browser/vr/elements/rect.cc index 3199c254..1c4ad40c 100644 --- a/chrome/browser/vr/elements/rect.cc +++ b/chrome/browser/vr/elements/rect.cc
@@ -25,7 +25,7 @@ void Rect::SetEdgeColor(SkColor color) { animation_player().TransitionColorTo(last_frame_time(), FOREGROUND_COLOR, - center_color_, color); + edge_color_, color); } void Rect::NotifyClientColorAnimated(SkColor color,
diff --git a/chrome/browser/vr/elements/rect_unittest.cc b/chrome/browser/vr/elements/rect_unittest.cc new file mode 100644 index 0000000..6eb5969 --- /dev/null +++ b/chrome/browser/vr/elements/rect_unittest.cc
@@ -0,0 +1,55 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/vr/elements/rect.h" + +#include "base/memory/ptr_util.h" +#include "chrome/browser/vr/target_property.h" +#include "chrome/browser/vr/test/animation_utils.h" +#include "chrome/browser/vr/test/constants.h" +#include "chrome/browser/vr/ui_scene.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkColor.h" + +namespace vr { + +TEST(Rect, SetColorCorrectly) { + auto rect = base::MakeUnique<Rect>(); + + EXPECT_NE(SK_ColorCYAN, rect->edge_color()); + EXPECT_NE(SK_ColorCYAN, rect->center_color()); + + rect->SetColor(SK_ColorCYAN); + EXPECT_EQ(SK_ColorCYAN, rect->edge_color()); + EXPECT_EQ(SK_ColorCYAN, rect->center_color()); + + rect->SetEdgeColor(SK_ColorRED); + rect->SetCenterColor(SK_ColorBLUE); + + EXPECT_EQ(SK_ColorRED, rect->edge_color()); + EXPECT_EQ(SK_ColorBLUE, rect->center_color()); +} + +TEST(Rect, AnimateColorCorrectly) { + UiScene scene; + auto element = base::MakeUnique<Rect>(); + Rect* rect = element.get(); + scene.AddUiElement(kRoot, std::move(element)); + + rect->SetEdgeColor(SK_ColorRED); + rect->SetCenterColor(SK_ColorBLUE); + + rect->SetTransitionedProperties({BACKGROUND_COLOR, FOREGROUND_COLOR}); + rect->SetColor(SK_ColorBLACK); + + scene.OnBeginFrame(MsToTicks(1), kForwardVector); + EXPECT_EQ(SK_ColorRED, rect->edge_color()); + EXPECT_EQ(SK_ColorBLUE, rect->center_color()); + + scene.OnBeginFrame(MsToTicks(5000), kForwardVector); + EXPECT_EQ(SK_ColorBLACK, rect->edge_color()); + EXPECT_EQ(SK_ColorBLACK, rect->center_color()); +} + +} // namespace vr
diff --git a/chrome/browser/vr/elements/reticle.cc b/chrome/browser/vr/elements/reticle.cc new file mode 100644 index 0000000..f682d6c --- /dev/null +++ b/chrome/browser/vr/elements/reticle.cc
@@ -0,0 +1,59 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/vr/elements/reticle.h" + +#include "base/numerics/math_constants.h" +#include "chrome/browser/vr/model/model.h" +#include "chrome/browser/vr/ui_element_renderer.h" +#include "chrome/browser/vr/ui_scene.h" +#include "chrome/browser/vr/ui_scene_constants.h" + +namespace vr { + +Reticle::Reticle(UiScene* scene, Model* model) : scene_(scene), model_(model) { + set_name(kReticle); + set_hit_testable(false); + SetVisible(true); +} + +Reticle::~Reticle() = default; + +void Reticle::Render(UiElementRenderer* renderer, + const gfx::Transform& model_view_proj_matrix) const { + // Scale the reticle to have a fixed FOV size at any distance. + const float eye_to_target = + std::sqrt(model_->reticle.target_point.SquaredDistanceTo(kOrigin)); + + gfx::Transform mat; + mat.Scale3d(kReticleWidth * eye_to_target, kReticleHeight * eye_to_target, 1); + + gfx::Quaternion rotation; + + UiElement* target = + scene_->GetUiElementById(model_->reticle.target_element_id); + + if (target) { + // Make the reticle planar to the element it's hitting. + rotation = gfx::Quaternion(gfx::Vector3dF(0.0f, 0.0f, -1.0f), + -target->GetNormal()); + } else { + // Rotate the reticle to directly face the eyes. + rotation = gfx::Quaternion(gfx::Vector3dF(0.0f, 0.0f, -1.0f), + model_->reticle.target_point - kOrigin); + } + gfx::Transform rotation_mat(rotation); + mat = rotation_mat * mat; + + gfx::Point3F target_point = + ScalePoint(model_->reticle.target_point, kReticleOffset); + // Place the pointer slightly in front of the plane intersection point. + mat.matrix().postTranslate(target_point.x(), target_point.y(), + target_point.z()); + + gfx::Transform transform = model_view_proj_matrix * mat; + renderer->DrawReticle(computed_opacity(), transform); +} + +} // namespace vr
diff --git a/chrome/browser/vr/elements/reticle.h b/chrome/browser/vr/elements/reticle.h new file mode 100644 index 0000000..144c506 --- /dev/null +++ b/chrome/browser/vr/elements/reticle.h
@@ -0,0 +1,45 @@ +// Copyright 2017 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_ELEMENTS_RETICLE_H_ +#define CHROME_BROWSER_VR_ELEMENTS_RETICLE_H_ + +#include "chrome/browser/vr/elements/ui_element.h" +#include "ui/gfx/geometry/point3_f.h" + +namespace vr { + +class UiScene; +struct Model; + +class Reticle : public UiElement { + public: + Reticle(UiScene* scene, Model* model); + ~Reticle() override; + + private: + void Render(UiElementRenderer* renderer, + const gfx::Transform& model_view_proj_matrix) const final; + + gfx::Point3F origin_; + gfx::Point3F target_; + + // This is used to convert the target id into a UiElement instance. We are not + // permitted to retain pointers to UiElements since they may be destructed, + // but the scene itself is constant, so we will look up our elements on the + // fly. + UiScene* scene_; + + // Unlike other UiElements which bind their values form the model, the reticle + // must derive values from the model late in the pipeline after the scene has + // fully updated its geometry. We therefore retain a pointer to the model and + // make use of it in |Render|. + Model* model_; + + DISALLOW_COPY_AND_ASSIGN(Reticle); +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_ELEMENTS_RETICLE_H_
diff --git a/chrome/browser/vr/elements/ui_element_name.cc b/chrome/browser/vr/elements/ui_element_name.cc new file mode 100644 index 0000000..2ee8b44a --- /dev/null +++ b/chrome/browser/vr/elements/ui_element_name.cc
@@ -0,0 +1,92 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/vr/elements/ui_element_name.h" + +#include "base/macros.h" + +namespace vr { + +namespace { + +static const char* g_ui_element_name_strings[] = { + "kNone", + "kRoot", + "k2dBrowsingRoot", + "k2dBrowsingBackground", + "k2dBrowsingForeground", + "k2dBrowsingContentGroup", + "k2dBrowsingViewportAwareRoot", + "kWebVrRoot", + "kWebVrViewportAwareRoot", + "kContentQuad", + "kControllerGroup", + "kLaser", + "kController", + "kReticle", + "kBackplane", + "kCeiling", + "kFloor", + "kUrlBar", + "kIndicatorLayout", + "kAudioCaptureIndicator", + "kVideoCaptureIndicator", + "kScreenCaptureIndicator", + "kLocationAccessIndicator", + "kBluetoothConnectedIndicator", + "kLoadingIndicator", + "kLoadingIndicatorForeground", + "kCloseButton", + "kVoiceSearchButton", + "kScreenDimmer", + "kExitWarning", + "kExitPrompt", + "kExitPromptBackplane", + "kWebVrUrlToastTransientParent", + "kWebVrUrlToast", + "kExclusiveScreenToastTransientParent", + "kExclusiveScreenToast", + "kExclusiveScreenToastViewportAwareTransientParent", + "kExclusiveScreenToastViewportAware", + "kSplashScreenRoot", + "kSplashScreenTransientParent", + "kSplashScreenViewportAwareRoot", + "kSplashScreenText", + "kSplashScreenBackground", + "kBackgroundFront", + "kBackgroundLeft", + "kBackgroundBack", + "kBackgroundRight", + "kBackgroundTop", + "kBackgroundBottom", + "kUnderDevelopmentNotice", + "kWebVrTimeoutSpinner", + "kWebVrTimeoutSpinnerBackground", + "kWebVrTimeoutMessage", + "kWebVrTimeoutMessageLayout", + "kWebVrTimeoutMessageIcon", + "kWebVrTimeoutMessageText", + "kWebVrTimeoutMessageButton", + "kWebVrTimeoutMessageButtonText", + "kSpeechRecognitionPrompt", + "kSpeechRecognitionPromptGrowingCircle", + "kSpeechRecognitionPromptInnerCircle", + "kSpeechRecognitionPromptMicrophoneIcon", + "kSpeechRecognitionPromptBackplane", + "kSuggestionLayout", + "kNumUiElementNames", +}; + +static_assert( + kNumUiElementNames + 1 == arraysize(g_ui_element_name_strings), + "Mismatch between the kUiElementName enum and the corresponding array " + "of strings."); + +} // namespace + +std::string UiElementNameToString(UiElementName name) { + return g_ui_element_name_strings[name]; +} + +} // namespace vr
diff --git a/chrome/browser/vr/elements/ui_element_name.h b/chrome/browser/vr/elements/ui_element_name.h index 70488676..729a7fa 100644 --- a/chrome/browser/vr/elements/ui_element_name.h +++ b/chrome/browser/vr/elements/ui_element_name.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_NAME_H_ #define CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_NAME_H_ +#include <string> + namespace vr { // These identifiers serve as stable, semantic identifiers for UI elements. @@ -19,6 +21,10 @@ kWebVrRoot, kWebVrViewportAwareRoot, kContentQuad, + kControllerGroup, + kLaser, + kController, + kReticle, kBackplane, kCeiling, kFloor, @@ -69,8 +75,13 @@ kSpeechRecognitionPromptMicrophoneIcon, kSpeechRecognitionPromptBackplane, kSuggestionLayout, + + // This must be last. + kNumUiElementNames, }; +std::string UiElementNameToString(UiElementName name); + } // namespace vr #endif // CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_NAME_H_
diff --git a/chrome/browser/vr/model/controller_model.h b/chrome/browser/vr/model/controller_model.h new file mode 100644 index 0000000..0d8dd11c --- /dev/null +++ b/chrome/browser/vr/model/controller_model.h
@@ -0,0 +1,30 @@ +// Copyright 2017 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_MODEL_CONTROLLER_MODEL_H_ +#define CHROME_BROWSER_VR_MODEL_CONTROLLER_MODEL_H_ + +#include "chrome/browser/vr/ui_input_manager.h" +#include "ui/gfx/geometry/point3_f.h" +#include "ui/gfx/transform.h" + +namespace vr { + +// The ControllerModel encapsulates generic controller information read from the +// platform-specific VR subsystem (e.g., GVR). It is used by both the +// UiInputManager (for generating gestures), and by the UI for rendering the +// controller. +struct ControllerModel { + gfx::Transform transform; + gfx::Vector3dF laser_direction; + gfx::Point3F laser_origin; + UiInputManager::ButtonState touchpad_button_state = UiInputManager::UP; + UiInputManager::ButtonState app_button_state = UiInputManager::UP; + UiInputManager::ButtonState home_button_state = UiInputManager::UP; + float opacity = 1.0f; +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_MODEL_CONTROLLER_MODEL_H_
diff --git a/chrome/browser/vr/model/model.h b/chrome/browser/vr/model/model.h index 5260d17..07df52e6de 100644 --- a/chrome/browser/vr/model/model.h +++ b/chrome/browser/vr/model/model.h
@@ -5,26 +5,13 @@ #ifndef CHROME_BROWSER_VR_MODEL_MODEL_H_ #define CHROME_BROWSER_VR_MODEL_MODEL_H_ +#include "chrome/browser/vr/model/controller_model.h" #include "chrome/browser/vr/model/omnibox_suggestions.h" +#include "chrome/browser/vr/model/reticle_model.h" +#include "chrome/browser/vr/model/web_vr_timeout_state.h" namespace vr { -// As we wait for WebVR frames, we may pass through the following states. -enum WebVrTimeoutState { - // We are not awaiting a WebVR frame. - kWebVrNoTimeoutPending, - kWebVrAwaitingFirstFrame, - // We are awaiting a WebVR frame, and we will soon exceed the amount of time - // that we're willing to wait. In this state, it could be appropriate to show - // an affordance to the user to let them know that WebVR is delayed (eg, this - // would be when we might show a spinner or progress bar). - kWebVrTimeoutImminent, - // In this case the time allotted for waiting for the first WebVR frame has - // been entirely exceeded. This would, for example, be an appropriate time to - // show "sad tab" UI to allow the user to bail on the WebVR content. - kWebVrTimedOut, -}; - struct Model { Model(); ~Model(); @@ -38,6 +25,9 @@ bool recognizing_speech = false; int speech_recognition_state = 0; + ControllerModel controller; + ReticleModel reticle; + std::vector<OmniboxSuggestion> omnibox_suggestions; };
diff --git a/chrome/browser/vr/model/reticle_model.h b/chrome/browser/vr/model/reticle_model.h new file mode 100644 index 0000000..768ae3e --- /dev/null +++ b/chrome/browser/vr/model/reticle_model.h
@@ -0,0 +1,24 @@ +// Copyright 2017 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_MODEL_RETICLE_MODEL_H_ +#define CHROME_BROWSER_VR_MODEL_RETICLE_MODEL_H_ + +#include "ui/gfx/geometry/point3_f.h" + +namespace vr { + +// The ReticleModel contains information related to the target of the +// controller's laser. It is computed by the UiInputManager and is used by the +// input manager in the production of gestures as well as by the Reticle element +// in the scene. +struct ReticleModel { + gfx::Point3F target_point; + gfx::PointF target_local_point; + int target_element_id = 0; +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_MODEL_RETICLE_MODEL_H_
diff --git a/chrome/browser/vr/model/web_vr_timeout_state.h b/chrome/browser/vr/model/web_vr_timeout_state.h new file mode 100644 index 0000000..84f756a3 --- /dev/null +++ b/chrome/browser/vr/model/web_vr_timeout_state.h
@@ -0,0 +1,28 @@ +// Copyright 2017 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_MODEL_WEB_VR_TIMEOUT_STATE_H_ +#define CHROME_BROWSER_VR_MODEL_WEB_VR_TIMEOUT_STATE_H_ + +namespace vr { + +// As we wait for WebVR frames, we may pass through the following states. +enum WebVrTimeoutState { + // We are not awaiting a WebVR frame. + kWebVrNoTimeoutPending, + kWebVrAwaitingFirstFrame, + // We are awaiting a WebVR frame, and we will soon exceed the amount of time + // that we're willing to wait. In this state, it could be appropriate to show + // an affordance to the user to let them know that WebVR is delayed (eg, this + // would be when we might show a spinner or progress bar). + kWebVrTimeoutImminent, + // In this case the time allotted for waiting for the first WebVR frame has + // been entirely exceeded. This would, for example, be an appropriate time to + // show "sad tab" UI to allow the user to bail on the WebVR content. + kWebVrTimedOut, +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_MODEL_WEB_VR_TIMEOUT_STATE_H_
diff --git a/chrome/browser/vr/test/fake_ui_element_renderer.cc b/chrome/browser/vr/test/fake_ui_element_renderer.cc index e5b46878..1c84c40 100644 --- a/chrome/browser/vr/test/fake_ui_element_renderer.cc +++ b/chrome/browser/vr/test/fake_ui_element_renderer.cc
@@ -45,4 +45,25 @@ called_ = true; } +void FakeUiElementRenderer::DrawController( + ControllerMesh::State state, + float opacity, + const gfx::Transform& view_proj_matrix) { + opacity_ = opacity; + called_ = true; +} + +void FakeUiElementRenderer::DrawLaser(float opacity, + const gfx::Transform& view_proj_matrix) { + opacity_ = opacity; + called_ = true; +} + +void FakeUiElementRenderer::DrawReticle( + float opacity, + const gfx::Transform& view_proj_matrix) { + opacity_ = opacity; + called_ = true; +} + } // namespace vr
diff --git a/chrome/browser/vr/test/fake_ui_element_renderer.h b/chrome/browser/vr/test/fake_ui_element_renderer.h index cc0a5ae..279cb110 100644 --- a/chrome/browser/vr/test/fake_ui_element_renderer.h +++ b/chrome/browser/vr/test/fake_ui_element_renderer.h
@@ -40,6 +40,16 @@ int gridline_count, float opacity) override; + void DrawController(ControllerMesh::State state, + float opacity, + const gfx::Transform& view_proj_matrix) override; + + void DrawLaser(float opacity, + const gfx::Transform& view_proj_matrix) override; + + void DrawReticle(float opacity, + const gfx::Transform& view_proj_matrix) override; + private: float opacity_ = -1.f; float called_ = false;
diff --git a/chrome/browser/vr/test/ui_pixel_test.cc b/chrome/browser/vr/test/ui_pixel_test.cc index 7771feb..366b1a8 100644 --- a/chrome/browser/vr/test/ui_pixel_test.cc +++ b/chrome/browser/vr/test/ui_pixel_test.cc
@@ -7,6 +7,7 @@ #include "base/memory/ptr_util.h" #include "build/build_config.h" #include "chrome/browser/vr/browser_ui_interface.h" +#include "chrome/browser/vr/model/model.h" #include "chrome/browser/vr/test/constants.h" #include "chrome/browser/vr/ui_browser_interface.h" #include "chrome/browser/vr/ui_input_manager.h" @@ -69,13 +70,14 @@ const gfx::Transform& controller_transform, const gfx::Transform& view_matrix, const gfx::Transform& proj_matrix) { - ControllerInfo controller_info; - controller_info.transform = controller_transform; - controller_info.opacity = controller_opacity; - controller_info.laser_origin = laser_origin; - controller_info.touchpad_button_state = button_state; - controller_info.app_button_state = UiInputManager::ButtonState::UP; - controller_info.home_button_state = UiInputManager::ButtonState::UP; + ControllerModel controller_model; + controller_model.laser_direction = kForwardVector; + controller_model.transform = controller_transform; + controller_model.opacity = controller_opacity; + controller_model.laser_origin = laser_origin; + controller_model.touchpad_button_state = button_state; + controller_model.app_button_state = UiInputManager::ButtonState::UP; + controller_model.home_button_state = UiInputManager::ButtonState::UP; RenderInfo render_info; render_info.head_pose = view_matrix; render_info.left_eye_info.view_matrix = view_matrix; @@ -88,17 +90,16 @@ render_info.right_eye_info.viewport = {0, 0, 0, 0}; GestureList gesture_list; + ReticleModel reticle_model; EXPECT_TRUE(ui_->scene()->OnBeginFrame( base::TimeTicks(), gfx::Vector3dF(-render_info.head_pose.matrix().get(2, 0), -render_info.head_pose.matrix().get(2, 1), -render_info.head_pose.matrix().get(2, 2)))); - ui_->input_manager()->HandleInput( - gfx::Vector3dF(0.0f, 0.0f, -1.0f), controller_info.laser_origin, - controller_info.touchpad_button_state, &gesture_list, - &controller_info.target_point, &controller_info.reticle_render_target); - - ui_->ui_renderer()->Draw(render_info, controller_info); + ui_->input_manager()->HandleInput(controller_model, &reticle_model, + &gesture_list); + ui_->OnControllerUpdated(controller_model, reticle_model); + ui_->ui_renderer()->Draw(render_info); // We produce GL errors while rendering. Clear them all so that we can check // for errors of subsequent calls.
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc index 3cd5fdc..e9913a4 100644 --- a/chrome/browser/vr/testapp/vr_test_context.cc +++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -10,6 +10,7 @@ #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/vr/controller_mesh.h" #include "chrome/browser/vr/model/model.h" #include "chrome/browser/vr/model/omnibox_suggestions.h" #include "chrome/browser/vr/test/constants.h" @@ -45,15 +46,12 @@ constexpr float kViewScaleAdjustmentFactor = 0.2f; constexpr gfx::Point3F kLaserOrigin = {0.5f, -0.5f, 0.f}; +constexpr gfx::Vector3dF kLaserLocalOffset = {0.f, -0.0075f, -0.05f}; +constexpr float kControllerScaleFactor = 1.5f; } // namespace -VrTestContext::VrTestContext() - : controller_info_(base::MakeUnique<ControllerInfo>()), - view_scale_factor_(kDefaultViewScaleFactor) { - controller_info_->reticle_render_target = nullptr; - controller_info_->laser_origin = kLaserOrigin; - +VrTestContext::VrTestContext() : view_scale_factor_(kDefaultViewScaleFactor) { base::FilePath pak_path; PathService::Get(base::DIR_MODULE, &pak_path); ui::ResourceBundle::InitSharedInstanceWithPakPath( @@ -97,7 +95,7 @@ // Update the render position of all UI elements (including desktop). ui_->scene()->OnBeginFrame(current_time, kForwardVector); ui_->OnProjMatrixChanged(render_info.left_eye_info.proj_matrix); - ui_->ui_renderer()->Draw(render_info, *controller_info_); + ui_->ui_renderer()->Draw(render_info); // TODO(cjgrant): Render viewport-aware elements. } @@ -182,12 +180,27 @@ gfx::Vector3dF controller_direction = {0, 0, -1.f}; beam_transform.TransformVector(&controller_direction); + gfx::Vector3dF local_offset = kLaserLocalOffset; + beam_transform.TransformVector(&local_offset); + local_offset.Scale(kControllerScaleFactor); + + ControllerModel controller_model; + controller_model.laser_direction = controller_direction; + controller_model.laser_origin = kLaserOrigin + local_offset; + + controller_model.transform.Translate3d(kLaserOrigin.x(), kLaserOrigin.y(), + kLaserOrigin.z()); + + controller_model.transform.Scale3d( + kControllerScaleFactor, kControllerScaleFactor, kControllerScaleFactor); + controller_model.transform.RotateAboutYAxis(head_angle_y_degrees_ + delta_y); + controller_model.transform.RotateAboutXAxis(head_angle_x_degrees_ + delta_x); + GestureList gesture_list; - ui_->input_manager()->HandleInput( - controller_direction, controller_info_->laser_origin, - controller_info_->touchpad_button_state, &gesture_list, - &controller_info_->target_point, - &controller_info_->reticle_render_target); + ReticleModel reticle_model; + ui_->input_manager()->HandleInput(controller_model, &reticle_model, + &gesture_list); + ui_->OnControllerUpdated(controller_model, reticle_model); } void VrTestContext::OnGlInitialized(const gfx::Size& window_size) { @@ -196,6 +209,9 @@ window_size_ = window_size; ui_->OnGlInitialized(content_texture_id, UiElementRenderer::kTextureLocationLocal); + + ui_->vr_shell_renderer()->GetControllerRenderer()->SetUp( + ControllerMesh::LoadFromResources()); } unsigned int VrTestContext::CreateFakeContentTexture() {
diff --git a/chrome/browser/vr/testapp/vr_test_context.h b/chrome/browser/vr/testapp/vr_test_context.h index 5b311b4..428f5367 100644 --- a/chrome/browser/vr/testapp/vr_test_context.h +++ b/chrome/browser/vr/testapp/vr_test_context.h
@@ -19,7 +19,6 @@ namespace vr { -struct ControllerInfo; class Ui; // This class provides a home for the VR UI in a testapp context, and @@ -69,8 +68,6 @@ std::unique_ptr<Ui> ui_; gfx::Size window_size_; - std::unique_ptr<ControllerInfo> controller_info_; - gfx::Transform head_pose_; float head_angle_x_degrees_ = 0; float head_angle_y_degrees_ = 0;
diff --git a/chrome/browser/vr/ui.cc b/chrome/browser/vr/ui.cc index c930f86e..b8e0340 100644 --- a/chrome/browser/vr/ui.cc +++ b/chrome/browser/vr/ui.cc
@@ -132,6 +132,12 @@ scene_manager_->OnAppButtonGesturePerformed(direction); } +void Ui::OnControllerUpdated(const ControllerModel& controller_model, + const ReticleModel& reticle_model) { + model_->controller = controller_model; + model_->reticle = reticle_model; +} + void Ui::OnProjMatrixChanged(const gfx::Transform& proj_matrix) { scene_manager_->OnProjMatrixChanged(proj_matrix); }
diff --git a/chrome/browser/vr/ui.h b/chrome/browser/vr/ui.h index e38d9f4..4524a4f 100644 --- a/chrome/browser/vr/ui.h +++ b/chrome/browser/vr/ui.h
@@ -77,6 +77,8 @@ UiElementRenderer::TextureLocation content_location) override; void OnAppButtonClicked() override; void OnAppButtonGesturePerformed(UiInterface::Direction direction) override; + void OnControllerUpdated(const ControllerModel& controller_model, + const ReticleModel& reticle_model) override; void OnProjMatrixChanged(const gfx::Transform& proj_matrix) override; void OnWebVrFrameAvailable() override; void OnWebVrTimedOut() override;
diff --git a/chrome/browser/vr/ui_element_renderer.h b/chrome/browser/vr/ui_element_renderer.h index 08f10ee..f110bc9 100644 --- a/chrome/browser/vr/ui_element_renderer.h +++ b/chrome/browser/vr/ui_element_renderer.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_VR_UI_ELEMENT_RENDERER_H_ #define CHROME_BROWSER_VR_UI_ELEMENT_RENDERER_H_ +#include "chrome/browser/vr/controller_mesh.h" #include "third_party/skia/include/core/SkColor.h" namespace gfx { @@ -46,6 +47,17 @@ const SkColor grid_color, int gridline_count, float opacity) = 0; + + // TODO(crbug/779108) This presumes a Daydream controller. + virtual void DrawController(ControllerMesh::State state, + float opacity, + const gfx::Transform& view_proj_matrix) = 0; + + virtual void DrawLaser(float opacity, + const gfx::Transform& view_proj_matrix) = 0; + + virtual void DrawReticle(float opacity, + const gfx::Transform& view_proj_matrix) = 0; }; } // namespace vr
diff --git a/chrome/browser/vr/ui_input_manager.cc b/chrome/browser/vr/ui_input_manager.cc index 6e89523..9fd474882 100644 --- a/chrome/browser/vr/ui_input_manager.cc +++ b/chrome/browser/vr/ui_input_manager.cc
@@ -8,6 +8,8 @@ #include "base/macros.h" #include "chrome/browser/vr/elements/ui_element.h" +#include "chrome/browser/vr/model/controller_model.h" +#include "chrome/browser/vr/model/reticle_model.h" #include "chrome/browser/vr/ui_scene.h" // TODO(tiborg): Remove include once we use a generic type to pass scroll/fling // gestures. @@ -70,15 +72,12 @@ } void HitTestElements(UiElement* element, + ReticleModel* reticle_model, gfx::Vector3dF* out_eye_to_target, - float* out_closest_element_distance, - gfx::Point3F* out_target_point, - UiElement** out_target_element, - gfx::PointF* out_target_local_point) { + float* out_closest_element_distance) { for (auto& child : element->children()) { - HitTestElements(child.get(), out_eye_to_target, - out_closest_element_distance, out_target_point, - out_target_element, out_target_local_point); + HitTestElements(child.get(), reticle_model, out_eye_to_target, + out_closest_element_distance); } if (!element->IsHitTestable()) { @@ -98,9 +97,9 @@ } *out_closest_element_distance = distance_to_plane; - *out_target_point = plane_intersection_point; - *out_target_element = element; - *out_target_local_point = local_point; + reticle_model->target_point = plane_intersection_point; + reticle_model->target_element_id = element->id(); + reticle_model->target_local_point = local_point; } } // namespace @@ -109,18 +108,13 @@ UiInputManager::~UiInputManager() {} -void UiInputManager::HandleInput(const gfx::Vector3dF& laser_direction, - const gfx::Point3F& laser_origin, - ButtonState button_state, - GestureList* gesture_list, - gfx::Point3F* out_target_point, - UiElement** out_reticle_render_target) { - gfx::PointF target_local_point(kInvalidTargetPoint); +void UiInputManager::HandleInput(const ControllerModel& controller_model, + ReticleModel* reticle_model, + GestureList* gesture_list) { gfx::Vector3dF eye_to_target; - *out_reticle_render_target = nullptr; - GetVisualTargetElement(laser_direction, laser_origin, &eye_to_target, - out_target_point, out_reticle_render_target, - &target_local_point); + reticle_model->target_element_id = 0; + reticle_model->target_local_point = kInvalidTargetPoint; + GetVisualTargetElement(controller_model, reticle_model, &eye_to_target); UiElement* target_element = nullptr; // TODO(vollick): this should be replaced with a formal notion of input @@ -132,16 +126,16 @@ float distance_to_plane; if (!GetTargetLocalPoint(eye_to_target, *target_element, 2 * scene_->background_distance(), - &target_local_point, &plane_intersection_point, - &distance_to_plane)) { - target_local_point = kInvalidTargetPoint; + &reticle_model->target_local_point, + &plane_intersection_point, &distance_to_plane)) { + reticle_model->target_local_point = kInvalidTargetPoint; } } } else if (!in_scroll_ && !in_click_) { // TODO(vollick): support multiple dispatch. We may want to, for example, // dispatch raw events to several elements we hit (imagine nested horizontal // and vertical scrollers). Currently, we only dispatch to one "winner". - target_element = *out_reticle_render_target; + target_element = scene_->GetUiElementById(reticle_model->target_element_id); if (target_element && IsScrollEvent(*gesture_list)) { UiElement* ancestor = target_element; while (!ancestor->scrollable() && ancestor->parent()) { @@ -153,12 +147,14 @@ } } - SendFlingCancel(gesture_list, target_local_point); + SendFlingCancel(gesture_list, reticle_model->target_local_point); // For simplicity, don't allow scrolling while clicking until we need to. if (!in_click_) { - SendScrollEnd(gesture_list, target_local_point, button_state); - if (!SendScrollBegin(target_element, gesture_list, target_local_point)) { - SendScrollUpdate(gesture_list, target_local_point); + SendScrollEnd(gesture_list, reticle_model->target_local_point, + controller_model.touchpad_button_state); + if (!SendScrollBegin(target_element, gesture_list, + reticle_model->target_local_point)) { + SendScrollUpdate(gesture_list, reticle_model->target_local_point); } } @@ -168,18 +164,22 @@ return; } SendHoverLeave(target_element); - if (!SendHoverEnter(target_element, target_local_point)) { - SendHoverMove(target_local_point); + if (!SendHoverEnter(target_element, reticle_model->target_local_point)) { + SendHoverMove(reticle_model->target_local_point); } - SendButtonDown(target_element, target_local_point, button_state); - if (SendButtonUp(target_element, target_local_point, button_state)) { - target_element = *out_reticle_render_target; + SendButtonDown(target_element, reticle_model->target_local_point, + controller_model.touchpad_button_state); + if (SendButtonUp(target_element, reticle_model->target_local_point, + controller_model.touchpad_button_state)) { + target_element = scene_->GetUiElementById(reticle_model->target_element_id); SendHoverLeave(target_element); - SendHoverEnter(target_element, target_local_point); + SendHoverEnter(target_element, reticle_model->target_local_point); } previous_button_state_ = - (button_state == ButtonState::CLICKED) ? ButtonState::UP : button_state; + (controller_model.touchpad_button_state == ButtonState::CLICKED) + ? ButtonState::UP + : controller_model.touchpad_button_state; } void UiInputManager::SendFlingCancel(GestureList* gesture_list, @@ -374,12 +374,9 @@ } void UiInputManager::GetVisualTargetElement( - const gfx::Vector3dF& laser_direction, - const gfx::Point3F& laser_origin, - gfx::Vector3dF* out_eye_to_target, - gfx::Point3F* out_target_point, - UiElement** out_target_element, - gfx::PointF* out_target_local_point) const { + const ControllerModel& controller_model, + ReticleModel* reticle_model, + gfx::Vector3dF* out_eye_to_target) const { // If we place the reticle based on elements intersecting the controller beam, // we can end up with the reticle hiding behind elements, or jumping laterally // in the field of view. This is physically correct, but hard to use. For @@ -395,17 +392,19 @@ // that the sphere is centered at the controller, rather than the eye, for // simplicity. float distance = scene_->background_distance(); - *out_target_point = GetRayPoint(laser_origin, laser_direction, distance); - *out_eye_to_target = *out_target_point - kOrigin; + reticle_model->target_point = + GetRayPoint(controller_model.laser_origin, + controller_model.laser_direction, distance); + *out_eye_to_target = reticle_model->target_point - kOrigin; out_eye_to_target->GetNormalized(out_eye_to_target); // Determine which UI element (if any) intersects the line between the eyes // and the controller target position. - float closest_element_distance = (*out_target_point - kOrigin).Length(); + float closest_element_distance = + (reticle_model->target_point - kOrigin).Length(); - HitTestElements(&scene_->root_element(), out_eye_to_target, - &closest_element_distance, out_target_point, - out_target_element, out_target_local_point); + HitTestElements(&scene_->root_element(), reticle_model, out_eye_to_target, + &closest_element_distance); } } // namespace vr
diff --git a/chrome/browser/vr/ui_input_manager.h b/chrome/browser/vr/ui_input_manager.h index 2920b95d..55ea0729 100644 --- a/chrome/browser/vr/ui_input_manager.h +++ b/chrome/browser/vr/ui_input_manager.h
@@ -20,6 +20,8 @@ class UiScene; class UiElement; +struct ControllerModel; +struct ReticleModel; using GestureList = std::vector<std::unique_ptr<blink::WebGestureEvent>>; @@ -36,12 +38,9 @@ explicit UiInputManager(UiScene* scene); ~UiInputManager(); // TODO(tiborg): Use generic gesture type instead of blink::WebGestureEvent. - void HandleInput(const gfx::Vector3dF& laser_direction, - const gfx::Point3F& laser_origin, - ButtonState button_state, - GestureList* gesture_list, - gfx::Point3F* out_target_point, - UiElement** out_reticle_render_target); + void HandleInput(const ControllerModel& controller_model, + ReticleModel* reticle_model, + GestureList* gesture_list); private: void SendFlingCancel(GestureList* gesture_list, @@ -63,12 +62,9 @@ bool SendButtonUp(UiElement* target, const gfx::PointF& target_point, ButtonState button_state); - void GetVisualTargetElement(const gfx::Vector3dF& laser_direction, - const gfx::Point3F& laser_origin, - gfx::Vector3dF* out_eye_to_target, - gfx::Point3F* out_target_point, - UiElement** out_target_element, - gfx::PointF* out_target_local_point) const; + void GetVisualTargetElement(const ControllerModel& controller_model, + ReticleModel* reticle_model, + gfx::Vector3dF* out_eye_to_target) const; UiScene* scene_; int hover_target_id_ = 0;
diff --git a/chrome/browser/vr/ui_input_manager_unittest.cc b/chrome/browser/vr/ui_input_manager_unittest.cc index c9786a1b..fb8f2ba 100644 --- a/chrome/browser/vr/ui_input_manager_unittest.cc +++ b/chrome/browser/vr/ui_input_manager_unittest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/vr/content_input_delegate.h" #include "chrome/browser/vr/elements/rect.h" #include "chrome/browser/vr/elements/ui_element.h" +#include "chrome/browser/vr/model/model.h" #include "chrome/browser/vr/test/animation_utils.h" #include "chrome/browser/vr/test/constants.h" #include "chrome/browser/vr/test/mock_content_input_delegate.h" @@ -65,11 +66,14 @@ void HandleInput(const gfx::Vector3dF& laser_direction, UiInputManager::ButtonState button_state) { + ControllerModel controller_model; + controller_model.laser_direction = laser_direction; + controller_model.laser_origin = {0, 0, 0}; + controller_model.touchpad_button_state = button_state; + ReticleModel reticle_model; GestureList gesture_list; - gfx::Point3F target_point; - UiElement* target_element; - input_manager_->HandleInput(laser_direction, {0, 0, 0}, button_state, - &gesture_list, &target_point, &target_element); + input_manager_->HandleInput(controller_model, &reticle_model, + &gesture_list); } protected: @@ -99,18 +103,20 @@ scene_->AddUiElement(kRoot, std::move(element)); scene_->OnBeginFrame(base::TimeTicks(), kForwardVector); + ControllerModel controller_model; + controller_model.laser_direction = kBackwardVector; + controller_model.laser_origin = {0, 0, 0}; + controller_model.touchpad_button_state = kUp; + ReticleModel reticle_model; GestureList gesture_list; - gfx::Point3F target_point; - UiElement* target; - input_manager_->HandleInput(kBackwardVector, {0, 0, 0}, kUp, &gesture_list, - &target_point, &target); - EXPECT_EQ(target, nullptr); + input_manager_->HandleInput(controller_model, &reticle_model, &gesture_list); + EXPECT_EQ(0, reticle_model.target_element_id); - input_manager_->HandleInput(kForwardVector, {0, 0, 0}, kUp, &gesture_list, - &target_point, &target); - EXPECT_EQ(target, p_element); - EXPECT_NEAR(target_point.z(), -1.0, kEpsilon); + controller_model.laser_direction = kForwardVector; + input_manager_->HandleInput(controller_model, &reticle_model, &gesture_list); + EXPECT_EQ(p_element->id(), reticle_model.target_element_id); + EXPECT_NEAR(-1.0, reticle_model.target_point.z(), kEpsilon); } // Test hover and click by toggling button state, and directing the controller @@ -230,25 +236,25 @@ gfx::Point3F content_quad_center; content_quad->world_space_transform().TransformPoint(&content_quad_center); gfx::Point3F origin; + + ControllerModel controller_model; + controller_model.laser_direction = content_quad_center - origin; + controller_model.laser_origin = origin; + controller_model.touchpad_button_state = UiInputManager::ButtonState::DOWN; + ReticleModel reticle_model; GestureList gesture_list; - gfx::Point3F out_target_point; - UiElement* out_reticle_render_target; - input_manager_->HandleInput(content_quad_center - origin, origin, - UiInputManager::ButtonState::DOWN, &gesture_list, - &out_target_point, &out_reticle_render_target); + input_manager_->HandleInput(controller_model, &reticle_model, &gesture_list); // We should have hit the content quad if our math was correct. - ASSERT_NE(nullptr, out_reticle_render_target); - EXPECT_EQ(UiElementName::kContentQuad, out_reticle_render_target->name()); + ASSERT_NE(0, reticle_model.target_element_id); + EXPECT_EQ(content_quad->id(), reticle_model.target_element_id); // Unless we suppress content move events during clicks, this will cause us to // call OnContentMove on the delegate. We should do this suppression, so we // set the expected number of calls to zero. EXPECT_CALL(*content_input_delegate_, OnContentMove(testing::_)).Times(0); - input_manager_->HandleInput(content_quad_center - origin, origin, - UiInputManager::ButtonState::DOWN, &gesture_list, - &out_target_point, &out_reticle_render_target); + input_manager_->HandleInput(controller_model, &reticle_model, &gesture_list); } } // namespace vr
diff --git a/chrome/browser/vr/ui_interface.h b/chrome/browser/vr/ui_interface.h index 3f3c0b1..d487c706 100644 --- a/chrome/browser/vr/ui_interface.h +++ b/chrome/browser/vr/ui_interface.h
@@ -13,6 +13,9 @@ namespace vr { +struct ControllerModel; +struct ReticleModel; + // This is the platform-specific interface to the VR UI. class UiInterface { public: @@ -34,6 +37,8 @@ virtual void OnAppButtonClicked() = 0; virtual void OnAppButtonGesturePerformed( UiInterface::Direction direction) = 0; + virtual void OnControllerUpdated(const ControllerModel& controller_model, + const ReticleModel& reticle_model) = 0; virtual void OnProjMatrixChanged(const gfx::Transform& proj_matrix) = 0; virtual void OnWebVrFrameAvailable() = 0; virtual void OnWebVrTimedOut() = 0;
diff --git a/chrome/browser/vr/ui_renderer.cc b/chrome/browser/vr/ui_renderer.cc index 920ca5b..59c01cb 100644 --- a/chrome/browser/vr/ui_renderer.cc +++ b/chrome/browser/vr/ui_renderer.cc
@@ -4,61 +4,34 @@ #include "chrome/browser/vr/ui_renderer.h" -#include "base/numerics/math_constants.h" #include "base/trace_event/trace_event.h" #include "chrome/browser/vr/elements/ui_element.h" #include "chrome/browser/vr/ui_scene.h" -#include "chrome/browser/vr/vr_controller_model.h" #include "chrome/browser/vr/vr_shell_renderer.h" #include "ui/gl/gl_bindings.h" namespace vr { -namespace { - -static constexpr gfx::Point3F kOrigin = {0.0f, 0.0f, 0.0f}; - -// Fraction of the distance to the object the reticle is drawn at to avoid -// rounding errors drawing the reticle behind the object. -// TODO(mthiesse): Find a better approach for drawing the reticle on an object. -// Right now we have to wedge it very precisely between the content window and -// backplane to avoid rendering artifacts. We should stop using the depth buffer -// since the back-to-front order of our elements is well defined. This would, -// among other things, prevent z-fighting when we draw content in the same -// plane. -static constexpr float kReticleOffset = 0.999f; - -static constexpr float kLaserWidth = 0.01f; - -static constexpr float kReticleWidth = 0.025f; -static constexpr float kReticleHeight = 0.025f; - -} // namespace - UiRenderer::UiRenderer(UiScene* scene, VrShellRenderer* vr_shell_renderer) : scene_(scene), vr_shell_renderer_(vr_shell_renderer) {} UiRenderer::~UiRenderer() = default; -// TODO(crbug.com/767515): UiRenderer must not care about the elements its +// TODO(crbug.com/767515): UiRenderer must not care about the elements it's // rendering and be platform agnostic, each element should know how to render // itself correctly. -void UiRenderer::Draw(const RenderInfo& render_info, - const ControllerInfo& controller_info) { - Draw2dBrowsing(render_info, controller_info); - DrawSplashScreen(render_info, controller_info); +void UiRenderer::Draw(const RenderInfo& render_info) { + Draw2dBrowsing(render_info); + DrawSplashScreen(render_info); } -void UiRenderer::Draw2dBrowsing(const RenderInfo& render_info, - const ControllerInfo& controller_info) { +void UiRenderer::Draw2dBrowsing(const RenderInfo& render_info) { const auto& elements = scene_->GetVisible2dBrowsingElements(); const auto& elements_overlay = scene_->GetVisible2dBrowsingOverlayElements(); + const auto& controller_elements = scene_->GetVisibleControllerElements(); if (elements.empty() && elements_overlay.empty()) return; - // TODO(crbug.com/767583): The controller is drawn as part of a call to - // DrawUiView for 2d browsing elements. This means that the controller is not - // supported with overlay elements. if (!elements.empty()) { // Enable depth testing. Note that we do not clear the color buffer. The // scene's background elements are responsible for drawing a complete @@ -67,24 +40,24 @@ glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glClear(GL_DEPTH_BUFFER_BIT); - DrawUiView(render_info, controller_info, elements, - scene_->ControllerWouldBeVisibleInTheSceneGraph() - ? kReticleVisible - : kReticleHidden); + DrawUiView(render_info, elements); } - if (elements_overlay.empty()) + if (elements_overlay.empty() && controller_elements.empty()) return; // The overlays do not make use of depth testing. glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); - DrawUiView(render_info, controller_info, elements_overlay, kReticleHidden); + DrawUiView(render_info, elements_overlay); + + // We do want to cull backfaces on the controller, however. + glEnable(GL_CULL_FACE); + DrawUiView(render_info, controller_elements); } -void UiRenderer::DrawSplashScreen(const RenderInfo& render_info, - const ControllerInfo& controller_info) { +void UiRenderer::DrawSplashScreen(const RenderInfo& render_info) { const auto& elements = scene_->GetVisibleSplashScreenElements(); if (elements.empty()) return; @@ -100,18 +73,13 @@ glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); - DrawUiView(render_info, controller_info, elements, - scene_->ControllerWouldBeVisibleInTheSceneGraph() - ? kReticleVisible - : kReticleHidden); + DrawUiView(render_info, elements); // NB: we do not draw the viewport aware objects here. They get put into // another buffer that is size optimized. } -void UiRenderer::DrawWebVrOverlayForeground( - const RenderInfo& render_info, - const ControllerInfo& controller_info) { +void UiRenderer::DrawWebVrOverlayForeground(const RenderInfo& render_info) { // The WebVR overlay foreground is drawn as a separate pass, so we need to set // up our gl state before drawing. glEnable(GL_CULL_FACE); @@ -120,15 +88,11 @@ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - DrawUiView(render_info, controller_info, - scene_->GetVisibleWebVrOverlayForegroundElements(), - kReticleHidden); + DrawUiView(render_info, scene_->GetVisibleWebVrOverlayForegroundElements()); } void UiRenderer::DrawUiView(const RenderInfo& render_info, - const ControllerInfo& controller_info, - const std::vector<const UiElement*>& elements, - UiRenderer::ReticleMode reticle_mode) { + const std::vector<const UiElement*>& elements) { TRACE_EVENT0("gpu", "VrShellGl::DrawUiView"); auto sorted_elements = GetElementsInDrawOrder(elements); @@ -138,40 +102,18 @@ glViewport(eye_info.viewport.x(), eye_info.viewport.y(), eye_info.viewport.width(), eye_info.viewport.height()); - DrawElements(eye_info.view_proj_matrix, sorted_elements, render_info, - controller_info, reticle_mode); - if (reticle_mode == kReticleVisible) { - DrawController(eye_info.view_proj_matrix, render_info, controller_info); - DrawLaser(eye_info.view_proj_matrix, render_info, controller_info); - } + DrawElements(eye_info.view_proj_matrix, sorted_elements, render_info); } } void UiRenderer::DrawElements(const gfx::Transform& view_proj_matrix, const std::vector<const UiElement*>& elements, - const RenderInfo& render_info, - const ControllerInfo& controller_info, - UiRenderer::ReticleMode reticle_mode) { + const RenderInfo& render_info) { if (elements.empty()) { return; } - bool drawn_reticle = false; for (const auto* element : elements) { - // If we have no element to draw the reticle on, draw it after the - // background (the initial draw phase). - if (!controller_info.reticle_render_target && - reticle_mode == kReticleVisible && !drawn_reticle && - element->draw_phase() >= scene_->first_foreground_draw_phase()) { - DrawReticle(view_proj_matrix, render_info, controller_info); - drawn_reticle = true; - } - DrawElement(view_proj_matrix, *element); - - if (reticle_mode == kReticleVisible && - (controller_info.reticle_render_target == element)) { - DrawReticle(view_proj_matrix, render_info, controller_info); - } } vr_shell_renderer_->Flush(); } @@ -190,6 +132,8 @@ // Sort elements primarily based on their draw phase (lower draw phase first) // and secondarily based on their tree order (as specified by the sorted // |elements| vector). + // TODO(vollick): update the predicate to take into account some notion of "3d + // rendering contexts" and the ordering of the reticle wrt to other elements. std::stable_sort(sorted_elements.begin(), sorted_elements.end(), [](const UiElement* first, const UiElement* second) { return first->draw_phase() < second->draw_phase(); @@ -198,112 +142,4 @@ return sorted_elements; } -void UiRenderer::DrawReticle(const gfx::Transform& render_matrix, - const RenderInfo& render_info, - const ControllerInfo& controller_info) { - // Scale the reticle to have a fixed FOV size at any distance. - const float eye_to_target = - std::sqrt(controller_info.target_point.SquaredDistanceTo(kOrigin)); - - gfx::Transform mat; - mat.Scale3d(kReticleWidth * eye_to_target, kReticleHeight * eye_to_target, 1); - - gfx::Quaternion rotation; - - if (controller_info.reticle_render_target != nullptr) { - // Make the reticle planar to the element it's hitting. - rotation = - gfx::Quaternion(gfx::Vector3dF(0.0f, 0.0f, -1.0f), - -controller_info.reticle_render_target->GetNormal()); - } else { - // Rotate the reticle to directly face the eyes. - rotation = gfx::Quaternion(gfx::Vector3dF(0.0f, 0.0f, -1.0f), - controller_info.target_point - kOrigin); - } - gfx::Transform rotation_mat(rotation); - mat = rotation_mat * mat; - - gfx::Point3F target_point = - ScalePoint(controller_info.target_point, kReticleOffset); - // Place the pointer slightly in front of the plane intersection point. - mat.matrix().postTranslate(target_point.x(), target_point.y(), - target_point.z()); - - gfx::Transform transform = render_matrix * mat; - vr_shell_renderer_->GetReticleRenderer()->Draw(transform); -} - -void UiRenderer::DrawLaser(const gfx::Transform& render_matrix, - const RenderInfo& render_info, - const ControllerInfo& controller_info) { - // Find the length of the beam (from hand to target). - const float laser_length = - std::sqrt(controller_info.laser_origin.SquaredDistanceTo( - ScalePoint(controller_info.target_point, kReticleOffset))); - - // Build a beam, originating from the origin. - gfx::Transform mat; - - // Move the beam half its height so that its end sits on the origin. - mat.matrix().postTranslate(0.0f, 0.5f, 0.0f); - mat.matrix().postScale(kLaserWidth, laser_length, 1); - - // Tip back 90 degrees to flat, pointing at the scene. - const gfx::Quaternion quat(gfx::Vector3dF(1.0f, 0.0f, 0.0f), - -base::kPiDouble / 2); - gfx::Transform rotation_mat(quat); - mat = rotation_mat * mat; - - const gfx::Vector3dF beam_direction = - controller_info.target_point - controller_info.laser_origin; - - gfx::Transform beam_direction_mat( - gfx::Quaternion(gfx::Vector3dF(0.0f, 0.0f, -1.0f), beam_direction)); - - // Render multiple faces to make the laser appear cylindrical. - const int faces = 4; - gfx::Transform face_transform; - gfx::Transform transform; - for (int i = 0; i < faces; i++) { - // Rotate around Z. - const float angle = base::kPiFloat * 2 * i / faces; - const gfx::Quaternion rot({0.0f, 0.0f, 1.0f}, angle); - face_transform = beam_direction_mat * gfx::Transform(rot) * mat; - - // Move the beam origin to the hand. - face_transform.matrix().postTranslate(controller_info.laser_origin.x(), - controller_info.laser_origin.y(), - controller_info.laser_origin.z()); - transform = render_matrix * face_transform; - vr_shell_renderer_->GetLaserRenderer()->Draw(controller_info.opacity, - transform); - } -} - -void UiRenderer::DrawController(const gfx::Transform& view_proj_matrix, - const RenderInfo& render_info, - const ControllerInfo& controller_info) { - if (!vr_shell_renderer_->GetControllerRenderer()->IsSetUp()) { - return; - } - - VrControllerModel::State state; - if (controller_info.touchpad_button_state == - UiInputManager::ButtonState::DOWN) { - state = VrControllerModel::TOUCHPAD; - } else if (controller_info.app_button_state == - UiInputManager::ButtonState::DOWN) { - state = VrControllerModel::APP; - } else if (controller_info.home_button_state == - UiInputManager::ButtonState::DOWN) { - state = VrControllerModel::SYSTEM; - } else { - state = VrControllerModel::IDLE; - } - - gfx::Transform transform = view_proj_matrix * controller_info.transform; - vr_shell_renderer_->GetControllerRenderer()->Draw( - state, controller_info.opacity, transform); -} - } // namespace vr
diff --git a/chrome/browser/vr/ui_renderer.h b/chrome/browser/vr/ui_renderer.h index e02e119..b769387 100644 --- a/chrome/browser/vr/ui_renderer.h +++ b/chrome/browser/vr/ui_renderer.h
@@ -16,18 +16,6 @@ class UiElement; class VrShellRenderer; -// Provides information needed to render the controller. -struct ControllerInfo { - gfx::Point3F target_point; - gfx::Point3F laser_origin; - UiInputManager::ButtonState touchpad_button_state = UiInputManager::UP; - UiInputManager::ButtonState app_button_state = UiInputManager::UP; - UiInputManager::ButtonState home_button_state = UiInputManager::UP; - gfx::Transform transform; - float opacity = 1.0f; - UiElement* reticle_render_target = nullptr; -}; - // Provides information for rendering such as the viewport and view/projection // matrix. struct RenderInfo { @@ -52,45 +40,26 @@ VrShellRenderer* vr_shell_renderer); ~UiRenderer(); - void Draw(const RenderInfo& render_info, - const ControllerInfo& controller_info); + void Draw(const RenderInfo& render_info); // This is exposed separately because we do a separate pass to render this // content into an optimized viewport. - void DrawWebVrOverlayForeground(const RenderInfo& render_info, - const ControllerInfo& controller_info); + void DrawWebVrOverlayForeground(const RenderInfo& render_info); static std::vector<const UiElement*> GetElementsInDrawOrder( const std::vector<const UiElement*>& elements); private: - enum ReticleMode { kReticleVisible, kReticleHidden }; - - void Draw2dBrowsing(const RenderInfo& render_info, - const ControllerInfo& controller_info); - void DrawSplashScreen(const RenderInfo& render_info, - const ControllerInfo& controller_info); + void Draw2dBrowsing(const RenderInfo& render_info); + void DrawSplashScreen(const RenderInfo& render_info); void DrawUiView(const RenderInfo& render_info, - const ControllerInfo& controller_info, - const std::vector<const UiElement*>& elements, - ReticleMode reticle_mode); + const std::vector<const UiElement*>& elements); void DrawElements(const gfx::Transform& view_proj_matrix, const std::vector<const UiElement*>& elements, - const RenderInfo& render_info, - const ControllerInfo& controller_info, - ReticleMode reticle_mode); + const RenderInfo& render_info); void DrawElement(const gfx::Transform& view_proj_matrix, const UiElement& element); - void DrawReticle(const gfx::Transform& render_matrix, - const RenderInfo& render_info, - const ControllerInfo& controller_info); - void DrawLaser(const gfx::Transform& render_matrix, - const RenderInfo& render_info, - const ControllerInfo& controller_info); - void DrawController(const gfx::Transform& view_proj_matrix, - const RenderInfo& render_info, - const ControllerInfo& controller_info); UiScene* scene_ = nullptr; VrShellRenderer* vr_shell_renderer_ = nullptr;
diff --git a/chrome/browser/vr/ui_renderer_unittest.cc b/chrome/browser/vr/ui_renderer_unittest.cc index 4f33a34..0841991 100644 --- a/chrome/browser/vr/ui_renderer_unittest.cc +++ b/chrome/browser/vr/ui_renderer_unittest.cc
@@ -94,6 +94,10 @@ { kWebVrUrlToast, kExclusiveScreenToastViewportAware, }}, + {&UiScene::GetVisibleControllerElements, + { + kController, kLaser, kReticle, + }}, }; INSTANTIATE_TEST_CASE_P(SortingTests,
diff --git a/chrome/browser/vr/ui_scene.cc b/chrome/browser/vr/ui_scene.cc index 9baa2db5..7cbc253 100644 --- a/chrome/browser/vr/ui_scene.cc +++ b/chrome/browser/vr/ui_scene.cc
@@ -212,6 +212,13 @@ }); } +UiScene::Elements UiScene::GetVisibleControllerElements() const { + return GetVisibleElements(GetUiElementByName(kControllerGroup), + [](UiElement* element) { + return element->draw_phase() == kPhaseForeground; + }); +} + UiScene::UiScene() { root_element_ = base::MakeUnique<UiElement>(); root_element_->set_name(kRoot); @@ -230,18 +237,4 @@ element.Initialize(); } -bool UiScene::ControllerWouldBeVisibleInTheSceneGraph() const { - UiElement* button = GetUiElementByName(kWebVrTimeoutMessageButton); - if (button && button->IsVisible()) - return true; - - UiElement* browsing_root = GetUiElementByName(k2dBrowsingRoot); - bool browsing_mode = browsing_root && browsing_root->IsVisible(); - - UiElement* spinner_bg = GetUiElementByName(kWebVrTimeoutSpinnerBackground); - bool transitioning_to_webvr = spinner_bg && spinner_bg->IsVisible(); - - return browsing_mode && !transitioning_to_webvr; -} - } // namespace vr
diff --git a/chrome/browser/vr/ui_scene.h b/chrome/browser/vr/ui_scene.h index 5403093..5b1b18bd 100644 --- a/chrome/browser/vr/ui_scene.h +++ b/chrome/browser/vr/ui_scene.h
@@ -58,6 +58,7 @@ Elements GetVisible2dBrowsingOverlayElements() const; Elements GetVisibleSplashScreenElements() const; Elements GetVisibleWebVrOverlayForegroundElements() const; + Elements GetVisibleControllerElements() const; float background_distance() const { return background_distance_; } void set_background_distance(float d) { background_distance_ = d; } @@ -80,10 +81,6 @@ void OnGlInitialized(); - // TODO(vollick): this should be removed once the controller is in the scene - // graph. crbug.com/774501 - bool ControllerWouldBeVisibleInTheSceneGraph() const; - private: std::unique_ptr<UiElement> root_element_;
diff --git a/chrome/browser/vr/ui_scene_constants.h b/chrome/browser/vr/ui_scene_constants.h index f2398897..1582caa 100644 --- a/chrome/browser/vr/ui_scene_constants.h +++ b/chrome/browser/vr/ui_scene_constants.h
@@ -165,6 +165,23 @@ static constexpr float kScreenDimmerOpacity = 0.9f; +static constexpr gfx::Point3F kOrigin = {0.0f, 0.0f, 0.0f}; + +// Fraction of the distance to the object the reticle is drawn at to avoid +// rounding errors drawing the reticle behind the object. +// TODO(mthiesse): Find a better approach for drawing the reticle on an object. +// Right now we have to wedge it very precisely between the content window and +// backplane to avoid rendering artifacts. We should stop using the depth buffer +// since the back-to-front order of our elements is well defined. This would, +// among other things, prevent z-fighting when we draw content in the same +// plane. +static constexpr float kReticleOffset = 0.999f; + +static constexpr float kLaserWidth = 0.01f; + +static constexpr float kReticleWidth = 0.025f; +static constexpr float kReticleHeight = 0.025f; + static constexpr float kVoiceSearchButtonXOffset = 0.25f; static constexpr float kSuggestionGap = 0.01f;
diff --git a/chrome/browser/vr/ui_scene_manager.cc b/chrome/browser/vr/ui_scene_manager.cc index 86303633..804255f 100644 --- a/chrome/browser/vr/ui_scene_manager.cc +++ b/chrome/browser/vr/ui_scene_manager.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/vr/databinding/vector_binding.h" #include "chrome/browser/vr/elements/button.h" #include "chrome/browser/vr/elements/content_element.h" +#include "chrome/browser/vr/elements/controller.h" #include "chrome/browser/vr/elements/draw_phase.h" #include "chrome/browser/vr/elements/exclusive_screen_toast.h" #include "chrome/browser/vr/elements/exit_prompt.h" @@ -20,8 +21,10 @@ #include "chrome/browser/vr/elements/full_screen_rect.h" #include "chrome/browser/vr/elements/grid.h" #include "chrome/browser/vr/elements/invisible_hit_target.h" +#include "chrome/browser/vr/elements/laser.h" #include "chrome/browser/vr/elements/linear_layout.h" #include "chrome/browser/vr/elements/rect.h" +#include "chrome/browser/vr/elements/reticle.h" #include "chrome/browser/vr/elements/spinner.h" #include "chrome/browser/vr/elements/system_indicator.h" #include "chrome/browser/vr/elements/text.h" @@ -166,6 +169,7 @@ CreateSplashScreen(model); CreateUnderDevelopmentNotice(); CreateVoiceSearchUiGroup(model); + CreateController(model); ConfigureScene(); } @@ -623,6 +627,54 @@ scene_->AddUiElement(kSpeechRecognitionPrompt, std::move(element)); } +void UiSceneManager::CreateController(Model* model) { + auto group = base::MakeUnique<UiElement>(); + group->set_name(kControllerGroup); + group->SetVisible(true); + group->set_hit_testable(false); + group->AddBinding(base::MakeUnique<Binding<bool>>( + base::Bind( + [](Model* m, UiSceneManager* mgr) { + bool browsing_mode = + !mgr->web_vr_mode() && !mgr->showing_web_vr_splash_screen(); + return browsing_mode || m->web_vr_timeout_state == kWebVrTimedOut; + }, + base::Unretained(model), base::Unretained(this)), + base::Bind([](UiElement* v, const bool& b) { v->SetVisible(b); }, + base::Unretained(group.get())))); + scene_->AddUiElement(kRoot, std::move(group)); + + auto controller = base::MakeUnique<Controller>(); + controller->set_draw_phase(kPhaseForeground); + controller->AddBinding(VR_BIND_FUNC(gfx::Transform, Model, model, + controller.transform, Controller, + controller.get(), set_local_transform)); + controller->AddBinding( + VR_BIND_FUNC(bool, Model, model, + controller.touchpad_button_state == UiInputManager::DOWN, + Controller, controller.get(), set_touchpad_button_pressed)); + controller->AddBinding(VR_BIND_FUNC( + bool, Model, model, controller.app_button_state == UiInputManager::DOWN, + Controller, controller.get(), set_app_button_pressed)); + controller->AddBinding(VR_BIND_FUNC( + bool, Model, model, controller.home_button_state == UiInputManager::DOWN, + Controller, controller.get(), set_home_button_pressed)); + controller->AddBinding(VR_BIND_FUNC(float, Model, model, controller.opacity, + Controller, controller.get(), + SetOpacity)); + scene_->AddUiElement(kControllerGroup, std::move(controller)); + + auto laser = base::MakeUnique<Laser>(model); + laser->set_draw_phase(kPhaseForeground); + laser->AddBinding(VR_BIND_FUNC(float, Model, model, controller.opacity, Laser, + laser.get(), SetOpacity)); + scene_->AddUiElement(kControllerGroup, std::move(laser)); + + auto reticle = base::MakeUnique<Reticle>(scene_, model); + reticle->set_draw_phase(kPhaseForeground); + scene_->AddUiElement(kControllerGroup, std::move(reticle)); +} + void UiSceneManager::CreateUrlBar(Model* model) { auto url_bar = base::MakeUnique<UrlBar>( 512,
diff --git a/chrome/browser/vr/ui_scene_manager.h b/chrome/browser/vr/ui_scene_manager.h index fd6ba133..e6f41fd 100644 --- a/chrome/browser/vr/ui_scene_manager.h +++ b/chrome/browser/vr/ui_scene_manager.h
@@ -95,6 +95,10 @@ // kWebVrTimeoutMessageText // kWebVrTimeoutMessageButton // kWebVrTimeoutMessageButtonText +// kControllerGroup +// kLaser +// kController +// kReticle // // TODO(vollick): The above hierarchy is complex, brittle, and would be easier // to manage if it were specified in a declarative format. @@ -135,8 +139,12 @@ void OnSecurityIconClickedForTesting(); void OnExitPromptChoiceForTesting(bool chose_exit); - // TODO(vollick): this should move to the model. + // TODO(vollick): these should move to the model. const ColorScheme& color_scheme() const; + bool web_vr_mode() const { return web_vr_mode_; } + bool showing_web_vr_splash_screen() const { + return showing_web_vr_splash_screen_; + } private: void Create2dBrowsingSubtreeRoots(Model* model); @@ -156,6 +164,7 @@ void CreateExitPrompt(); void CreateToasts(Model* model); void CreateVoiceSearchUiGroup(Model* model); + void CreateController(Model* model); void ConfigureScene(); void ConfigureExclusiveScreenToast();
diff --git a/chrome/browser/vr/vr_shell_renderer.cc b/chrome/browser/vr/vr_shell_renderer.cc index 8bad7f07..8d63177 100644 --- a/chrome/browser/vr/vr_shell_renderer.cc +++ b/chrome/browser/vr/vr_shell_renderer.cc
@@ -204,6 +204,7 @@ uniform mediump float inner_ring_thickness; uniform mediump float mid_ring_end; uniform mediump float mid_ring_opacity; + uniform mediump float opacity; void main() { mediump float r = length(v_TexCoordinate - vec2(0.5, 0.5)); @@ -222,7 +223,7 @@ mediump float black_alpha_factor = mid_ring_opacity * (1.0 - (r - black_radius) * black_feather); mediump float alpha = clamp( - min(hole_alpha, max(color1, black_alpha_factor)), 0.0, 1.0); + min(hole_alpha, max(color1, black_alpha_factor)) * opacity, 0.0, 1.0); lowp vec3 color_rgb = color1 * color.xyz; gl_FragColor = vec4(color_rgb * color.w * alpha, color.w * alpha); } @@ -317,7 +318,10 @@ float mask = 1.0 - step(1.0, length(v_CornerPosition)); // Add some noise to prevent banding artifacts in the gradient. float n = (fract(dot(v_Position.xy, vec2(12345.67, 456.7))) - 0.5) / 255.0; - gl_FragColor = (color + n) * u_Opacity * mask; + + color = color + n; + color = vec4(color.rgb * color.a, color.a); + gl_FragColor = color * u_Opacity * mask; } ); @@ -750,9 +754,11 @@ mid_ring_end_handle_ = glGetUniformLocation(program_handle_, "mid_ring_end"); mid_ring_opacity_handle_ = glGetUniformLocation(program_handle_, "mid_ring_opacity"); + opacity_handle_ = glGetUniformLocation(program_handle_, "opacity"); } -void ReticleRenderer::Draw(const gfx::Transform& view_proj_matrix) { +void ReticleRenderer::Draw(float opacity, + const gfx::Transform& view_proj_matrix) { PrepareToDraw(model_view_proj_matrix_handle_, view_proj_matrix); glUniform4f(color_handle_, kReticleColor[0], kReticleColor[1], @@ -763,6 +769,7 @@ glUniform1f(inner_ring_thickness_handle_, kInnerRingThickness); glUniform1f(mid_ring_end_handle_, kMidRingEnd); glUniform1f(mid_ring_opacity_handle_, kMidRingOpacity); + glUniform1f(opacity_handle_, opacity); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_); glDrawElements(GL_TRIANGLES, arraysize(kQuadIndices), GL_UNSIGNED_SHORT, 0); @@ -815,7 +822,7 @@ ControllerRenderer::ControllerRenderer() : BaseRenderer(kControllerVertexShader, kControllerFragmentShader), - texture_handles_(VrControllerModel::STATE_COUNT) { + texture_handles_(ControllerMesh::STATE_COUNT) { model_view_proj_matrix_handle_ = glGetUniformLocation(program_handle_, "u_ModelViewProjMatrix"); tex_coord_handle_ = glGetAttribLocation(program_handle_, "a_TexCoordinate"); @@ -825,7 +832,7 @@ ControllerRenderer::~ControllerRenderer() = default; -void ControllerRenderer::SetUp(std::unique_ptr<VrControllerModel> model) { +void ControllerRenderer::SetUp(std::unique_ptr<ControllerMesh> model) { TRACE_EVENT0("gpu", "ControllerRenderer::SetUp"); glGenBuffersARB(1, &indices_buffer_); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer_); @@ -837,8 +844,8 @@ glBufferData(GL_ARRAY_BUFFER, model->ElementsBufferSize(), model->ElementsBuffer(), GL_STATIC_DRAW); - glGenTextures(VrControllerModel::STATE_COUNT, texture_handles_.data()); - for (int i = 0; i < VrControllerModel::STATE_COUNT; i++) { + glGenTextures(ControllerMesh::STATE_COUNT, texture_handles_.data()); + for (int i = 0; i < ControllerMesh::STATE_COUNT; i++) { sk_sp<SkImage> texture = model->GetTexture(i); SkPixmap pixmap; if (!texture->peekPixels(&pixmap)) { @@ -871,7 +878,7 @@ setup_ = true; } -void ControllerRenderer::Draw(VrControllerModel::State state, +void ControllerRenderer::Draw(ControllerMesh::State state, float opacity, const gfx::Transform& view_proj_matrix) { glUseProgram(program_handle_); @@ -1098,6 +1105,25 @@ opacity); } +void VrShellRenderer::DrawController(ControllerMesh::State state, + float opacity, + const gfx::Transform& view_proj_matrix) { + if (!GetControllerRenderer()->IsSetUp()) { + return; + } + GetControllerRenderer()->Draw(state, opacity, view_proj_matrix); +} + +void VrShellRenderer::DrawLaser(float opacity, + const gfx::Transform& view_proj_matrix) { + GetLaserRenderer()->Draw(opacity, view_proj_matrix); +} + +void VrShellRenderer::DrawReticle(float opacity, + const gfx::Transform& view_proj_matrix) { + GetReticleRenderer()->Draw(opacity, view_proj_matrix); +} + ExternalTexturedQuadRenderer* VrShellRenderer::GetExternalTexturedQuadRenderer() { FlushIfNecessary(external_textured_quad_renderer_.get());
diff --git a/chrome/browser/vr/vr_shell_renderer.h b/chrome/browser/vr/vr_shell_renderer.h index 419df95..15b1e91 100644 --- a/chrome/browser/vr/vr_shell_renderer.h +++ b/chrome/browser/vr/vr_shell_renderer.h
@@ -10,8 +10,8 @@ #include "base/containers/queue.h" #include "base/macros.h" +#include "chrome/browser/vr/controller_mesh.h" #include "chrome/browser/vr/ui_element_renderer.h" -#include "chrome/browser/vr/vr_controller_model.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size_f.h" @@ -56,6 +56,15 @@ const SkColor grid_color, int gridline_count, float opacity) override; + void DrawController(ControllerMesh::State state, + float opacity, + const gfx::Transform& view_proj_matrix) override; + + void DrawLaser(float opacity, + const gfx::Transform& view_proj_matrix) override; + + void DrawReticle(float opacity, + const gfx::Transform& view_proj_matrix) override; // VrShell's internal GL rendering API. ExternalTexturedQuadRenderer* GetExternalTexturedQuadRenderer(); @@ -201,7 +210,7 @@ ReticleRenderer(); ~ReticleRenderer() override; - void Draw(const gfx::Transform& view_proj_matrix); + void Draw(float opacity, const gfx::Transform& view_proj_matrix); private: GLuint model_view_proj_matrix_handle_; @@ -212,6 +221,7 @@ GLuint inner_ring_thickness_handle_; GLuint mid_ring_end_handle_; GLuint mid_ring_opacity_handle_; + GLuint opacity_handle_; DISALLOW_COPY_AND_ASSIGN(ReticleRenderer); }; @@ -240,8 +250,8 @@ ControllerRenderer(); ~ControllerRenderer() override; - void SetUp(std::unique_ptr<VrControllerModel> model); - void Draw(VrControllerModel::State state, + void SetUp(std::unique_ptr<ControllerMesh> model); + void Draw(ControllerMesh::State state, float opacity, const gfx::Transform& view_proj_matrix); bool IsSetUp() const { return setup_; }
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_Big5_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_Big5_saved_from_no_encoding_specified.html index 1dea24b..016e4df 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_Big5_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_Big5_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0080)http://mock.http/encoding_tests/auto_detect/Big5_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=Big5"> <title> Big5 </title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_EUC-KR_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_EUC-KR_saved_from_no_encoding_specified.html index 161fac3..8ac0f96e 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_EUC-KR_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_EUC-KR_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0082)http://mock.http/encoding_tests/auto_detect/EUC-KR_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=EUC-KR"> <title> EUC-KR </title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_GBK_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_GBK_saved_from_no_encoding_specified.html index cdabea0..8d78ce5 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_GBK_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_GBK_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD Xhtml 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<!-- saved from url=(0079)http://mock.http/encoding_tests/auto_detect/GBK_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=GBK"> <title>ÖйúÖÆÔìµÄÁì¾üÕß3Ãû</title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-5_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-5_saved_from_no_encoding_specified.html index 4c15e6e..2f0d69f 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-5_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-5_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0086)http://mock.http/encoding_tests/auto_detect/ISO-8859-5_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-5"> <title> ISO-8859-5 </title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-6_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-6_saved_from_no_encoding_specified.html index 66e4052..d1bdd6fe1 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-6_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-6_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0086)http://mock.http/encoding_tests/auto_detect/ISO-8859-6_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-6"> <title> ISO-8859-6 </title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-7_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-7_saved_from_no_encoding_specified.html index 12da1fb5..35c3da1 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-7_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-7_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0086)http://mock.http/encoding_tests/auto_detect/ISO-8859-7_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-7"> <title> ISO-8859-7 </title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-8-I_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-8-I_saved_from_no_encoding_specified.html index de39f5a0..7ad794e 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-8-I_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_ISO-8859-8-I_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0088)http://mock.http/encoding_tests/auto_detect/ISO-8859-8-I_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1255"> <title> ISO-8859-8-I </title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_KOI8-R_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_KOI8-R_saved_from_no_encoding_specified.html index d1d8f9af..c5ba0b9f 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_KOI8-R_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_KOI8-R_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0082)http://mock.http/encoding_tests/auto_detect/KOI8-R_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=KOI8-R"> <title> KOI8-R </title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_Shift-JIS_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_Shift-JIS_saved_from_no_encoding_specified.html index 7b25aaa..81247ed2 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_Shift-JIS_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_Shift-JIS_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0085)http://mock.http/encoding_tests/auto_detect/Shift-JIS_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <title> Shift_JIS </title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_iso-8859-1_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_iso-8859-1_saved_from_no_encoding_specified.html index c647f3b..955f1d7 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_iso-8859-1_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_iso-8859-1_saved_from_no_encoding_specified.html
@@ -1,10 +1,10 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD html 4.01 Transitional//EN" "http://www.w3c.o rg/TR/1999/REC-html401-19991224/loose.dtd"> -<!-- saved from url=(0086)http://mock.http/encoding_tests/auto_detect/iso-8859-1_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html lang="en-US" xml:lang="en-US" xmlns="http://www.w3.org/1999/xhtml"><head profile="http://www.w3.org/2000/08/w3c-synd/#"><meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <title>iso-8859-1</title> </head> <body> -<h1 id="logo"><img height="48" alt="The World Wide Web Consortium (W3C)" src="http://mock.http/Icons/w3c_main" width="315"></h1> +<h1 id="logo"><img height="48" alt="The World Wide Web Consortium (W3C)" src="./sub_resource_files/w3c_main" width="315"></h1> <h2 id="slogan">Leading the Web to Its Full Potential...</h2> </body></html> \ No newline at end of file
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1251_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1251_saved_from_no_encoding_specified.html index 159cbc8..ede027a0 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1251_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1251_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0088)http://mock.http/encoding_tests/auto_detect/windows-1251_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <title> windows-1251 </title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1254_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1254_saved_from_no_encoding_specified.html index c4ae80d..64bbcbe 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1254_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1254_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0088)http://mock.http/encoding_tests/auto_detect/windows-1254_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1254"> <title> windows-1254 </title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1255_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1255_saved_from_no_encoding_specified.html index bfe6159..90a92a3 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1255_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1255_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0088)http://mock.http/encoding_tests/auto_detect/windows-1255_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1255"> <title> windows-1255 </title> </head>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1256_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1256_saved_from_no_encoding_specified.html index e684de3..98ea829 100644 --- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1256_saved_from_no_encoding_specified.html +++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_windows-1256_saved_from_no_encoding_specified.html
@@ -1,5 +1,5 @@ -<!-- saved from url=(0088)http://mock.http/encoding_tests/auto_detect/windows-1256_with_no_encoding_specified.html --> +<!-- saved from url=(%04d)%s --> <html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1256"> <title> windows-1256 </title> </head>
diff --git a/content/browser/frame_host/render_frame_message_filter.cc b/content/browser/frame_host/render_frame_message_filter.cc index 9e9a5e7..1f20a07 100644 --- a/content/browser/frame_host/render_frame_message_filter.cc +++ b/content/browser/frame_host/render_frame_message_filter.cc
@@ -442,7 +442,9 @@ void RenderFrameMessageFilter::SetCookie(int32_t render_frame_id, const GURL& url, const GURL& site_for_cookies, - const std::string& cookie) { + const std::string& cookie, + SetCookieCallback callback) { + std::move(callback).Run(); ChildProcessSecurityPolicyImpl* policy = ChildProcessSecurityPolicyImpl::GetInstance(); if (!policy->CanAccessDataForOrigin(render_process_id_, url)) {
diff --git a/content/browser/frame_host/render_frame_message_filter.h b/content/browser/frame_host/render_frame_message_filter.h index 95a8c39..9f4ecba 100644 --- a/content/browser/frame_host/render_frame_message_filter.h +++ b/content/browser/frame_host/render_frame_message_filter.h
@@ -127,7 +127,8 @@ void SetCookie(int32_t render_frame_id, const GURL& url, const GURL& site_for_cookies, - const std::string& cookie) override; + const std::string& cookie, + SetCookieCallback callback) override; void GetCookies(int render_frame_id, const GURL& url, const GURL& site_for_cookies,
diff --git a/content/browser/frame_host/render_frame_message_filter_browsertest.cc b/content/browser/frame_host/render_frame_message_filter_browsertest.cc index aeda684..f743a84 100644 --- a/content/browser/frame_host/render_frame_message_filter_browsertest.cc +++ b/content/browser/frame_host/render_frame_message_filter_browsertest.cc
@@ -4,6 +4,8 @@ #include <string> +#include "base/bind.h" +#include "base/bind_helpers.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/test/histogram_tester.h" @@ -234,10 +236,11 @@ ->PostTask(FROM_HERE, base::BindOnce( [](RenderFrameHost* frame) { GetFilterForProcess(frame->GetProcess()) - ->SetCookie(frame->GetRoutingID(), - GURL("https://baz.com/"), - GURL("https://baz.com/"), - "pwn=ed"); + ->SetCookie( + frame->GetRoutingID(), + GURL("https://baz.com/"), + GURL("https://baz.com/"), "pwn=ed", + base::BindOnce(&base::DoNothing)); }, main_frame));
diff --git a/content/common/render_frame_message_filter.mojom b/content/common/render_frame_message_filter.mojom index 5bbf05e..0a9f158 100644 --- a/content/common/render_frame_message_filter.mojom +++ b/content/common/render_frame_message_filter.mojom
@@ -7,10 +7,13 @@ import "url/mojo/url.mojom"; interface RenderFrameMessageFilter { - // Sets a cookie. The cookie is set asynchronously, but will be available to - // any subsequent GetCookies() request. + // Sets a cookie. Returns after the cookie write request has been scheduled on + // the IO thread (the database is modified asynchronously). This ensures that + // network requests issued after the cookie setter call are processed after + // the cookie change is committed, and therefore see the change. + [Sync] SetCookie(int32 render_frame_id, url.mojom.Url url, - url.mojom.Url first_party_for_cookies, string cookie); + url.mojom.Url first_party_for_cookies, string cookie) => (); // Used to get cookies for the given URL. This may block waiting for a // previous SetCookie message to be processed.
diff --git a/content/renderer/renderer_webcookiejar_impl.cc b/content/renderer/renderer_webcookiejar_impl.cc index fc25e80..4c22634 100644 --- a/content/renderer/renderer_webcookiejar_impl.cc +++ b/content/renderer/renderer_webcookiejar_impl.cc
@@ -4,6 +4,8 @@ #include "content/renderer/renderer_webcookiejar_impl.h" +#include "base/bind.h" +#include "base/bind_helpers.h" #include "base/strings/utf_string_conversions.h" #include "content/common/frame_messages.h" #include "content/public/renderer/content_renderer_client.h" @@ -21,7 +23,8 @@ std::string value_utf8 = value.Utf8(WebString::UTF8ConversionMode::kStrictReplacingErrorsWithFFFD); RenderThreadImpl::current()->render_frame_message_filter()->SetCookie( - sender_->GetRoutingID(), url, site_for_cookies, value_utf8); + sender_->GetRoutingID(), url, site_for_cookies, value_utf8, + base::BindOnce(&base::DoNothing)); } WebString RendererWebCookieJarImpl::Cookies(const WebURL& url,
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter index fd345df3..30cb5cc 100644 --- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -2384,7 +2384,6 @@ -BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithOffTheRecordDownloads/1 -BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithOffTheRecordWindowAndRegularDownload/0 -BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithOffTheRecordWindowAndRegularDownload/1 --BrowserEncodingTest.TestEncodingAutoDetect -CaptivePortalBrowserTest.AbortLoad -CaptivePortalBrowserTest.CloseLoginTab -CaptivePortalBrowserTest.Disabled @@ -2539,35 +2538,6 @@ -DownloadTest.UnknownSize -DownloadTestWithFakeSafeBrowsing.NoUncommonDownloadReportWithoutUserProceed -DownloadTestWithFakeSafeBrowsing.SendUncommonDownloadReportIfUserProceed --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/0 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/1 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/10 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/11 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/12 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/13 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/14 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/15 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/16 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/18 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/19 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/2 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/20 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/21 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/22 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/23 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/24 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/25 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/26 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/27 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/28 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/29 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/3 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/4 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/5 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/6 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/7 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/8 --EncodingAliases/BrowserEncodingTest.TestEncodingAliasMapping/9 -ErrorPageAutoReloadTest.AutoReload -ErrorPageAutoReloadTest.IgnoresSameDocumentNavigation -ErrorPageAutoReloadTest.ManualReloadNotSuppressed
diff --git a/third_party/WebKit/Source/core/loader/CookieJar.cpp b/third_party/WebKit/Source/core/loader/CookieJar.cpp index d8c6708c..33595464 100644 --- a/third_party/WebKit/Source/core/loader/CookieJar.cpp +++ b/third_party/WebKit/Source/core/loader/CookieJar.cpp
@@ -61,6 +61,7 @@ WebCookieJar* cookie_jar = ToCookieJar(document); if (!cookie_jar) return; + SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Blink.CookieJar.SyncCookiesSetTime"); cookie_jar->SetCookie(url, document->SiteForCookies(), cookie_string); }
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py index 1dede1d..8bab466a 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
@@ -470,8 +470,15 @@ description += 'Build: %s\n\n' % build_link description += ( - 'Note to sheriffs: This is an automatically-generated CL. Please\n' - 'contact ecosystem-infra@chromium.org in case of problems.\n\n') + 'Note to sheriffs: This CL imports external tests and adds\n' + 'expectations for those tests; if this CL is large and causes\n' + 'a few new failures, please fix the failures by adding new\n' + 'lines to TestExpectations rather than reverting. See:\n' + 'https://chromium.googlesource.com' + '/chromium/src/+/master/docs/testing/web_platform_tests.md\n\n') + + if directory_owners: + description += self._format_directory_owners(directory_owners) + '\n\n' # Move any No-Export tag to the end of the description. description = description.replace('No-Export: true', '')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py index 44d891c..0015fc6 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
@@ -4,7 +4,6 @@ import datetime import json -import unittest from webkitpy.common.checkout.git_mock import MockGit from webkitpy.common.host_mock import MockHost @@ -268,8 +267,12 @@ self.assertEqual( description, 'Last commit message\n\n' - 'Note to sheriffs: This is an automatically-generated CL. Please\n' - 'contact ecosystem-infra@chromium.org in case of problems.\n\n' + 'Note to sheriffs: This CL imports external tests and adds\n' + 'expectations for those tests; if this CL is large and causes\n' + 'a few new failures, please fix the failures by adding new\n' + 'lines to TestExpectations rather than reverting. See:\n' + 'https://chromium.googlesource.com' + '/chromium/src/+/master/docs/testing/web_platform_tests.md\n\n' 'No-Export: true') self.assertEqual(host.executive.calls, [['git', 'log', '-1', '--format=%B']]) @@ -295,7 +298,6 @@ 'No-Export: true', description) - @unittest.skip("http://crbug.com/780055") def test_cl_description_with_directory_owners(self): host = MockHost() host.executive = MockExecutive(output='Last commit message\n\n')
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 464b6766..4f5e1c8 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -6572,6 +6572,12 @@ </summary> </histogram> +<histogram name="Blink.CookieJar.SyncCookiesSetTime" units="microseconds"> + <owner>kinuko@chromium.org</owner> + <owner>dcheng@chromium.org</owner> + <summary>Microseconds per sync IPC call to set cookies.</summary> +</histogram> + <histogram name="Blink.CookieJar.SyncCookiesTime" units="microseconds"> <owner>kinuko@chromium.org</owner> <owner>dcheng@chromium.org</owner>