Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions fml/raster_thread_merger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ RasterThreadMerger::RasterThreadMerger(fml::TaskQueueId platform_queue_id,
FML_CHECK(!task_queues_->Owns(platform_queue_id_, gpu_queue_id_));
}

void RasterThreadMerger::SetMergeUnmergeCallback(const fml::closure& callback) {
merge_unmerge_callback_ = callback;
}

void RasterThreadMerger::MergeWithLease(size_t lease_term) {
std::scoped_lock lock(lease_term_mutex_);
if (TaskQueuesAreSame()) {
Expand All @@ -30,11 +34,19 @@ void RasterThreadMerger::MergeWithLease(size_t lease_term) {
return;
}
FML_DCHECK(lease_term > 0) << "lease_term should be positive.";
if (!IsMergedUnSafe()) {
bool success = task_queues_->Merge(platform_queue_id_, gpu_queue_id_);
FML_CHECK(success) << "Unable to merge the raster and platform threads.";
lease_term_ = lease_term;

if (IsMergedUnSafe()) {
merged_condition_.notify_one();
return;
}

bool success = task_queues_->Merge(platform_queue_id_, gpu_queue_id_);
if (success && merge_unmerge_callback_ != nullptr) {
merge_unmerge_callback_();
}
FML_CHECK(success) << "Unable to merge the raster and platform threads.";
lease_term_ = lease_term;

merged_condition_.notify_one();
}

Expand All @@ -48,6 +60,9 @@ void RasterThreadMerger::UnMergeNow() {
}
lease_term_ = 0;
bool success = task_queues_->Unmerge(platform_queue_id_);
if (success && merge_unmerge_callback_ != nullptr) {
merge_unmerge_callback_();
}
FML_CHECK(success) << "Unable to un-merge the raster and platform threads.";
}

Expand Down
8 changes: 8 additions & 0 deletions fml/raster_thread_merger.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ class RasterThreadMerger
// noop.
bool IsEnabled();

// Registers a callback that can be used to clean up global state right after
// the thread configuration has changed.
//
// For example, it can be used to clear the GL context so it can be used in
// the next task from a different thread.
void SetMergeUnmergeCallback(const fml::closure& callback);

private:
static const int kLeaseNotSet;
fml::TaskQueueId platform_queue_id_;
Expand All @@ -93,6 +100,7 @@ class RasterThreadMerger
std::atomic_int lease_term_;
std::condition_variable merged_condition_;
std::mutex lease_term_mutex_;
fml::closure merge_unmerge_callback_;
bool enabled_;

bool IsMergedUnSafe() const;
Expand Down
16 changes: 8 additions & 8 deletions shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ void Rasterizer::Setup(std::unique_ptr<Surface> surface) {
delegate_.GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId();
raster_thread_merger_ =
fml::MakeRefCounted<fml::RasterThreadMerger>(platform_id, gpu_id);

raster_thread_merger_->SetMergeUnmergeCallback(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the merge/unmerge callback need to be removed during rasterizer teardown?

The callback is holding a pointer to the rasterizer, so the rasterizer needs to ensure that the callback does not outlive the rasterizer.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 2893c34

[weak_this = weak_factory_.GetWeakPtr()]() {
// Clear the GL context after the thread configuration has changed.
if (weak_this && weak_this->surface_) {
weak_this->surface_->ClearRenderContext();
}
});
}
#endif
}
Expand Down Expand Up @@ -467,14 +475,6 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) {

FireNextFrameCallbackIfPresent();

// Clear the render context after submitting the frame.
// This ensures that the GL context is released after drawing to the
// surface.
//
// The GL context must be clear before performing Gr context deferred
// cleanup.
surface_->ClearRenderContext();

if (surface_->GetContext()) {
TRACE_EVENT0("flutter", "PerformDeferredSkiaCleanup");
surface_->GetContext()->performDeferredCleanup(kSkiaCleanupExpiration);
Expand Down