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

71 {
72 FlutterThreadSynchronizerTestScaffold* scaffold =
73 [[FlutterThreadSynchronizerTestScaffold alloc] init];
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 }

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

236 {
237 FlutterThreadSynchronizerTestScaffold* scaffold =
238 [[FlutterThreadSynchronizerTestScaffold alloc] init];
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 }

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

116 {
117 FlutterThreadSynchronizerTestScaffold* scaffold =
118 [[FlutterThreadSynchronizerTestScaffold alloc] init];
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 }

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

288 {
289 FlutterThreadSynchronizerTestScaffold* scaffold =
290 [[FlutterThreadSynchronizerTestScaffold alloc] init];
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 }

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

181 {
182 FlutterThreadSynchronizerTestScaffold* scaffold =
183 [[FlutterThreadSynchronizerTestScaffold alloc] init];
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 }

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:16
FlutterThreadSynchronizerTestScaffold
Definition: FlutterThreadSynchronizerTest.mm:10