| Flutter macOS Embedder |

Classes | Namespaces | 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

## Namespaces
| flutter
| flutter::testing

## 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 77 of file FlutterThreadSynchronizerTest.mm.

77 {
78 FlutterThreadSynchronizerTestScaffold* scaffold =
79 [[FlutterThreadSynchronizerTestScaffold alloc] init];
80 FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer;
81
82 // Initial resize: does not block until the first frame.
83 __block int notifiedResize = 0;
84 [scaffold dispatchMainTask:^{
85 [synchronizer registerView:1];
86 [synchronizer beginResizeForView:1
87 size:CGSize{5, 5}
88 notify:^{
89 notifiedResize += 1;
90 }];
91 }];
92 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
93 [scaffold joinMain];
94 EXPECT_EQ(notifiedResize, 1);
95
96 // Still does not block.
97 [scaffold dispatchMainTask:^{
98 [synchronizer beginResizeForView:1
99 size:CGSize{7, 7}
100 notify:^{
101 notifiedResize += 1;
102 }];
103 }];
104 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
105 [scaffold joinMain];
106 EXPECT_EQ(notifiedResize, 2);
107
108 // First frame
109 __block int notifiedCommit = 0;
110 [scaffold dispatchRenderTask:^{
111 [synchronizer performCommitForView:1
112 size:CGSize{7, 7}
113 notify:^{
114 notifiedCommit += 1;
115 }];
116 }];
117 EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]);
118 [scaffold joinRender];
119 EXPECT_EQ(notifiedCommit, 1);
120 }

References FlutterThreadSynchronizer::beginResizeForView:size:notify:, FlutterThreadSynchronizerTestScaffold::dispatchMainTask:, FlutterThreadSynchronizerTestScaffold::dispatchRenderTask:, FlutterThreadSynchronizerTestScaffold::joinMain, FlutterThreadSynchronizerTestScaffold::joinRender, FlutterThreadSynchronizer::performCommitForView:size:notify:, FlutterThreadSynchronizer::registerView:, and FlutterThreadSynchronizerTestScaffold::synchronizer.

## ◆ TEST() [2/5]

TEST | ( | FlutterThreadSynchronizerTest | ,
|  | RegularCommitForMultipleViews |
| ) |  |

Definition at line 242 of file FlutterThreadSynchronizerTest.mm.

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

References FlutterThreadSynchronizer::beginResizeForView:size:notify:, FlutterThreadSynchronizerTestScaffold::dispatchMainTask:, FlutterThreadSynchronizerTestScaffold::dispatchRenderTask:, FlutterThreadSynchronizerTestScaffold::joinMain, FlutterThreadSynchronizerTestScaffold::joinRender, FlutterThreadSynchronizer::performCommitForView:size:notify:, FlutterThreadSynchronizer::registerView:, and FlutterThreadSynchronizerTestScaffold::synchronizer.

## ◆ TEST() [3/5]

TEST | ( | FlutterThreadSynchronizerTest | ,
|  | ResizingBlocksRenderingUntilSizeMatches |
| ) |  |

Definition at line 122 of file FlutterThreadSynchronizerTest.mm.

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

References FlutterThreadSynchronizer::beginResizeForView:size:notify:, FlutterThreadSynchronizerTestScaffold::dispatchMainTask:, FlutterThreadSynchronizerTestScaffold::dispatchRenderTask:, FlutterThreadSynchronizerTestScaffold::joinMain, FlutterThreadSynchronizerTestScaffold::joinRender, FlutterThreadSynchronizer::performCommitForView:size:notify:, FlutterThreadSynchronizer::registerView:, and FlutterThreadSynchronizerTestScaffold::synchronizer.

## ◆ TEST() [4/5]

TEST | ( | FlutterThreadSynchronizerTest | ,
|  | ResizingForMultipleViews |
| ) |  |

Definition at line 294 of file FlutterThreadSynchronizerTest.mm.

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

References FlutterThreadSynchronizer::beginResizeForView:size:notify:, FlutterThreadSynchronizerTestScaffold::dispatchMainTask:, FlutterThreadSynchronizerTestScaffold::dispatchRenderTask:, FlutterThreadSynchronizerTestScaffold::joinMain, FlutterThreadSynchronizerTestScaffold::joinRender, FlutterThreadSynchronizer::performCommitForView:size:notify:, FlutterThreadSynchronizer::registerView:, and FlutterThreadSynchronizerTestScaffold::synchronizer.

## ◆ TEST() [5/5]

TEST | ( | FlutterThreadSynchronizerTest | ,
|  | ShutdownMakesEverythingNonBlocking |
| ) |  |

Definition at line 187 of file FlutterThreadSynchronizerTest.mm.

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

References FlutterThreadSynchronizer::beginResizeForView:size:notify:, FlutterThreadSynchronizerTestScaffold::dispatchMainTask:, FlutterThreadSynchronizerTestScaffold::dispatchRenderTask:, FlutterThreadSynchronizerTestScaffold::joinMain, FlutterThreadSynchronizerTestScaffold::joinRender, FlutterThreadSynchronizer::performCommitForView:size:notify:, FlutterThreadSynchronizer::registerView:, FlutterThreadSynchronizer::shutdown, and FlutterThreadSynchronizerTestScaffold::synchronizer.

## Variable Documentation

## ◆ _mainLatch

std::shared_ptr<fml::AutoResetWaitableEvent> _mainLatch

Initial value:
{
dispatch_queue_t _mainQueue

Definition at line 27 of file FlutterThreadSynchronizerTest.mm.

## ◆ _renderLatch

std::shared_ptr<fml::AutoResetWaitableEvent> _renderLatch

Definition at line 32 of file FlutterThreadSynchronizerTest.mm.

## ◆ _renderQueue

dispatch_queue_t _renderQueue

Definition at line 31 of file FlutterThreadSynchronizerTest.mm.

Referenced by FlutterThreadSynchronizerTestScaffold::dispatchRenderTask:, FlutterThreadSynchronizerTestScaffold::init, and FlutterThreadSynchronizerTestScaffold::joinRender.

## ◆ _synchronizer

FlutterThreadSynchronizer* _synchronizer

Definition at line 34 of file FlutterThreadSynchronizerTest.mm.

Referenced by FlutterThreadSynchronizerTestScaffold::init.

FlutterThreadSynchronizerTestScaffold::synchronizer
FlutterThreadSynchronizer * synchronizer
Definition: FlutterThreadSynchronizerTest.mm:18
FlutterThreadSynchronizer
Definition: FlutterThreadSynchronizer.h:13
FlutterThreadSynchronizerTestScaffold
Definition: FlutterThreadSynchronizerTest.mm:16