Flutter Engine
The Flutter Engine
Classes | Functions | Variables
FlutterThreadSynchronizerTest.mm File Reference
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h"
#import "flutter/fml/synchronization/waitable_event.h"
#import "flutter/testing/testing.h"

Go to the source code of this file.

Classes

class  FlutterThreadSynchronizerTestScaffold
 

Functions

 TEST (FlutterThreadSynchronizerTest, RegularCommit)
 
 TEST (FlutterThreadSynchronizerTest, ResizingBlocksRenderingUntilSizeMatches)
 
 TEST (FlutterThreadSynchronizerTest, ShutdownMakesEverythingNonBlocking)
 
 TEST (FlutterThreadSynchronizerTest, RegularCommitForMultipleViews)
 
 TEST (FlutterThreadSynchronizerTest, ResizingForMultipleViews)
 

Variables

std::shared_ptr< fml::AutoResetWaitableEvent_mainLatch
 
dispatch_queue_t _renderQueue
 
std::shared_ptr< fml::AutoResetWaitableEvent_renderLatch
 
FlutterThreadSynchronizer_synchronizer
 

Function Documentation

◆ TEST() [1/5]

TEST ( FlutterThreadSynchronizerTest  ,
RegularCommit   
)

Definition at line 71 of file FlutterThreadSynchronizerTest.mm.

71 {
74 FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer;
75
76 // Initial resize: does not block until the first frame.
77 __block int notifiedResize = 0;
78 [scaffold dispatchMainTask:^{
79 [synchronizer registerView:1];
80 [synchronizer beginResizeForView:1
81 size:CGSize{5, 5}
82 notify:^{
83 notifiedResize += 1;
84 }];
85 }];
86 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
87 [scaffold joinMain];
88 EXPECT_EQ(notifiedResize, 1);
89
90 // Still does not block.
91 [scaffold dispatchMainTask:^{
92 [synchronizer beginResizeForView:1
93 size:CGSize{7, 7}
94 notify:^{
95 notifiedResize += 1;
96 }];
97 }];
98 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
99 [scaffold joinMain];
100 EXPECT_EQ(notifiedResize, 2);
101
102 // First frame
103 __block int notifiedCommit = 0;
104 [scaffold dispatchRenderTask:^{
105 [synchronizer performCommitForView:1
106 size:CGSize{7, 7}
107 notify:^{
108 notifiedCommit += 1;
109 }];
110 }];
111 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
112 [scaffold joinRender];
113 EXPECT_EQ(notifiedCommit, 1);
114}
static bool init()
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259

◆ TEST() [2/5]

TEST ( FlutterThreadSynchronizerTest  ,
RegularCommitForMultipleViews   
)

Definition at line 236 of file FlutterThreadSynchronizerTest.mm.

236 {
239 FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer;
240 fml::AutoResetWaitableEvent begunResizingLatch;
241 fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch;
242
243 // Initial resize: does not block until the first frame.
244 [scaffold dispatchMainTask:^{
245 [synchronizer registerView:1];
246 [synchronizer registerView:2];
247 [synchronizer beginResizeForView:1
248 size:CGSize{5, 5}
249 notify:^{
250 }];
251 [synchronizer beginResizeForView:2
252 size:CGSize{15, 15}
253 notify:^{
254 begunResizing->Signal();
255 }];
256 }];
257 begunResizing->Wait();
258 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
259 [scaffold joinMain];
260
261 // Still does not block.
262 [scaffold dispatchMainTask:^{
263 [synchronizer beginResizeForView:1
264 size:CGSize{7, 7}
265 notify:^{
266 begunResizing->Signal();
267 }];
268 }];
269 begunResizing->Signal();
270 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
271 [scaffold joinMain];
272
273 // First frame
274 [scaffold dispatchRenderTask:^{
275 [synchronizer performCommitForView:1
276 size:CGSize{7, 7}
277 notify:^{
278 }];
279 [synchronizer performCommitForView:2
280 size:CGSize{15, 15}
281 notify:^{
282 }];
283 }];
284 [scaffold joinRender];
285 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
286}

◆ TEST() [3/5]

TEST ( FlutterThreadSynchronizerTest  ,
ResizingBlocksRenderingUntilSizeMatches   
)

Definition at line 116 of file FlutterThreadSynchronizerTest.mm.

116 {
119 FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer;
120 // A latch to ensure that a beginResizeForView: call has at least executed
121 // something, so that the isWaitingWhenMutexIsAvailable: call correctly stops
122 // at either when beginResizeForView: finishes or waits half way.
123 fml::AutoResetWaitableEvent begunResizingLatch;
124 fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch;
125
126 // Initial resize: does not block until the first frame.
127 [scaffold dispatchMainTask:^{
128 [synchronizer registerView:1];
129 [synchronizer beginResizeForView:1
130 size:CGSize{5, 5}
131 notify:^{
132 }];
133 }];
134 [scaffold joinMain];
135 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
136
137 // First frame.
138 [scaffold dispatchRenderTask:^{
139 [synchronizer performCommitForView:1
140 size:CGSize{5, 5}
141 notify:^{
142 }];
143 }];
144 [scaffold joinRender];
145 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
146
147 // Resize to (7, 7): blocks until the next frame.
148 [scaffold dispatchMainTask:^{
149 [synchronizer beginResizeForView:1
150 size:CGSize{7, 7}
151 notify:^{
152 begunResizing->Signal();
153 }];
154 }];
155 begunResizing->Wait();
156 EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]);
157
158 // Render with old size.
159 [scaffold dispatchRenderTask:^{
160 [synchronizer performCommitForView:1
161 size:CGSize{5, 5}
162 notify:^{
163 }];
164 }];
165 [scaffold joinRender];
166 EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]);
167
168 // Render with new size.
169 [scaffold dispatchRenderTask:^{
170 [synchronizer performCommitForView:1
171 size:CGSize{7, 7}
172 notify:^{
173 }];
174 }];
175 [scaffold joinRender];
176 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
177
178 [scaffold joinMain];
179}
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678

◆ TEST() [4/5]

TEST ( FlutterThreadSynchronizerTest  ,
ResizingForMultipleViews   
)

Definition at line 288 of file FlutterThreadSynchronizerTest.mm.

288 {
291 FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer;
292 fml::AutoResetWaitableEvent begunResizingLatch;
293 fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch;
294
295 // Initial resize: does not block until the first frame.
296 [scaffold dispatchMainTask:^{
297 [synchronizer registerView:1];
298 [synchronizer registerView:2];
299 [synchronizer beginResizeForView:1
300 size:CGSize{5, 5}
301 notify:^{
302 }];
303 [synchronizer beginResizeForView:2
304 size:CGSize{15, 15}
305 notify:^{
306 }];
307 }];
308 [scaffold joinMain];
309 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
310
311 // First frame.
312 [scaffold dispatchRenderTask:^{
313 [synchronizer performCommitForView:1
314 size:CGSize{5, 5}
315 notify:^{
316 }];
317 [synchronizer performCommitForView:2
318 size:CGSize{15, 15}
319 notify:^{
320 }];
321 }];
322 [scaffold joinRender];
323 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
324
325 // Resize view 2 to (17, 17): blocks until the next frame.
326 [scaffold dispatchMainTask:^{
327 [synchronizer beginResizeForView:2
328 size:CGSize{17, 17}
329 notify:^{
330 begunResizing->Signal();
331 }];
332 }];
333 begunResizing->Wait();
334 EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]);
335
336 // Render view 1 with the size. Still blocking.
337 [scaffold dispatchRenderTask:^{
338 [synchronizer performCommitForView:1
339 size:CGSize{5, 5}
340 notify:^{
341 }];
342 }];
343 [scaffold joinRender];
344 EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]);
345
346 // Render view 2 with the old size. Still blocking.
347 [scaffold dispatchRenderTask:^{
348 [synchronizer performCommitForView:1
349 size:CGSize{15, 15}
350 notify:^{
351 }];
352 }];
353 [scaffold joinRender];
354 EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]);
355
356 // Render view 1 with the size.
357 [scaffold dispatchRenderTask:^{
358 [synchronizer performCommitForView:1
359 size:CGSize{5, 5}
360 notify:^{
361 }];
362 }];
363 [scaffold joinRender];
364 EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]);
365
366 // Render view 2 with the new size. Unblocks.
367 [scaffold dispatchRenderTask:^{
368 [synchronizer performCommitForView:2
369 size:CGSize{17, 17}
370 notify:^{
371 }];
372 }];
373 [scaffold joinRender];
374 [scaffold joinMain];
375 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
376}

◆ TEST() [5/5]

TEST ( FlutterThreadSynchronizerTest  ,
ShutdownMakesEverythingNonBlocking   
)

Definition at line 181 of file FlutterThreadSynchronizerTest.mm.

181 {
184 FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer;
185 fml::AutoResetWaitableEvent begunResizingLatch;
186 fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch;
187
188 // Initial resize
189 [scaffold dispatchMainTask:^{
190 [synchronizer registerView:1];
191 [synchronizer beginResizeForView:1
192 size:CGSize{5, 5}
193 notify:^{
194 }];
195 }];
196 [scaffold joinMain];
197 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
198
199 // Push a frame.
200 [scaffold dispatchRenderTask:^{
201 [synchronizer performCommitForView:1
202 size:CGSize{5, 5}
203 notify:^{
204 }];
205 }];
206 [scaffold joinRender];
207 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
208
209 [scaffold dispatchMainTask:^{
210 [synchronizer shutdown];
211 }];
212
213 // Resize to (7, 7). Should not block any frames since it has shut down.
214 [scaffold dispatchMainTask:^{
215 [synchronizer beginResizeForView:1
216 size:CGSize{7, 7}
217 notify:^{
218 begunResizing->Signal();
219 }];
220 }];
221 begunResizing->Wait();
222 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
223 [scaffold joinMain];
224
225 // All further calls should be unblocking.
226 [scaffold dispatchRenderTask:^{
227 [synchronizer performCommitForView:1
228 size:CGSize{9, 9}
229 notify:^{
230 }];
231 }];
232 [scaffold joinRender];
233 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
234}

Variable Documentation

◆ _mainLatch

std::shared_ptr<fml::AutoResetWaitableEvent> _mainLatch
Initial value:
{
dispatch_queue_t _mainQueue

Definition at line 23 of file FlutterThreadSynchronizerTest.mm.

◆ _renderLatch

std::shared_ptr<fml::AutoResetWaitableEvent> _renderLatch

Definition at line 26 of file FlutterThreadSynchronizerTest.mm.

◆ _renderQueue

dispatch_queue_t _renderQueue

Definition at line 25 of file FlutterThreadSynchronizerTest.mm.

◆ _synchronizer

FlutterThreadSynchronizer* _synchronizer

Definition at line 28 of file FlutterThreadSynchronizerTest.mm.