Flutter Engine
surface_pool_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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 <memory>
6 #include "flutter/shell/platform/android/external_view_embedder/surface_pool.h"
7 
8 #include "flutter/fml/make_copyable.h"
9 #include "flutter/shell/platform/android/jni/jni_mock.h"
10 #include "flutter/shell/platform/android/surface/android_surface_mock.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13 #include "third_party/skia/include/gpu/GrDirectContext.h"
14 
15 namespace flutter {
16 namespace testing {
17 
18 using ::testing::ByMove;
19 using ::testing::Return;
20 
21 class TestAndroidSurfaceFactory : public AndroidSurfaceFactory {
22  public:
23  using TestSurfaceProducer =
24  std::function<std::unique_ptr<AndroidSurface>(void)>;
25  explicit TestAndroidSurfaceFactory(TestSurfaceProducer&& surface_producer) {
26  surface_producer_ = surface_producer;
27  }
28 
29  ~TestAndroidSurfaceFactory() override = default;
30 
31  std::unique_ptr<AndroidSurface> CreateSurface() override {
32  return surface_producer_();
33  }
34 
35  private:
36  TestSurfaceProducer surface_producer_;
37 };
38 
39 TEST(SurfacePool, GetLayer__AllocateOneLayer) {
40  auto pool = std::make_unique<SurfacePool>();
41 
42  auto gr_context = GrDirectContext::MakeMock(nullptr);
43  auto android_context =
44  std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
45 
46  auto jni_mock = std::make_shared<JNIMock>();
47  auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
48  EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
49  .WillOnce(Return(
50  ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
51  0, window))));
52 
53  auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
54  [&android_context, gr_context, window]() {
55  auto android_surface_mock =
56  std::make_unique<AndroidSurfaceMock>(android_context);
57  EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
58  EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
59  EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
60  return android_surface_mock;
61  });
62  auto layer = pool->GetLayer(gr_context.get(), *android_context, jni_mock,
63  surface_factory);
64 
65  ASSERT_NE(nullptr, layer);
66  ASSERT_EQ(reinterpret_cast<intptr_t>(gr_context.get()),
67  layer->gr_context_key);
68 }
69 
70 TEST(SurfacePool, GetUnusedLayers) {
71  auto pool = std::make_unique<SurfacePool>();
72 
73  auto gr_context = GrDirectContext::MakeMock(nullptr);
74  auto android_context =
75  std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
76 
77  auto jni_mock = std::make_shared<JNIMock>();
78  auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
79  EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
80  .WillOnce(Return(
81  ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
82  0, window))));
83 
84  auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
85  [&android_context, gr_context, window]() {
86  auto android_surface_mock =
87  std::make_unique<AndroidSurfaceMock>(android_context);
88  EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
89  EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
90  EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
91  return android_surface_mock;
92  });
93  auto layer = pool->GetLayer(gr_context.get(), *android_context, jni_mock,
94  surface_factory);
95  ASSERT_EQ(0UL, pool->GetUnusedLayers().size());
96 
97  pool->RecycleLayers();
98 
99  ASSERT_EQ(1UL, pool->GetUnusedLayers().size());
100  ASSERT_EQ(layer, pool->GetUnusedLayers()[0]);
101 }
102 
103 TEST(SurfacePool, GetLayer__Recycle) {
104  auto pool = std::make_unique<SurfacePool>();
105 
106  auto gr_context_1 = GrDirectContext::MakeMock(nullptr);
107  auto jni_mock = std::make_shared<JNIMock>();
108  auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
109  EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
110  .WillOnce(Return(
111  ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
112  0, window))));
113 
114  auto android_context =
115  std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
116 
117  auto gr_context_2 = GrDirectContext::MakeMock(nullptr);
118  auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
119  [&android_context, gr_context_1, gr_context_2, window]() {
120  auto android_surface_mock =
121  std::make_unique<AndroidSurfaceMock>(android_context);
122  // Allocate two GPU surfaces for each gr context.
123  EXPECT_CALL(*android_surface_mock,
124  CreateGPUSurface(gr_context_1.get()));
125  EXPECT_CALL(*android_surface_mock,
126  CreateGPUSurface(gr_context_2.get()));
127  // Set the native window once.
128  EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
129  EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
130  return android_surface_mock;
131  });
132  auto layer_1 = pool->GetLayer(gr_context_1.get(), *android_context, jni_mock,
133  surface_factory);
134 
135  pool->RecycleLayers();
136 
137  auto layer_2 = pool->GetLayer(gr_context_2.get(), *android_context, jni_mock,
138  surface_factory);
139 
140  ASSERT_NE(nullptr, layer_1);
141  ASSERT_EQ(layer_1, layer_2);
142  ASSERT_EQ(reinterpret_cast<intptr_t>(gr_context_2.get()),
143  layer_1->gr_context_key);
144  ASSERT_EQ(reinterpret_cast<intptr_t>(gr_context_2.get()),
145  layer_2->gr_context_key);
146 }
147 
148 TEST(SurfacePool, GetLayer__AllocateTwoLayers) {
149  auto pool = std::make_unique<SurfacePool>();
150 
151  auto gr_context = GrDirectContext::MakeMock(nullptr);
152  auto android_context =
153  std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
154 
155  auto jni_mock = std::make_shared<JNIMock>();
156  auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
157  EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
158  .Times(2)
159  .WillOnce(Return(
160  ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
161  0, window))))
162  .WillOnce(Return(
163  ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
164  1, window))));
165 
166  auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
167  [&android_context, gr_context, window]() {
168  auto android_surface_mock =
169  std::make_unique<AndroidSurfaceMock>(android_context);
170  EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
171  EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
172  EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
173  return android_surface_mock;
174  });
175  auto layer_1 = pool->GetLayer(gr_context.get(), *android_context, jni_mock,
176  surface_factory);
177  auto layer_2 = pool->GetLayer(gr_context.get(), *android_context, jni_mock,
178  surface_factory);
179  ASSERT_NE(nullptr, layer_1);
180  ASSERT_NE(nullptr, layer_2);
181  ASSERT_NE(layer_1, layer_2);
182  ASSERT_EQ(0, layer_1->id);
183  ASSERT_EQ(1, layer_2->id);
184 }
185 
186 TEST(SurfacePool, DestroyLayers) {
187  auto pool = std::make_unique<SurfacePool>();
188  auto jni_mock = std::make_shared<JNIMock>();
189 
190  EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(0);
191  pool->DestroyLayers(jni_mock);
192 
193  auto gr_context = GrDirectContext::MakeMock(nullptr);
194  auto android_context =
195  std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
196 
197  auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
198  EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
199  .Times(1)
200  .WillOnce(Return(
201  ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
202  0, window))));
203 
204  auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
205  [&android_context, gr_context, window]() {
206  auto android_surface_mock =
207  std::make_unique<AndroidSurfaceMock>(android_context);
208  EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
209  EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
210  EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
211  return android_surface_mock;
212  });
213  pool->GetLayer(gr_context.get(), *android_context, jni_mock, surface_factory);
214 
215  EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces());
216  pool->DestroyLayers(jni_mock);
217 
218  pool->RecycleLayers();
219  ASSERT_TRUE(pool->GetUnusedLayers().empty());
220 }
221 
222 TEST(SurfacePool, DestroyLayers__frameSizeChanged) {
223  auto pool = std::make_unique<SurfacePool>();
224  auto jni_mock = std::make_shared<JNIMock>();
225 
226  auto gr_context = GrDirectContext::MakeMock(nullptr);
227  auto android_context =
228  std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
229 
230  auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
231 
232  auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
233  [&android_context, gr_context, window]() {
234  auto android_surface_mock =
235  std::make_unique<AndroidSurfaceMock>(android_context);
236  EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
237  EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
238  EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
239  return android_surface_mock;
240  });
241  pool->SetFrameSize(SkISize::Make(10, 10));
242  EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(0);
243  EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
244  .Times(1)
245  .WillOnce(Return(
246  ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
247  0, window))));
248 
249  pool->GetLayer(gr_context.get(), *android_context, jni_mock, surface_factory);
250 
251  pool->SetFrameSize(SkISize::Make(20, 20));
252  EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(1);
253  EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
254  .Times(1)
255  .WillOnce(Return(
256  ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
257  1, window))));
258  pool->GetLayer(gr_context.get(), *android_context, jni_mock, surface_factory);
259 
260  ASSERT_TRUE(pool->GetUnusedLayers().empty());
261 }
262 
263 } // namespace testing
264 } // namespace flutter
std::unique_ptr< AndroidSurface > CreateSurface() override
TestAndroidSurfaceFactory(TestSurfaceProducer &&surface_producer)
std::function< std::unique_ptr< AndroidSurface >(void)> TestSurfaceProducer
static bool IsValid(double value)
TEST(DisplayListCanvas, DrawPaint)