| Flutter macOS Embedder |

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

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

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

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

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

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

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

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

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

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

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 21 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.

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

## ◆ _synchronizer

FlutterThreadSynchronizer* _synchronizer

Definition at line 28 of file FlutterThreadSynchronizerTest.mm.

Referenced by FlutterThreadSynchronizerTestScaffold::init.

FlutterThreadSynchronizerTestScaffold::synchronizer
FlutterThreadSynchronizer * synchronizer
Definition: FlutterThreadSynchronizerTest.mm:12
FlutterThreadSynchronizer
Definition: FlutterThreadSynchronizer.h:18
FlutterThreadSynchronizerTestScaffold
Definition: FlutterThreadSynchronizerTest.mm:10