| Flutter macOS Embedder |

Classes | Namespaces | Functions | Variables
FlutterThreadSynchronizerTest.mm File Reference
`#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h"`
`#import <OCMock/OCMock.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 78 of file FlutterThreadSynchronizerTest.mm.

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

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

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

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

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

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

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

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

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

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

## ◆ _renderLatch

std::shared_ptr<fml::AutoResetWaitableEvent> _renderLatch

Definition at line 33 of file FlutterThreadSynchronizerTest.mm.

## ◆ _renderQueue

dispatch_queue_t _renderQueue

Definition at line 32 of file FlutterThreadSynchronizerTest.mm.

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

## ◆ _synchronizer

FlutterThreadSynchronizer* _synchronizer

Definition at line 35 of file FlutterThreadSynchronizerTest.mm.

Referenced by FlutterThreadSynchronizerTestScaffold::init.

FlutterThreadSynchronizerTestScaffold::synchronizer
FlutterThreadSynchronizer * synchronizer
Definition: FlutterThreadSynchronizerTest.mm:19
FlutterThreadSynchronizer
Definition: FlutterThreadSynchronizer.h:13
FlutterThreadSynchronizerTestScaffold
Definition: FlutterThreadSynchronizerTest.mm:17