9
9
10
10
#include " flutter/fml/base32.h"
11
11
#include " flutter/fml/file.h"
12
+ #include " flutter/fml/make_copyable.h"
12
13
#include " flutter/fml/mapping.h"
13
14
#include " flutter/fml/paths.h"
14
15
#include " flutter/fml/trace_event.h"
@@ -40,33 +41,38 @@ PersistentCache* PersistentCache::GetCacheForProcess() {
40
41
}
41
42
42
43
PersistentCache::PersistentCache ()
43
- : cache_directory_(CreateDirectory(fml::paths::GetCachesDirectory(),
44
- {
45
- " flutter_engine" , //
46
- GetFlutterEngineVersion (), //
47
- " skia" , //
48
- GetSkiaVersion () //
49
- },
50
- fml::FilePermission::kReadWrite )) {
51
- if (!cache_directory_.is_valid ()) {
44
+ : cache_directory_(std::make_shared<fml::UniqueFD>(
45
+ CreateDirectory (fml::paths::GetCachesDirectory(),
46
+ {
47
+ " flutter_engine" , //
48
+ GetFlutterEngineVersion (), //
49
+ " skia" , //
50
+ GetSkiaVersion () //
51
+ },
52
+ fml::FilePermission::kReadWrite ))) {
53
+ if (!IsValid ()) {
52
54
FML_LOG (ERROR) << " Could not acquire the persistent cache directory. "
53
55
" Caching of GPU resources on disk is disabled." ;
54
56
}
55
57
}
56
58
57
59
PersistentCache::~PersistentCache () = default ;
58
60
61
+ bool PersistentCache::IsValid () const {
62
+ return cache_directory_ && cache_directory_->is_valid ();
63
+ }
64
+
59
65
// |GrContextOptions::PersistentCache|
60
66
sk_sp<SkData> PersistentCache::load (const SkData& key) {
61
67
TRACE_EVENT0 (" flutter" , " PersistentCacheLoad" );
62
- if (!cache_directory_. is_valid ()) {
68
+ if (!IsValid ()) {
63
69
return nullptr ;
64
70
}
65
71
auto file_name = SkKeyToFilePath (key);
66
72
if (file_name.size () == 0 ) {
67
73
return nullptr ;
68
74
}
69
- auto file = fml::OpenFile (cache_directory_, file_name.c_str (), false ,
75
+ auto file = fml::OpenFile (* cache_directory_, file_name.c_str (), false ,
70
76
fml::FilePermission::kRead );
71
77
if (!file.is_valid ()) {
72
78
return nullptr ;
@@ -80,23 +86,81 @@ sk_sp<SkData> PersistentCache::load(const SkData& key) {
80
86
return SkData::MakeWithCopy (mapping->GetMapping (), mapping->GetSize ());
81
87
}
82
88
89
+ static void PersistentCacheStore (fml::RefPtr<fml::TaskRunner> worker,
90
+ std::shared_ptr<fml::UniqueFD> cache_directory,
91
+ std::string key,
92
+ std::unique_ptr<fml::Mapping> value) {
93
+ auto task = fml::MakeCopyable ([cache_directory, //
94
+ file_name = std::move (key), //
95
+ mapping = std::move (value) //
96
+ ]() mutable {
97
+ TRACE_EVENT0 (" flutter" , " PersistentCacheStore" );
98
+ if (!fml::WriteAtomically (*cache_directory, //
99
+ file_name.c_str (), //
100
+ *mapping) //
101
+ ) {
102
+ FML_DLOG (ERROR) << " Could not write cache contents to persistent store." ;
103
+ }
104
+ });
105
+
106
+ if (!worker) {
107
+ FML_LOG (ERROR)
108
+ << " The persistent cache has no available workers. Performing the task "
109
+ " on the current thread. This slow operation is going to occur on a "
110
+ " frame workload." ;
111
+ task ();
112
+ } else {
113
+ worker->PostTask (std::move (task));
114
+ }
115
+ }
116
+
83
117
// |GrContextOptions::PersistentCache|
84
118
void PersistentCache::store (const SkData& key, const SkData& data) {
85
- TRACE_EVENT0 (" flutter" , " PersistentCacheStore" );
86
- if (!cache_directory_.is_valid ()) {
119
+ if (!IsValid ()) {
87
120
return ;
88
121
}
89
122
90
123
auto file_name = SkKeyToFilePath (key);
91
- auto mapping =
92
- std::make_unique<fml::NonOwnedMapping>(data.bytes (), data.size ());
93
-
94
- if (!fml::WriteAtomically (cache_directory_, //
95
- file_name.c_str (), //
96
- *mapping) //
97
- ) {
98
- FML_DLOG (ERROR) << " Could not write cache contents to persistent store." ;
124
+
125
+ if (file_name.size () == 0 ) {
126
+ return ;
127
+ }
128
+
129
+ auto mapping = std::make_unique<fml::DataMapping>(
130
+ std::vector<uint8_t >{data.bytes (), data.bytes () + data.size ()});
131
+
132
+ if (mapping == nullptr || mapping->GetSize () == 0 ) {
133
+ return ;
99
134
}
135
+
136
+ PersistentCacheStore (GetWorkerTaskRunner (), cache_directory_,
137
+ std::move (file_name), std::move (mapping));
138
+ }
139
+
140
+ void PersistentCache::AddWorkerTaskRunner (
141
+ fml::RefPtr<fml::TaskRunner> task_runner) {
142
+ std::lock_guard<std::mutex> lock (worker_task_runners_mutex_);
143
+ worker_task_runners_.insert (task_runner);
144
+ }
145
+
146
+ void PersistentCache::RemoveWorkerTaskRunner (
147
+ fml::RefPtr<fml::TaskRunner> task_runner) {
148
+ std::lock_guard<std::mutex> lock (worker_task_runners_mutex_);
149
+ auto found = worker_task_runners_.find (task_runner);
150
+ if (found != worker_task_runners_.end ()) {
151
+ worker_task_runners_.erase (found);
152
+ }
153
+ }
154
+
155
+ fml::RefPtr<fml::TaskRunner> PersistentCache::GetWorkerTaskRunner () const {
156
+ fml::RefPtr<fml::TaskRunner> worker;
157
+
158
+ std::lock_guard<std::mutex> lock (worker_task_runners_mutex_);
159
+ if (!worker_task_runners_.empty ()) {
160
+ worker = *worker_task_runners_.begin ();
161
+ }
162
+
163
+ return worker;
100
164
}
101
165
102
166
} // namespace shell
0 commit comments