mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
182 lines
4.8 KiB
C++
182 lines
4.8 KiB
C++
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#define FML_USED_ON_EMBEDDER
|
|
|
|
#include "flutter/fml/raster_thread_merger.h"
|
|
|
|
#include <utility>
|
|
|
|
#include "flutter/fml/message_loop_impl.h"
|
|
|
|
namespace fml {
|
|
|
|
RasterThreadMerger::RasterThreadMerger(fml::TaskQueueId platform_queue_id,
|
|
fml::TaskQueueId gpu_queue_id)
|
|
: RasterThreadMerger(
|
|
MakeRefCounted<SharedThreadMerger>(platform_queue_id, gpu_queue_id),
|
|
platform_queue_id,
|
|
gpu_queue_id) {}
|
|
|
|
RasterThreadMerger::RasterThreadMerger(
|
|
fml::RefPtr<fml::SharedThreadMerger> shared_merger,
|
|
fml::TaskQueueId platform_queue_id,
|
|
fml::TaskQueueId gpu_queue_id)
|
|
: platform_queue_id_(platform_queue_id),
|
|
gpu_queue_id_(gpu_queue_id),
|
|
shared_merger_(std::move(shared_merger)) {}
|
|
|
|
void RasterThreadMerger::SetMergeUnmergeCallback(const fml::closure& callback) {
|
|
merge_unmerge_callback_ = callback;
|
|
}
|
|
|
|
const fml::RefPtr<fml::SharedThreadMerger>&
|
|
RasterThreadMerger::GetSharedRasterThreadMerger() const {
|
|
return shared_merger_;
|
|
}
|
|
|
|
fml::RefPtr<fml::RasterThreadMerger>
|
|
RasterThreadMerger::CreateOrShareThreadMerger(
|
|
const fml::RefPtr<fml::RasterThreadMerger>& parent_merger,
|
|
TaskQueueId platform_id,
|
|
TaskQueueId raster_id) {
|
|
if (parent_merger && parent_merger->platform_queue_id_ == platform_id &&
|
|
parent_merger->gpu_queue_id_ == raster_id) {
|
|
auto shared_merger = parent_merger->GetSharedRasterThreadMerger();
|
|
return fml::MakeRefCounted<RasterThreadMerger>(shared_merger, platform_id,
|
|
raster_id);
|
|
} else {
|
|
return fml::MakeRefCounted<RasterThreadMerger>(platform_id, raster_id);
|
|
}
|
|
}
|
|
|
|
void RasterThreadMerger::MergeWithLease(size_t lease_term) {
|
|
std::scoped_lock lock(mutex_);
|
|
if (TaskQueuesAreSame()) {
|
|
return;
|
|
}
|
|
if (!IsEnabledUnSafe()) {
|
|
return;
|
|
}
|
|
FML_DCHECK(lease_term > 0) << "lease_term should be positive.";
|
|
|
|
if (IsMergedUnSafe()) {
|
|
merged_condition_.notify_one();
|
|
return;
|
|
}
|
|
|
|
bool success = shared_merger_->MergeWithLease(this, lease_term);
|
|
if (success && merge_unmerge_callback_ != nullptr) {
|
|
merge_unmerge_callback_();
|
|
}
|
|
|
|
merged_condition_.notify_one();
|
|
}
|
|
|
|
void RasterThreadMerger::UnMergeNowIfLastOne() {
|
|
std::scoped_lock lock(mutex_);
|
|
|
|
if (TaskQueuesAreSame()) {
|
|
return;
|
|
}
|
|
if (!IsEnabledUnSafe()) {
|
|
return;
|
|
}
|
|
bool success = shared_merger_->UnMergeNowIfLastOne(this);
|
|
if (success && merge_unmerge_callback_ != nullptr) {
|
|
merge_unmerge_callback_();
|
|
}
|
|
}
|
|
|
|
bool RasterThreadMerger::IsOnPlatformThread() const {
|
|
return MessageLoop::GetCurrentTaskQueueId() == platform_queue_id_;
|
|
}
|
|
|
|
bool RasterThreadMerger::IsOnRasterizingThread() {
|
|
std::scoped_lock lock(mutex_);
|
|
|
|
if (IsMergedUnSafe()) {
|
|
return IsOnPlatformThread();
|
|
} else {
|
|
return !IsOnPlatformThread();
|
|
}
|
|
}
|
|
|
|
void RasterThreadMerger::ExtendLeaseTo(size_t lease_term) {
|
|
FML_DCHECK(lease_term > 0) << "lease_term should be positive.";
|
|
if (TaskQueuesAreSame()) {
|
|
return;
|
|
}
|
|
std::scoped_lock lock(mutex_);
|
|
if (!IsEnabledUnSafe()) {
|
|
return;
|
|
}
|
|
shared_merger_->ExtendLeaseTo(this, lease_term);
|
|
}
|
|
|
|
bool RasterThreadMerger::IsMerged() {
|
|
std::scoped_lock lock(mutex_);
|
|
return IsMergedUnSafe();
|
|
}
|
|
|
|
void RasterThreadMerger::Enable() {
|
|
std::scoped_lock lock(mutex_);
|
|
shared_merger_->SetEnabledUnSafe(true);
|
|
}
|
|
|
|
void RasterThreadMerger::Disable() {
|
|
std::scoped_lock lock(mutex_);
|
|
shared_merger_->SetEnabledUnSafe(false);
|
|
}
|
|
|
|
bool RasterThreadMerger::IsEnabled() {
|
|
std::scoped_lock lock(mutex_);
|
|
return IsEnabledUnSafe();
|
|
}
|
|
|
|
bool RasterThreadMerger::IsEnabledUnSafe() const {
|
|
return shared_merger_->IsEnabledUnSafe();
|
|
}
|
|
|
|
bool RasterThreadMerger::IsMergedUnSafe() const {
|
|
return TaskQueuesAreSame() || shared_merger_->IsMergedUnSafe();
|
|
}
|
|
|
|
bool RasterThreadMerger::TaskQueuesAreSame() const {
|
|
return platform_queue_id_ == gpu_queue_id_;
|
|
}
|
|
|
|
void RasterThreadMerger::WaitUntilMerged() {
|
|
if (TaskQueuesAreSame()) {
|
|
return;
|
|
}
|
|
FML_CHECK(IsOnPlatformThread());
|
|
std::unique_lock<std::mutex> lock(mutex_);
|
|
merged_condition_.wait(lock, [&] { return IsMergedUnSafe(); });
|
|
}
|
|
|
|
RasterThreadStatus RasterThreadMerger::DecrementLease() {
|
|
if (TaskQueuesAreSame()) {
|
|
return RasterThreadStatus::kRemainsMerged;
|
|
}
|
|
std::scoped_lock lock(mutex_);
|
|
if (!IsMergedUnSafe()) {
|
|
return RasterThreadStatus::kRemainsUnmerged;
|
|
}
|
|
if (!IsEnabledUnSafe()) {
|
|
return RasterThreadStatus::kRemainsMerged;
|
|
}
|
|
bool unmerged_after_decrement = shared_merger_->DecrementLease(this);
|
|
if (unmerged_after_decrement) {
|
|
if (merge_unmerge_callback_ != nullptr) {
|
|
merge_unmerge_callback_();
|
|
}
|
|
return RasterThreadStatus::kUnmergedNow;
|
|
}
|
|
|
|
return RasterThreadStatus::kRemainsMerged;
|
|
}
|
|
|
|
} // namespace fml
|