Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
resource_manager_vk.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include "flutter/fml/cpu_affinity.h"
8#include "flutter/fml/thread.h"
9#include "flutter/fml/trace_event.h"
10#include "fml/logging.h"
11
12namespace impeller {
13
14std::shared_ptr<ResourceManagerVK> ResourceManagerVK::Create() {
15 // It will be tempting to refactor this to create the waiter thread in the
16 // static method instead of the constructor. However, that causes the
17 // destructor never to be called, and the thread never terminates!
18 //
19 // See https://github.com/flutter/flutter/issues/134482.
20 return std::shared_ptr<ResourceManagerVK>(new ResourceManagerVK());
21}
22
23ResourceManagerVK::ResourceManagerVK() : waiter_([&]() { Start(); }) {}
24
26 FML_DCHECK(waiter_.get_id() != std::this_thread::get_id())
27 << "The ResourceManager being destructed on its own spawned thread is a "
28 << "sign that ContextVK was not properly destroyed. A usual fix for this "
29 << "is to ensure that ContextVK is shutdown (i.e. context->Shutdown()) "
30 "before the ResourceManager is destroyed (i.e. at the end of a test).";
31 Terminate();
32 waiter_.join();
33}
34
35void ResourceManagerVK::Start() {
36 // It's possible for Start() to be called when terminating:
37 // { ResourceManagerVK::Create(); }
38 //
39 // ... so no FML_DCHECK here.
40
42 // While this code calls destructors it doesn't need to be particularly fast
43 // with them, as long as it doesn't interrupt raster thread.
45
46 bool should_exit = false;
47 while (!should_exit) {
48 std::unique_lock lock(reclaimables_mutex_);
49
50 // Wait until there are reclaimable resource or if the manager should be
51 // torn down.
52 reclaimables_cv_.wait(
53 lock, [&]() { return !reclaimables_.empty() || should_exit_; });
54
55 // Don't reclaim resources when the lock is being held as this may gate
56 // further reclaimables from being registered.
57 Reclaimables resources_to_collect;
58 std::swap(resources_to_collect, reclaimables_);
59
60 // We can't read the ivar outside the lock. Read it here instead.
61 should_exit = should_exit_;
62
63 // We know what to collect. Unlock before doing anything else.
64 lock.unlock();
65
66 // Claim all resources while tracing.
67 {
68 TRACE_EVENT0("Impeller", "ReclaimResources");
69 resources_to_collect.clear(); // Redundant because of scope but here so
70 // we can add a trace around it.
71 }
72 }
73}
74
75void ResourceManagerVK::Reclaim(std::unique_ptr<ResourceVK> resource) {
76 if (!resource) {
77 return;
78 }
79 {
80 std::scoped_lock lock(reclaimables_mutex_);
81 reclaimables_.emplace_back(std::move(resource));
82 }
83 reclaimables_cv_.notify_one();
84}
85
86void ResourceManagerVK::Terminate() {
87 // The thread should not be terminated more than once.
88 FML_DCHECK(!should_exit_);
89
90 {
91 std::scoped_lock lock(reclaimables_mutex_);
92 should_exit_ = true;
93 }
94 reclaimables_cv_.notify_one();
95}
96
97} // namespace impeller
static void SetCurrentThreadName(const ThreadConfig &config)
Definition thread.cc:135
A resource manager controls how resources are allocated and reclaimed.
static std::shared_ptr< ResourceManagerVK > Create()
Creates a shared resource manager (a dedicated thread).
void Reclaim(std::unique_ptr< ResourceVK > resource)
Mark a resource as being reclaimable.
~ResourceManagerVK()
Destroys the resource manager.
#define FML_DCHECK(condition)
Definition logging.h:103
@ kEfficiency
Request CPU affinity for the efficiency cores.
bool RequestAffinity(CpuAffinity affinity)
Request the given affinity for the current thread.
The ThreadConfig is the thread info include thread name, thread priority.
Definition thread.h:35
#define TRACE_EVENT0(category_group, name)