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