| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/vr/browser_renderer.h" |
| |
| #include "base/memory/raw_ptr.h" |
| #include "base/notreached.h" |
| #include "chrome/browser/vr/graphics_delegate.h" |
| #include "chrome/browser/vr/render_info.h" |
| #include "chrome/browser/vr/test/mock_browser_ui_interface.h" |
| #include "chrome/browser/vr/ui_interface.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| |
| using ::testing::_; |
| using ::testing::Return; |
| |
| namespace vr { |
| |
| class MockUi : public UiInterface { |
| public: |
| MockUi() = default; |
| ~MockUi() override = default; |
| |
| base::WeakPtr<BrowserUiInterface> GetBrowserUiWeakPtr() override { |
| return nullptr; |
| } |
| SchedulerUiInterface* GetSchedulerUiPtr() override { return nullptr; } |
| MOCK_METHOD0(OnGlInitialized, void()); |
| MOCK_METHOD2(GetTargetPointForTesting, |
| gfx::Point3F(UserFriendlyElementName, |
| const gfx::PointF& position)); |
| MOCK_METHOD1(GetElementVisibility, bool(UserFriendlyElementName)); |
| MOCK_METHOD2(OnBeginFrame, bool(base::TimeTicks, const gfx::Transform&)); |
| MOCK_CONST_METHOD0(SceneHasDirtyTextures, bool()); |
| MOCK_METHOD0(UpdateSceneTextures, void()); |
| MOCK_METHOD1(Draw, void(const RenderInfo&)); |
| MOCK_METHOD1(DrawWebVrOverlayForeground, void(const RenderInfo&)); |
| MOCK_METHOD0(HasWebXrOverlayElementsToDraw, bool()); |
| FovRectangles GetMinimalFovForWebXrOverlayElements(const gfx::Transform&, |
| const FovRectangle&, |
| const gfx::Transform&, |
| const FovRectangle&, |
| float) override { |
| return {}; |
| } |
| }; |
| |
| class MockGraphicsDelegate : public GraphicsDelegate { |
| public: |
| MockGraphicsDelegate() = default; |
| ~MockGraphicsDelegate() override = default; |
| |
| bool using_buffer() { return using_buffer_; } |
| |
| // GraphicsDelegate |
| void Initialize(base::OnceClosure on_initialized) override { |
| std::move(on_initialized).Run(); |
| } |
| bool PreRender() override { return true; } |
| void PostRender() override {} |
| gfx::GpuMemoryBufferHandle GetTexture() override { NOTREACHED(); } |
| gpu::SyncToken GetSyncToken() override { NOTREACHED(); } |
| void ResetMemoryBuffer() override {} |
| bool BindContext() override { return true; } |
| void ClearContext() override {} |
| void ClearBufferToBlack() override {} |
| |
| private: |
| void UseBuffer() { |
| CHECK(!using_buffer_); |
| using_buffer_ = true; |
| } |
| bool using_buffer_ = false; |
| }; |
| |
| std::vector<device::mojom::XRViewPtr> GetDefaultViews() { |
| int x_offset = 0; |
| static int width = 128; |
| static int height = 128; |
| |
| auto left = device::mojom::XRView::New(); |
| left->eye = device::mojom::XREye::kLeft; |
| left->viewport = gfx::Rect(x_offset, 0, width, height); |
| left->geometry = device::mojom::XRViewGeometry::New(); |
| left->geometry->field_of_view = |
| device::mojom::VRFieldOfView::New(45.0f, 45.0f, 45.0f, 45.0f); |
| x_offset += width; |
| |
| auto right = device::mojom::XRView::New(); |
| right->eye = device::mojom::XREye::kRight; |
| right->viewport = gfx::Rect(x_offset, 0, width, height); |
| right->geometry = device::mojom::XRViewGeometry::New(); |
| right->geometry->field_of_view = |
| device::mojom::VRFieldOfView::New(45.0f, 45.0f, 45.0f, 45.0f); |
| |
| std::vector<device::mojom::XRViewPtr> views; |
| views.push_back(std::move(left)); |
| views.push_back(std::move(right)); |
| |
| return views; |
| } |
| |
| class BrowserRendererTest : public testing::Test { |
| public: |
| struct BuildParams { |
| std::unique_ptr<MockUi> ui; |
| std::unique_ptr<MockGraphicsDelegate> graphics_delegate; |
| }; |
| |
| void SetUp() override { |
| auto ui = std::make_unique<MockUi>(); |
| build_params_ = { |
| std::make_unique<MockUi>(), |
| std::make_unique<MockGraphicsDelegate>(), |
| }; |
| ui_ = build_params_.ui.get(); |
| graphics_delegate_ = build_params_.graphics_delegate.get(); |
| graphics_delegate_->SetXrViews(GetDefaultViews()); |
| } |
| |
| std::unique_ptr<BrowserRenderer> CreateBrowserRenderer() { |
| return std::make_unique<BrowserRenderer>( |
| std::move(build_params_.ui), |
| std::move(build_params_.graphics_delegate), |
| 1 /* sliding_time_size */); |
| } |
| |
| protected: |
| raw_ptr<MockUi, DanglingUntriaged> ui_; |
| raw_ptr<MockGraphicsDelegate, DanglingUntriaged> graphics_delegate_; |
| |
| private: |
| BuildParams build_params_; |
| }; |
| |
| TEST_F(BrowserRendererTest, DrawWebXrFrameNoOverlay) { |
| testing::Sequence s; |
| auto browser_renderer = CreateBrowserRenderer(); |
| EXPECT_CALL(*ui_, SceneHasDirtyTextures()).WillOnce(Return(false)); |
| EXPECT_CALL(*ui_, UpdateSceneTextures).Times(0); |
| EXPECT_CALL(*ui_, HasWebXrOverlayElementsToDraw()).WillOnce(Return(false)); |
| |
| EXPECT_CALL(*ui_, OnBeginFrame(_, _)).Times(1).InSequence(s); |
| EXPECT_CALL(*ui_, Draw(_)).Times(0); |
| EXPECT_CALL(*ui_, DrawWebVrOverlayForeground(_)).Times(0); |
| // TODO: Replace this with something to validate that a call happened. |
| // EXPECT_CALL(*scheduler_delegate_, SubmitDrawnFrame(kWebXrFrame, _)) |
| // .Times(1) |
| // .InSequence(s); |
| |
| browser_renderer->DrawWebXrFrame(base::TimeTicks(), {}); |
| EXPECT_FALSE(graphics_delegate_->using_buffer()); |
| } |
| |
| TEST_F(BrowserRendererTest, DrawWebXrFrameWithOverlay) { |
| testing::Sequence s; |
| auto browser_renderer = CreateBrowserRenderer(); |
| EXPECT_CALL(*ui_, SceneHasDirtyTextures()).WillOnce(Return(false)); |
| EXPECT_CALL(*ui_, UpdateSceneTextures).Times(0); |
| EXPECT_CALL(*ui_, HasWebXrOverlayElementsToDraw()).WillOnce(Return(true)); |
| |
| EXPECT_CALL(*ui_, OnBeginFrame(_, _)).Times(1).InSequence(s); |
| EXPECT_CALL(*ui_, Draw(_)).Times(0); |
| EXPECT_CALL(*ui_, DrawWebVrOverlayForeground(_)).Times(1).InSequence(s); |
| // TODO: Replace this with something to validate that a call happened. |
| // EXPECT_CALL(*scheduler_delegate_, SubmitDrawnFrame(kWebXrFrame, _)) |
| // .Times(1) |
| // .InSequence(s); |
| |
| browser_renderer->DrawWebXrFrame(base::TimeTicks(), {}); |
| EXPECT_FALSE(graphics_delegate_->using_buffer()); |
| } |
| |
| } // namespace vr |