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

71  {
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  {
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  {
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  {
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  {
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

◆ _synchronizer

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