1 // Copyright 2020 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 "components/viz/service/display_embedder/software_output_device_win.h"
6 
7 #include "base/memory/unsafe_shared_memory_region.h"
8 #include "base/test/gmock_callback_support.h"
9 #include "components/viz/common/resources/resource_sizes.h"
10 #include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 using base::test::RunOnceClosure;
15 using testing::_;
16 
17 namespace viz {
18 namespace {
19 
20 constexpr gfx::Size kDefaultSize(100, 100);
21 
22 class MockLayeredWindowUpdater : public mojom::LayeredWindowUpdater {
23  public:
24   MockLayeredWindowUpdater() = default;
25   ~MockLayeredWindowUpdater() override = default;
26 
BindNewPipeAndPassRemote()27   mojo::PendingRemote<mojom::LayeredWindowUpdater> BindNewPipeAndPassRemote() {
28     return receiver_.BindNewPipeAndPassRemote();
29   }
30 
FlushForTesting()31   void FlushForTesting() { receiver_.FlushForTesting(); }
32 
33   // mojom::LayeredWindowUpdater implementation.
34   MOCK_METHOD(void,
35               OnAllocatedSharedMemory,
36               (const gfx::Size& size,
37                base::UnsafeSharedMemoryRegion memory_region),
38               (override));
39   MOCK_METHOD(void, Draw, (DrawCallback), (override));
40 
41  private:
42   mojo::Receiver<mojom::LayeredWindowUpdater> receiver_{this};
43 };
44 
45 }  // namespace
46 
47 class SoftwareOutputDeviceWinProxyTest : public testing::Test {
48  public:
SoftwareOutputDeviceWinProxyTest()49   SoftwareOutputDeviceWinProxyTest()
50       : device_(0, updater_.BindNewPipeAndPassRemote()) {}
51 
SetUp()52   void SetUp() override {
53     // Check that calling Resize() results in the allocation of shared memory
54     // and triggers the OnAllocatedSharedMemory() IPC.
55     EXPECT_CALL(updater_, OnAllocatedSharedMemory(kDefaultSize, _))
56         .WillOnce(
57             testing::WithArg<1>([](base::UnsafeSharedMemoryRegion region) {
58               EXPECT_TRUE(region.IsValid());
59               size_t required_bytes = ResourceSizes::CheckedSizeInBytes<size_t>(
60                   kDefaultSize, ResourceFormat::RGBA_8888);
61               EXPECT_GE(region.GetSize(), required_bytes);
62             }));
63     device_.Resize(kDefaultSize, 1.0f);
64     updater_.FlushForTesting();
65     testing::Mock::VerifyAndClearExpectations(&updater_);
66   }
67 
68  protected:
69   MockLayeredWindowUpdater updater_;
70   SoftwareOutputDeviceWinProxy device_;
71 };
72 
TEST_F(SoftwareOutputDeviceWinProxyTest,DrawWithSwap)73 TEST_F(SoftwareOutputDeviceWinProxyTest, DrawWithSwap) {
74   // Verify that calling BeginPaint() then EndPaint() triggers the Draw() IPC
75   // and then run the DrawCallback.
76   device_.BeginPaint(gfx::Rect(kDefaultSize));
77   EXPECT_CALL(updater_, Draw(_)).WillOnce(RunOnceClosure<0>());
78   device_.EndPaint();
79   updater_.FlushForTesting();
80   testing::Mock::VerifyAndClearExpectations(&updater_);
81 
82   // OnSwapBuffers() is called before DrawAck() so the swap buffers callback
83   // shouldn't run yet.
84   bool called = false;
85   device_.OnSwapBuffers(base::BindOnce(
86       [](bool* val, const gfx::Size& size) { *val = true; }, &called));
87   EXPECT_FALSE(called);
88 
89   // Verify that DrawAck() runs the swap buffers callback.
90   updater_.FlushForTesting();
91   EXPECT_TRUE(called);
92 }
93 
TEST_F(SoftwareOutputDeviceWinProxyTest,DrawNoSwap)94 TEST_F(SoftwareOutputDeviceWinProxyTest, DrawNoSwap) {
95   // Verify that calling BeginPaint() then EndPaint() triggers the Draw() IPC
96   // and then run the DrawCallback.
97   device_.BeginPaint(gfx::Rect(kDefaultSize));
98   EXPECT_CALL(updater_, Draw(_)).WillOnce(RunOnceClosure<0>());
99   device_.EndPaint();
100   updater_.FlushForTesting();
101   testing::Mock::VerifyAndClearExpectations(&updater_);
102 
103   // DrawAck() will be triggered after this second flush when the IPC response
104   // arrives. OnSwapBuffers() was never called which is allowed.
105   updater_.FlushForTesting();
106 }
107 
108 }  // namespace viz
109