11#include "flutter/fml/cpu_affinity.h"
12#include "flutter/fml/thread.h"
13#include "flutter/fml/trace_event.h"
20 static std::shared_ptr<WaitSetEntry>
Create(vk::UniqueFence p_fence,
22 return std::shared_ptr<WaitSetEntry>(
30 is_signalled_ =
device.getFenceStatus(fence_.get()) == vk::Result::eSuccess;
33 const vk::Fence&
GetFence()
const {
return fence_.get(); }
38 vk::UniqueFence fence_;
40 bool is_signalled_ =
false;
43 : fence_(
std::move(p_fence)),
44 callback_(
fml::ScopedCleanupClosure{p_callback}) {}
46 WaitSetEntry(
const WaitSetEntry&) =
delete;
48 WaitSetEntry(WaitSetEntry&&) =
delete;
50 WaitSetEntry& operator=(
const WaitSetEntry&) =
delete;
52 WaitSetEntry& operator=(WaitSetEntry&&) =
delete;
55FenceWaiterVK::FenceWaiterVK(std::weak_ptr<DeviceHolderVK> device_holder)
56 : device_holder_(
std::move(device_holder)) {
57 waiter_thread_ = std::make_unique<std::thread>([&]() {
Main(); });
62 waiter_thread_->join();
72 std::scoped_lock lock(wait_set_mutex_);
78 wait_set_cv_.notify_one();
83 std::vector<vk::Fence> fences;
84 for (
const auto& entry :
set) {
85 if (!entry->IsSignalled()) {
86 fences.emplace_back(entry->GetFence());
92void FenceWaiterVK::Main() {
100 bool terminate =
false;
103 std::unique_lock lock(wait_set_mutex_);
106 wait_set_cv_.wait(lock,
107 [&]() {
return !wait_set_.empty() || terminate_; });
110 terminate = terminate_;
124void FenceWaiterVK::WaitUntilEmpty() {
127 FML_DCHECK(terminate_) <<
"Fence waiter must be terminated.";
128 while (!wait_set_.empty() && Wait()) {
133bool FenceWaiterVK::Wait() {
137 std::scoped_lock lock(wait_set_mutex_);
138 wait_set = wait_set_;
141 using namespace std::literals::chrono_literals;
144 auto device_holder = device_holder_.lock();
145 if (!device_holder) {
149 const auto&
device = device_holder->GetDevice();
155 if (fences.empty()) {
163 std::chrono::nanoseconds{100ms}.count());
164 if (!(
result == vk::Result::eSuccess ||
result == vk::Result::eTimeout)) {
165 VALIDATION_LOG <<
"Fence waiter encountered an unexpected error. Tearing "
166 "down the waiter thread.";
174 for (
auto& entry : wait_set) {
175 entry->UpdateSignalledStatus(
device);
185 static constexpr auto is_signalled = [](
const auto& entry) {
186 return entry->IsSignalled();
188 std::scoped_lock lock(wait_set_mutex_);
191 std::copy_if(wait_set_.begin(), wait_set_.end(),
192 std::back_inserter(erased_entries), is_signalled);
194 std::remove_if(wait_set_.begin(), wait_set_.end(), is_signalled),
201 erased_entries.clear();
209 std::scoped_lock lock(wait_set_mutex_);
212 wait_set_cv_.notify_one();
Wraps a closure that is invoked in the destructor unless released by the caller.
static void SetCurrentThreadName(const ThreadConfig &config)
bool AddFence(vk::UniqueFence fence, const fml::closure &callback)
const vk::Fence & GetFence() const
static std::shared_ptr< WaitSetEntry > Create(vk::UniqueFence p_fence, const fml::closure &p_callback)
void UpdateSignalledStatus(const vk::Device &device)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_DCHECK(condition)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
@ kEfficiency
Request CPU affinity for the efficiency cores.
bool RequestAffinity(CpuAffinity affinity)
Request the given affinity for the current thread.
std::function< void()> closure
bool Main(const fml::CommandLine &command_line)
static std::vector< vk::Fence > GetFencesForWaitSet(const WaitSet &set)
std::vector< std::shared_ptr< WaitSetEntry > > WaitSet
The ThreadConfig is the thread info include thread name, thread priority.
#define TRACE_EVENT0(category_group, name)