7 #import <QuartzCore/QuartzCore.h>
10 #include <unordered_map>
13 #import "flutter/fml/logging.h"
14 #import "flutter/fml/synchronization/waitable_event.h"
34 - (BOOL)allViewsHaveFrame;
41 - (BOOL)someViewsHaveFrame;
51 - (instancetype)initWithMainQueue:(dispatch_queue_t)queue {
59 - (BOOL)allViewsHaveFrame {
60 for (
auto const& [viewId, contentSize] : _contentSizes) {
61 if (CGSizeEqualToSize(contentSize, CGSizeZero)) {
68 - (BOOL)someViewsHaveFrame {
69 for (
auto const& [viewId, contentSize] : _contentSizes) {
70 if (!CGSizeEqualToSize(contentSize, CGSizeZero)) {
78 dispatch_assert_queue(_mainQueue);
80 [CATransaction begin];
81 [CATransaction setDisableActions:YES];
82 for (dispatch_block_t block : _scheduledBlocks) {
85 [CATransaction commit];
86 _scheduledBlocks.clear();
90 std::unique_lock<std::mutex> lock(_mutex);
92 _beginResizeWaiting = YES;
94 while (![
self someViewsHaveFrame] && !_shuttingDown) {
95 _condBlockBeginResize.wait(lock);
99 _beginResizeWaiting = NO;
102 - (void)beginResizeForView:(int64_t)viewId
104 notify:(nonnull dispatch_block_t)notify {
105 dispatch_assert_queue(_mainQueue);
106 std::unique_lock<std::mutex> lock(_mutex);
108 if (![
self allViewsHaveFrame] || _shuttingDown) {
118 _contentSizes[viewId] = CGSizeMake(-1, -1);
120 _beginResizeWaiting = YES;
126 const CGSize& contentSize = _contentSizes[viewId];
127 if (CGSizeEqualToSize(contentSize, size) || CGSizeEqualToSize(contentSize, CGSizeZero)) {
130 _condBlockBeginResize.wait(lock);
134 _beginResizeWaiting = NO;
137 - (void)performCommitForView:(int64_t)viewId
139 notify:(nonnull dispatch_block_t)notify {
140 dispatch_assert_queue_not(_mainQueue);
141 fml::AutoResetWaitableEvent event;
143 std::unique_lock<std::mutex> lock(_mutex);
149 fml::AutoResetWaitableEvent& e = event;
150 _scheduledBlocks.push_back(^{
152 _contentSizes[viewId] = size;
155 if (_beginResizeWaiting) {
156 _condBlockBeginResize.notify_all();
158 dispatch_async(_mainQueue, ^{
159 std::unique_lock<std::mutex> lock(_mutex);
167 - (void)registerView:(int64_t)viewId {
168 dispatch_assert_queue(_mainQueue);
169 std::unique_lock<std::mutex> lock(_mutex);
170 _contentSizes[viewId] = CGSizeZero;
173 - (void)deregisterView:(int64_t)viewId {
174 dispatch_assert_queue(_mainQueue);
175 std::unique_lock<std::mutex> lock(_mutex);
176 _contentSizes.erase(viewId);
180 dispatch_assert_queue(_mainQueue);
181 std::unique_lock<std::mutex> lock(_mutex);
183 _condBlockBeginResize.notify_all();
188 std::unique_lock<std::mutex> lock(_mutex);
189 return _beginResizeWaiting;