mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
iOS: only add explicit transactions when there are platform views (only on main threads) (#21526)
This commit is contained in:
parent
0f4f6c738f
commit
9ede9bfa43
@ -279,6 +279,11 @@ PostPrerollResult FlutterPlatformViewsController::PostPrerollAction(
|
||||
CancelFrame();
|
||||
return PostPrerollResult::kSkipAndRetryFrame;
|
||||
}
|
||||
// If the post preroll action is successful, we will display platform views in the current frame.
|
||||
// In order to sync the rendering of the platform views (quartz) with skia's rendering,
|
||||
// We need to begin an explicit CATransaction. This transaction needs to be submitted
|
||||
// after the current frame is submitted.
|
||||
BeginCATransaction();
|
||||
raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
|
||||
return PostPrerollResult::kSuccess;
|
||||
}
|
||||
@ -286,6 +291,9 @@ PostPrerollResult FlutterPlatformViewsController::PostPrerollAction(
|
||||
void FlutterPlatformViewsController::PrerollCompositeEmbeddedView(
|
||||
int view_id,
|
||||
std::unique_ptr<EmbeddedViewParams> params) {
|
||||
// All the CATransactions should be committed by the end of the last frame,
|
||||
// so catransaction_added_ must be false.
|
||||
FML_DCHECK(!catransaction_added_);
|
||||
picture_recorders_[view_id] = std::make_unique<SkPictureRecorder>();
|
||||
|
||||
auto rtree_factory = RTreeFactory();
|
||||
@ -548,6 +556,10 @@ bool FlutterPlatformViewsController::SubmitFrame(GrDirectContext* gr_context,
|
||||
|
||||
did_submit &= frame->Submit();
|
||||
|
||||
// If the frame is submitted with embedded platform views,
|
||||
// there should be a |[CATransaction begin]| call in this frame prior to all the drawing.
|
||||
// If that case, we need to commit the transaction.
|
||||
CommitCATransactionIfNeeded();
|
||||
return did_submit;
|
||||
}
|
||||
|
||||
@ -662,6 +674,21 @@ void FlutterPlatformViewsController::DisposeViews() {
|
||||
views_to_dispose_.clear();
|
||||
}
|
||||
|
||||
void FlutterPlatformViewsController::BeginCATransaction() {
|
||||
FML_DCHECK([[NSThread currentThread] isMainThread]);
|
||||
FML_DCHECK(!catransaction_added_);
|
||||
[CATransaction begin];
|
||||
catransaction_added_ = true;
|
||||
}
|
||||
|
||||
void FlutterPlatformViewsController::CommitCATransactionIfNeeded() {
|
||||
if (catransaction_added_) {
|
||||
FML_DCHECK([[NSThread currentThread] isMainThread]);
|
||||
[CATransaction commit];
|
||||
catransaction_added_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
// This recognizers delays touch events from being dispatched to the responder chain until it failed
|
||||
|
||||
@ -245,6 +245,8 @@ class FlutterPlatformViewsController {
|
||||
|
||||
std::unique_ptr<fml::WeakPtrFactory<FlutterPlatformViewsController>> weak_factory_;
|
||||
|
||||
bool catransaction_added_ = false;
|
||||
|
||||
void OnCreate(FlutterMethodCall* call, FlutterResult& result);
|
||||
void OnDispose(FlutterMethodCall* call, FlutterResult& result);
|
||||
void OnAcceptGesture(FlutterMethodCall* call, FlutterResult& result);
|
||||
@ -294,6 +296,13 @@ class FlutterPlatformViewsController {
|
||||
// order.
|
||||
void BringLayersIntoView(LayersMap layer_map);
|
||||
|
||||
// Begin a CATransaction.
|
||||
// This transaction needs to be balanced with |CommitCATransactionIfNeeded|.
|
||||
void BeginCATransaction();
|
||||
|
||||
// Commit a CATransaction if |BeginCATransaction| has been called during the frame.
|
||||
void CommitCATransactionIfNeeded();
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(FlutterPlatformViewsController);
|
||||
};
|
||||
|
||||
|
||||
@ -71,9 +71,6 @@ void IOSSurface::CancelFrame() {
|
||||
TRACE_EVENT0("flutter", "IOSSurface::CancelFrame");
|
||||
FML_CHECK(platform_views_controller_ != nullptr);
|
||||
platform_views_controller_->CancelFrame();
|
||||
// Committing the current transaction as |BeginFrame| will create a nested
|
||||
// CATransaction otherwise.
|
||||
[CATransaction commit];
|
||||
}
|
||||
|
||||
// |ExternalViewEmbedder|
|
||||
@ -84,7 +81,6 @@ void IOSSurface::BeginFrame(SkISize frame_size,
|
||||
TRACE_EVENT0("flutter", "IOSSurface::BeginFrame");
|
||||
FML_CHECK(platform_views_controller_ != nullptr);
|
||||
platform_views_controller_->SetFrameSize(frame_size);
|
||||
[CATransaction begin];
|
||||
}
|
||||
|
||||
// |ExternalViewEmbedder|
|
||||
@ -102,10 +98,6 @@ PostPrerollResult IOSSurface::PostPrerollAction(
|
||||
TRACE_EVENT0("flutter", "IOSSurface::PostPrerollAction");
|
||||
FML_CHECK(platform_views_controller_ != nullptr);
|
||||
PostPrerollResult result = platform_views_controller_->PostPrerollAction(raster_thread_merger);
|
||||
if (result == PostPrerollResult::kSkipAndRetryFrame) {
|
||||
// Commit the current transaction if the frame is dropped.
|
||||
[CATransaction commit];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -126,13 +118,8 @@ SkCanvas* IOSSurface::CompositeEmbeddedView(int view_id) {
|
||||
void IOSSurface::SubmitFrame(GrDirectContext* context, std::unique_ptr<SurfaceFrame> frame) {
|
||||
TRACE_EVENT0("flutter", "IOSSurface::SubmitFrame");
|
||||
FML_CHECK(platform_views_controller_ != nullptr);
|
||||
bool submitted =
|
||||
platform_views_controller_->SubmitFrame(std::move(context), ios_context_, std::move(frame));
|
||||
|
||||
if (submitted) {
|
||||
TRACE_EVENT0("flutter", "IOSSurface::DidSubmitFrame");
|
||||
[CATransaction commit];
|
||||
}
|
||||
platform_views_controller_->SubmitFrame(std::move(context), ios_context_, std::move(frame));
|
||||
TRACE_EVENT0("flutter", "IOSSurface::DidSubmitFrame");
|
||||
}
|
||||
|
||||
// |ExternalViewEmbedder|
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user