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 "components/viz/service/display_embedder/output_device_backing.h"
6 
7 #include <limits>
8 #include <memory>
9 
10 #include "components/viz/common/resources/resource_sizes.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 
13 namespace viz {
14 namespace {
15 
GetViewportSizeInBytes(const gfx::Size & viewport_size)16 size_t GetViewportSizeInBytes(const gfx::Size& viewport_size) {
17   size_t bytes = std::numeric_limits<size_t>::max();
18   CHECK(ResourceSizes::MaybeSizeInBytes(viewport_size, RGBA_8888, &bytes));
19   return bytes;
20 }
21 
22 // Test implementation with a set viewport size.
23 class TestBackingClient : public OutputDeviceBacking::Client {
24  public:
TestBackingClient(OutputDeviceBacking * backing,const gfx::Size & viewport_size)25   TestBackingClient(OutputDeviceBacking* backing,
26                     const gfx::Size& viewport_size)
27       : backing_(backing), viewport_size_(viewport_size) {
28     backing_->RegisterClient(this);
29     backing_->ClientResized();
30     backing_->GetSharedMemoryRegion(viewport_size_);
31   }
~TestBackingClient()32   ~TestBackingClient() override { backing_->UnregisterClient(this); }
33 
viewport_size() const34   const gfx::Size& viewport_size() const { return viewport_size_; }
release_canvas_called() const35   bool release_canvas_called() const { return release_canvas_called_; }
36 
37   // OutputDeviceBacking::Client implementation.
GetViewportPixelSize() const38   const gfx::Size& GetViewportPixelSize() const override {
39     return viewport_size_;
40   }
ReleaseCanvas()41   void ReleaseCanvas() override { release_canvas_called_ = true; }
42 
43  private:
44   OutputDeviceBacking* const backing_;
45   gfx::Size viewport_size_;
46   bool release_canvas_called_ = false;
47 
48   DISALLOW_COPY_AND_ASSIGN(TestBackingClient);
49 };
50 
51 }  // namespace
52 
53 // Verify GetMaxViewportBytes() returns the size in bytes of the largest
54 // viewport.
TEST(OutputDeviceBackingTest,GetMaxViewportBytes)55 TEST(OutputDeviceBackingTest, GetMaxViewportBytes) {
56   OutputDeviceBacking backing;
57   TestBackingClient client_a(&backing, gfx::Size(1024, 768));
58   TestBackingClient client_b(&backing, gfx::Size(1920, 1080));
59 
60   EXPECT_EQ(GetViewportSizeInBytes(client_b.viewport_size()),
61             backing.GetMaxViewportBytes());
62 }
63 
64 // Verify that unregistering a client works as expected.
TEST(OutputDeviceBackingTest,UnregisterClient)65 TEST(OutputDeviceBackingTest, UnregisterClient) {
66   OutputDeviceBacking backing;
67   auto client_a =
68       std::make_unique<TestBackingClient>(&backing, gfx::Size(1920, 1080));
69   auto client_b =
70       std::make_unique<TestBackingClient>(&backing, gfx::Size(1080, 1920));
71   auto client_c =
72       std::make_unique<TestBackingClient>(&backing, gfx::Size(1024, 768));
73 
74   // Unregister one of the clients with the 1920x1080 viewport size.
75   client_a.reset();
76 
77   // After removing |client_a| the max viewport didn't change so ReleaseCanvas()
78   // shouldn't be have been called.
79   EXPECT_FALSE(client_b->release_canvas_called());
80   EXPECT_FALSE(client_c->release_canvas_called());
81 
82   // Unregister the second client with 1920x1080 viewport.
83   client_b.reset();
84 
85   // After removing |client_b| then max viewport did change so ReleaseCanvas()
86   // should have been called.
87   EXPECT_TRUE(client_c->release_canvas_called());
88 
89   EXPECT_EQ(GetViewportSizeInBytes(client_c->viewport_size()),
90             backing.GetMaxViewportBytes());
91 }
92 
93 // Verify that a client with a viewport that is too large doesn't allocate
94 // SharedMemory.
TEST(OutputDeviceBackingTest,ViewportSizeBiggerThanMax)95 TEST(OutputDeviceBackingTest, ViewportSizeBiggerThanMax) {
96   OutputDeviceBacking backing;
97 
98   // The viewport is bigger than |kMaxBitmapSizeBytes| and OutputDeviceBacking
99   // won't try to create a shared memory region for it.
100   TestBackingClient client_a(&backing, gfx::Size(16385, 8193));
101   EXPECT_EQ(nullptr, backing.GetSharedMemoryRegion(client_a.viewport_size()));
102 
103   // This should cause a region to get allocated.
104   TestBackingClient client_b(&backing, gfx::Size(1024, 768));
105   EXPECT_NE(nullptr, backing.GetSharedMemoryRegion(client_b.viewport_size()));
106 
107   // Even though SharedMemory was allocated to fit |client_b|, it will be too
108   // small for |client_a| and GetSharedMemoryRegion() should still return null.
109   EXPECT_EQ(nullptr, backing.GetSharedMemoryRegion(client_a.viewport_size()));
110 }
111 
112 }  // namespace viz
113