1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/environment.h"
6 #include "base/files/file.h"
7 #include "base/run_loop.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/threading/thread_restrictions.h"
10 #include "chrome/browser/vr/test/mock_xr_device_hook_base.h"
11 #include "chrome/browser/vr/test/multi_class_browser_test.h"
12 #include "chrome/browser/vr/test/ui_utils.h"
13 #include "chrome/browser/vr/test/webxr_vr_browser_test.h"
14
15 #include <memory>
16
17 namespace vr {
18
19 class MyXRMock : public MockXRDeviceHookBase {
20 public:
21 void OnFrameSubmitted(
22 device_test::mojom::SubmittedFrameDataPtr frame_data,
23 device_test::mojom::XRTestHook::OnFrameSubmittedCallback callback) final;
24
WaitForFrame()25 void WaitForFrame() {
26 DCHECK(!wait_loop_);
27 if (num_submitted_frames_ > 0)
28 return;
29
30 wait_loop_ = new base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed);
31 wait_loop_->Run();
32 delete wait_loop_;
33 wait_loop_ = nullptr;
34 }
35
36 device_test::mojom::ColorPtr last_submitted_color_ = {};
37 unsigned int num_submitted_frames_ = 0;
38
39 private:
40 base::RunLoop* wait_loop_ = nullptr;
41 };
42
OnFrameSubmitted(device_test::mojom::SubmittedFrameDataPtr frame_data,device_test::mojom::XRTestHook::OnFrameSubmittedCallback callback)43 void MyXRMock::OnFrameSubmitted(
44 device_test::mojom::SubmittedFrameDataPtr frame_data,
45 device_test::mojom::XRTestHook::OnFrameSubmittedCallback callback) {
46 last_submitted_color_ = std::move(frame_data->color);
47 num_submitted_frames_++;
48
49 if (wait_loop_) {
50 wait_loop_->Quit();
51 }
52
53 std::move(callback).Run();
54 }
55
56 // Pixel test for WebXR - start presentation, submit frames, get data back
57 // out. Validates that a pixel was rendered with the expected color.
TestPresentationPixelsImpl(WebXrVrBrowserTestBase * t,std::string filename)58 void TestPresentationPixelsImpl(WebXrVrBrowserTestBase* t,
59 std::string filename) {
60 // Disable frame-timeout UI to test what WebXR renders.
61 UiUtils::DisableFrameTimeoutForTesting();
62 MyXRMock my_mock;
63
64 // Load the test page, and enter presentation.
65 t->LoadFileAndAwaitInitialization(filename);
66 t->EnterSessionWithUserGestureOrFail();
67
68 // Wait for JavaScript to submit at least one frame.
69 ASSERT_TRUE(
70 t->PollJavaScriptBoolean("hasPresentedFrame", t->kPollTimeoutMedium))
71 << "No frame submitted";
72
73 // Tell JavaScript that it is done with the test.
74 t->ExecuteStepAndWait("finishTest()");
75 t->EndTest();
76
77 my_mock.WaitForFrame();
78
79 auto expected = device_test::mojom::Color::New(0, 0, 255, 255);
80 EXPECT_EQ(expected->r, my_mock.last_submitted_color_->r)
81 << "Red channel of submitted color does not match expectation";
82 EXPECT_EQ(expected->g, my_mock.last_submitted_color_->g)
83 << "Green channel of submitted color does not match expectation";
84 EXPECT_EQ(expected->b, my_mock.last_submitted_color_->b)
85 << "Blue channel of submitted color does not match expectation";
86 EXPECT_EQ(expected->a, my_mock.last_submitted_color_->a)
87 << "Alpha channel of submitted color does not match expectation";
88 }
89
WEBXR_VR_ALL_RUNTIMES_BROWSER_TEST_F(TestPresentationPixels)90 WEBXR_VR_ALL_RUNTIMES_BROWSER_TEST_F(TestPresentationPixels) {
91 TestPresentationPixelsImpl(t, "test_webxr_pixels");
92 }
93
94 } // namespace vr
95