Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 9ede9bf

Browse files
author
Chris Yang
authored
iOS: only add explicit transactions when there are platform views (only on main threads) (#21526)
1 parent 0f4f6c7 commit 9ede9bf

File tree

3 files changed

+38
-15
lines changed

3 files changed

+38
-15
lines changed

shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,21 @@
279279
CancelFrame();
280280
return PostPrerollResult::kSkipAndRetryFrame;
281281
}
282+
// If the post preroll action is successful, we will display platform views in the current frame.
283+
// In order to sync the rendering of the platform views (quartz) with skia's rendering,
284+
// We need to begin an explicit CATransaction. This transaction needs to be submitted
285+
// after the current frame is submitted.
286+
BeginCATransaction();
282287
raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
283288
return PostPrerollResult::kSuccess;
284289
}
285290

286291
void FlutterPlatformViewsController::PrerollCompositeEmbeddedView(
287292
int view_id,
288293
std::unique_ptr<EmbeddedViewParams> params) {
294+
// All the CATransactions should be committed by the end of the last frame,
295+
// so catransaction_added_ must be false.
296+
FML_DCHECK(!catransaction_added_);
289297
picture_recorders_[view_id] = std::make_unique<SkPictureRecorder>();
290298

291299
auto rtree_factory = RTreeFactory();
@@ -548,6 +556,10 @@
548556

549557
did_submit &= frame->Submit();
550558

559+
// If the frame is submitted with embedded platform views,
560+
// there should be a |[CATransaction begin]| call in this frame prior to all the drawing.
561+
// If that case, we need to commit the transaction.
562+
CommitCATransactionIfNeeded();
551563
return did_submit;
552564
}
553565

@@ -662,6 +674,21 @@
662674
views_to_dispose_.clear();
663675
}
664676

677+
void FlutterPlatformViewsController::BeginCATransaction() {
678+
FML_DCHECK([[NSThread currentThread] isMainThread]);
679+
FML_DCHECK(!catransaction_added_);
680+
[CATransaction begin];
681+
catransaction_added_ = true;
682+
}
683+
684+
void FlutterPlatformViewsController::CommitCATransactionIfNeeded() {
685+
if (catransaction_added_) {
686+
FML_DCHECK([[NSThread currentThread] isMainThread]);
687+
[CATransaction commit];
688+
catransaction_added_ = false;
689+
}
690+
}
691+
665692
} // namespace flutter
666693

667694
// This recognizers delays touch events from being dispatched to the responder chain until it failed

shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ class FlutterPlatformViewsController {
245245

246246
std::unique_ptr<fml::WeakPtrFactory<FlutterPlatformViewsController>> weak_factory_;
247247

248+
bool catransaction_added_ = false;
249+
248250
void OnCreate(FlutterMethodCall* call, FlutterResult& result);
249251
void OnDispose(FlutterMethodCall* call, FlutterResult& result);
250252
void OnAcceptGesture(FlutterMethodCall* call, FlutterResult& result);
@@ -294,6 +296,13 @@ class FlutterPlatformViewsController {
294296
// order.
295297
void BringLayersIntoView(LayersMap layer_map);
296298

299+
// Begin a CATransaction.
300+
// This transaction needs to be balanced with |CommitCATransactionIfNeeded|.
301+
void BeginCATransaction();
302+
303+
// Commit a CATransaction if |BeginCATransaction| has been called during the frame.
304+
void CommitCATransactionIfNeeded();
305+
297306
FML_DISALLOW_COPY_AND_ASSIGN(FlutterPlatformViewsController);
298307
};
299308

shell/platform/darwin/ios/ios_surface.mm

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,6 @@
7171
TRACE_EVENT0("flutter", "IOSSurface::CancelFrame");
7272
FML_CHECK(platform_views_controller_ != nullptr);
7373
platform_views_controller_->CancelFrame();
74-
// Committing the current transaction as |BeginFrame| will create a nested
75-
// CATransaction otherwise.
76-
[CATransaction commit];
7774
}
7875

7976
// |ExternalViewEmbedder|
@@ -84,7 +81,6 @@
8481
TRACE_EVENT0("flutter", "IOSSurface::BeginFrame");
8582
FML_CHECK(platform_views_controller_ != nullptr);
8683
platform_views_controller_->SetFrameSize(frame_size);
87-
[CATransaction begin];
8884
}
8985

9086
// |ExternalViewEmbedder|
@@ -102,10 +98,6 @@
10298
TRACE_EVENT0("flutter", "IOSSurface::PostPrerollAction");
10399
FML_CHECK(platform_views_controller_ != nullptr);
104100
PostPrerollResult result = platform_views_controller_->PostPrerollAction(raster_thread_merger);
105-
if (result == PostPrerollResult::kSkipAndRetryFrame) {
106-
// Commit the current transaction if the frame is dropped.
107-
[CATransaction commit];
108-
}
109101
return result;
110102
}
111103

@@ -126,13 +118,8 @@
126118
void IOSSurface::SubmitFrame(GrDirectContext* context, std::unique_ptr<SurfaceFrame> frame) {
127119
TRACE_EVENT0("flutter", "IOSSurface::SubmitFrame");
128120
FML_CHECK(platform_views_controller_ != nullptr);
129-
bool submitted =
130-
platform_views_controller_->SubmitFrame(std::move(context), ios_context_, std::move(frame));
131-
132-
if (submitted) {
133-
TRACE_EVENT0("flutter", "IOSSurface::DidSubmitFrame");
134-
[CATransaction commit];
135-
}
121+
platform_views_controller_->SubmitFrame(std::move(context), ios_context_, std::move(frame));
122+
TRACE_EVENT0("flutter", "IOSSurface::DidSubmitFrame");
136123
}
137124

138125
// |ExternalViewEmbedder|

0 commit comments

Comments
 (0)