Flutter macOS Embedder
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  {
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  {
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  {
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  {
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  {
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

◆ _synchronizer

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