Flutter Engine
The 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"
14
15namespace flutter {
16namespace testing {
17
18using ::testing::ByMove;
19using ::testing::Return;
20
21class TestAndroidSurfaceFactory : public AndroidSurfaceFactory {
22 public:
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
39TEST(SurfacePool, GetLayerAllocateOneLayer) {
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 =
54 std::make_shared<TestAndroidSurfaceFactory>([gr_context, window]() {
55 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
56 EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
57 EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
58 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
59 return android_surface_mock;
60 });
61 auto layer = pool->GetLayer(gr_context.get(), *android_context, jni_mock,
62 surface_factory);
63
64 ASSERT_TRUE(pool->HasLayers());
65 ASSERT_NE(nullptr, layer);
66 ASSERT_EQ(reinterpret_cast<intptr_t>(gr_context.get()),
67 layer->gr_context_key);
68}
69
70TEST(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 =
85 std::make_shared<TestAndroidSurfaceFactory>([gr_context, window]() {
86 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
87 EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
88 EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
89 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
90 return android_surface_mock;
91 });
92 auto layer = pool->GetLayer(gr_context.get(), *android_context, jni_mock,
93 surface_factory);
94 ASSERT_EQ(0UL, pool->GetUnusedLayers().size());
95
96 pool->RecycleLayers();
97
98 ASSERT_TRUE(pool->HasLayers());
99 ASSERT_EQ(1UL, pool->GetUnusedLayers().size());
100 ASSERT_EQ(layer, pool->GetUnusedLayers()[0]);
101}
102
103TEST(SurfacePool, GetLayerRecycle) {
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 [gr_context_1, gr_context_2, window]() {
120 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
121 // Allocate two GPU surfaces for each gr context.
122 EXPECT_CALL(*android_surface_mock,
123 CreateGPUSurface(gr_context_1.get()));
124 EXPECT_CALL(*android_surface_mock,
125 CreateGPUSurface(gr_context_2.get()));
126 // Set the native window once.
127 EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
128 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
129 return android_surface_mock;
130 });
131 auto layer_1 = pool->GetLayer(gr_context_1.get(), *android_context, jni_mock,
132 surface_factory);
133
134 pool->RecycleLayers();
135
136 auto layer_2 = pool->GetLayer(gr_context_2.get(), *android_context, jni_mock,
137 surface_factory);
138
139 ASSERT_TRUE(pool->HasLayers());
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
148TEST(SurfacePool, GetLayerAllocateTwoLayers) {
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 =
167 std::make_shared<TestAndroidSurfaceFactory>([gr_context, window]() {
168 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
169 EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
170 EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
171 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
172 return android_surface_mock;
173 });
174 auto layer_1 = pool->GetLayer(gr_context.get(), *android_context, jni_mock,
175 surface_factory);
176 auto layer_2 = pool->GetLayer(gr_context.get(), *android_context, jni_mock,
177 surface_factory);
178
179 ASSERT_TRUE(pool->HasLayers());
180 ASSERT_NE(nullptr, layer_1);
181 ASSERT_NE(nullptr, layer_2);
182 ASSERT_NE(layer_1, layer_2);
183 ASSERT_EQ(0, layer_1->id);
184 ASSERT_EQ(1, layer_2->id);
185}
186
187TEST(SurfacePool, DestroyLayers) {
188 auto pool = std::make_unique<SurfacePool>();
189 auto jni_mock = std::make_shared<JNIMock>();
190
191 EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(0);
192 pool->DestroyLayers(jni_mock);
193
194 auto gr_context = GrDirectContext::MakeMock(nullptr);
195 auto android_context =
196 std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
197
198 auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
199 EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
200 .Times(1)
201 .WillOnce(Return(
202 ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
203 0, window))));
204
205 auto surface_factory =
206 std::make_shared<TestAndroidSurfaceFactory>([gr_context, window]() {
207 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
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
217 ASSERT_TRUE(pool->HasLayers());
218 pool->DestroyLayers(jni_mock);
219
220 ASSERT_FALSE(pool->HasLayers());
221 ASSERT_TRUE(pool->GetUnusedLayers().empty());
222}
223
224TEST(SurfacePool, DestroyLayersFrameSizeChanged) {
225 auto pool = std::make_unique<SurfacePool>();
226 auto jni_mock = std::make_shared<JNIMock>();
227
228 auto gr_context = GrDirectContext::MakeMock(nullptr);
229 auto android_context =
230 std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
231
232 auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
233
234 auto surface_factory =
235 std::make_shared<TestAndroidSurfaceFactory>([gr_context, window]() {
236 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
237 EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()));
238 EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
239 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
240 return android_surface_mock;
241 });
242 pool->SetFrameSize(SkISize::Make(10, 10));
243 EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(0);
244 EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
245 .Times(1)
246 .WillOnce(Return(
247 ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
248 0, window))));
249
250 ASSERT_FALSE(pool->HasLayers());
251
252 pool->GetLayer(gr_context.get(), *android_context, jni_mock, surface_factory);
253
254 ASSERT_TRUE(pool->HasLayers());
255
256 pool->SetFrameSize(SkISize::Make(20, 20));
257 EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(1);
258 EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
259 .Times(1)
260 .WillOnce(Return(
261 ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
262 1, window))));
263 pool->GetLayer(gr_context.get(), *android_context, jni_mock, surface_factory);
264
265 ASSERT_TRUE(pool->GetUnusedLayers().empty());
266 ASSERT_TRUE(pool->HasLayers());
267}
268
269} // namespace testing
270} // namespace flutter
AutoreleasePool pool
static sk_sp< GrDirectContext > MakeMock(const GrMockOptions *, const GrContextOptions &)
TestAndroidSurfaceFactory(TestSurfaceProducer &&surface_producer)
std::unique_ptr< AndroidSurface > CreateSurface() override
std::function< std::unique_ptr< AndroidSurface >(void)> TestSurfaceProducer
GLFWwindow * window
Definition: main.cc:45
TEST(DisplayListComplexity, EmptyDisplayList)
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20