blob: 94cb73ddfed3684e18d211f1aaf660b40381db39 [file] [log] [blame]
// 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