Flutter Engine
The Flutter Engine
Classes | Public Member Functions | Static Public Member Functions | Static Public Attributes | Friends | List of all members
flutter::PersistentCache Class Reference

#include <persistent_cache.h>

Inheritance diagram for flutter::PersistentCache:
GrContextOptions::PersistentCache

Classes

struct  CacheObjectHeader
 
struct  SkSLCache
 

Public Member Functions

 ~PersistentCache () override
 
void AddWorkerTaskRunner (const fml::RefPtr< fml::TaskRunner > &task_runner)
 
void RemoveWorkerTaskRunner (const fml::RefPtr< fml::TaskRunner > &task_runner)
 
bool StoredNewShaders () const
 
void ResetStoredNewShaders ()
 
void DumpSkp (const SkData &data)
 
bool IsDumpingSkp () const
 
void SetIsDumpingSkp (bool value)
 
bool Purge ()
 
sk_sp< SkDataload (const SkData &key) override
 
std::vector< SkSLCacheLoadSkSLs () const
 Load all the SkSL shader caches in the right directory. More...
 
size_t PrecompileKnownSkSLs (GrDirectContext *context) const
 Precompile SkSLs packaged with the application and gathered during previous runs in the given context. More...
 
std::vector< std::unique_ptr< fml::Mapping > > GetSkpsFromAssetManager () const
 
- Public Member Functions inherited from GrContextOptions::PersistentCache
virtual ~PersistentCache ()=default
 
virtual sk_sp< SkDataload (const SkData &key)=0
 
virtual void store (const SkData &, const SkData &)
 
virtual void store (const SkData &key, const SkData &data, const SkString &)
 

Static Public Member Functions

static PersistentCacheGetCacheForProcess ()
 
static void ResetCacheForProcess ()
 
static void SetCacheDirectoryPath (std::string path)
 
static std::string SkKeyToFilePath (const SkData &key)
 
static std::unique_ptr< fml::MallocMappingBuildCacheObject (const SkData &key, const SkData &data)
 
static void SetAssetManager (std::shared_ptr< AssetManager > value)
 
static std::shared_ptr< AssetManagerasset_manager ()
 
static bool cache_sksl ()
 
static void SetCacheSkSL (bool value)
 
static void MarkStrategySet ()
 

Static Public Attributes

static bool gIsReadOnly = false
 
static constexpr char kSkSLSubdirName [] = "sksl"
 
static constexpr char kAssetFileName [] = "io.flutter.shaders.json"
 

Friends

class testing::ShellTest
 

Additional Inherited Members

- Protected Member Functions inherited from GrContextOptions::PersistentCache
 PersistentCache ()=default
 
 PersistentCache (const PersistentCache &)=delete
 
PersistentCacheoperator= (const PersistentCache &)=delete
 

Detailed Description

A cache of SkData that gets stored to disk.

This is mainly used for Shaders but is also written to by Dart. It is thread-safe for reading and writing from multiple threads.

Definition at line 32 of file persistent_cache.h.

Constructor & Destructor Documentation

◆ ~PersistentCache()

flutter::PersistentCache::~PersistentCache ( )
overridevirtualdefault

Reimplemented from GrContextOptions::PersistentCache.

Member Function Documentation

◆ AddWorkerTaskRunner()

void flutter::PersistentCache::AddWorkerTaskRunner ( const fml::RefPtr< fml::TaskRunner > &  task_runner)

Definition at line 446 of file persistent_cache.cc.

447 {
448 std::scoped_lock lock(worker_task_runners_mutex_);
449 worker_task_runners_.insert(task_runner);
450}

◆ asset_manager()

static std::shared_ptr< AssetManager > flutter::PersistentCache::asset_manager ( )
inlinestatic

Definition at line 124 of file persistent_cache.h.

124 {
125 return asset_manager_;
126 }

◆ BuildCacheObject()

std::unique_ptr< fml::MallocMapping > flutter::PersistentCache::BuildCacheObject ( const SkData key,
const SkData data 
)
static

Definition at line 380 of file persistent_cache.cc.

382 {
383 size_t total_size = sizeof(CacheObjectHeader) + key.size() + data.size();
384 uint8_t* mapping_buf = reinterpret_cast<uint8_t*>(malloc(total_size));
385 if (!mapping_buf) {
386 return nullptr;
387 }
388 auto mapping = std::make_unique<fml::MallocMapping>(mapping_buf, total_size);
389
390 CacheObjectHeader header(key.size());
391 memcpy(mapping_buf, &header, sizeof(CacheObjectHeader));
392 mapping_buf += sizeof(CacheObjectHeader);
393 memcpy(mapping_buf, key.data(), key.size());
394 mapping_buf += key.size();
395 memcpy(mapping_buf, data.data(), data.size());
396
397 return mapping;
398}
static size_t total_size(SkSBlockAllocator< N > &pool)
void * malloc(size_t size)
Definition: allocation.cc:19
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition: switches.h:41
static const char header[]
Definition: skpbench.cpp:88

◆ cache_sksl()

static bool flutter::PersistentCache::cache_sksl ( )
inlinestatic

Definition at line 128 of file persistent_cache.h.

128{ return cache_sksl_; }

◆ DumpSkp()

void flutter::PersistentCache::DumpSkp ( const SkData data)

Definition at line 428 of file persistent_cache.cc.

428 {
429 if (is_read_only_ || !IsValid()) {
430 FML_LOG(ERROR) << "Could not dump SKP from read-only or invalid persistent "
431 "cache.";
432 return;
433 }
434
435 std::stringstream name_stream;
437 name_stream << "shader_dump_" << std::to_string(ticks) << ".skp";
438 std::string file_name = name_stream.str();
439 FML_LOG(INFO) << "Dumping " << file_name;
440 auto mapping = std::make_unique<fml::DataMapping>(
441 std::vector<uint8_t>{data.bytes(), data.bytes() + data.size()});
442 PersistentCacheStore(GetWorkerTaskRunner(), cache_directory_,
443 std::move(file_name), std::move(mapping));
444}
constexpr int64_t ToNanoseconds() const
Definition: time_delta.h:61
TimeDelta ToEpochDelta() const
Definition: time_point.h:52
static TimePoint Now()
Definition: time_point.cc:49
#define FML_LOG(severity)
Definition: logging.h:82
static void PersistentCacheStore(const fml::RefPtr< fml::TaskRunner > &worker, const std::shared_ptr< fml::UniqueFD > &cache_directory, std::string key, std::unique_ptr< fml::Mapping > value)
static SkString to_string(int n)
Definition: nanobench.cpp:119
#define ERROR(message)
Definition: elf_loader.cc:260

◆ GetCacheForProcess()

PersistentCache * flutter::PersistentCache::GetCacheForProcess ( )
static

Definition at line 65 of file persistent_cache.cc.

65 {
66 std::scoped_lock lock(instance_mutex_);
67 if (gPersistentCache == nullptr) {
68 gPersistentCache.reset(new PersistentCache(gIsReadOnly));
69 }
70 return gPersistentCache.get();
71}

◆ GetSkpsFromAssetManager()

std::vector< std::unique_ptr< fml::Mapping > > flutter::PersistentCache::GetSkpsFromAssetManager ( ) const

Definition at line 478 of file persistent_cache.cc.

478 {
479 if (!asset_manager_) {
481 << "PersistentCache::GetSkpsFromAssetManager: Asset manager not set!";
482 return std::vector<std::unique_ptr<fml::Mapping>>();
483 }
484 return asset_manager_->GetAsMappings(".*\\.skp$", "shaders");
485}

◆ IsDumpingSkp()

bool flutter::PersistentCache::IsDumpingSkp ( ) const
inline

Definition at line 85 of file persistent_cache.h.

85{ return is_dumping_skp_; }

◆ load()

sk_sp< SkData > flutter::PersistentCache::load ( const SkData key)
overridevirtual

Returns the data for the key if it exists in the cache, otherwise returns null.

Implements GrContextOptions::PersistentCache.

Definition at line 332 of file persistent_cache.cc.

332 {
333 TRACE_EVENT0("flutter", "PersistentCacheLoad");
334 if (!IsValid()) {
335 return nullptr;
336 }
337 auto file_name = SkKeyToFilePath(key);
338 if (file_name.empty()) {
339 return nullptr;
340 }
341 auto result =
342 PersistentCache::LoadFile(*cache_directory_, file_name, false).value;
343 if (result != nullptr) {
344 TRACE_EVENT0("flutter", "PersistentCacheLoadHit");
345 }
346 return result;
347}
static std::string SkKeyToFilePath(const SkData &key)
GAsyncResult * result
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131

◆ LoadSkSLs()

std::vector< PersistentCache::SkSLCache > flutter::PersistentCache::LoadSkSLs ( ) const

Load all the SkSL shader caches in the right directory.

Definition at line 223 of file persistent_cache.cc.

223 {
224 TRACE_EVENT0("flutter", "PersistentCache::LoadSkSLs");
225 std::vector<PersistentCache::SkSLCache> result;
226 fml::FileVisitor visitor = [&result](const fml::UniqueFD& directory,
227 const std::string& filename) {
228 SkSLCache cache = LoadFile(directory, filename, true);
229 if (cache.key != nullptr && cache.value != nullptr) {
230 result.push_back(cache);
231 } else {
232 FML_LOG(ERROR) << "Failed to load: " << filename;
233 }
234 return true;
235 };
236
237 // Only visit sksl_cache_directory_ if this persistent cache is valid.
238 // However, we'd like to continue visit the asset dir even if this persistent
239 // cache is invalid.
240 if (IsValid()) {
241 // In case `rewinddir` doesn't work reliably, load SkSLs from a freshly
242 // opened directory (https://github.com/flutter/flutter/issues/65258).
243 fml::UniqueFD fresh_dir =
245 if (fresh_dir.is_valid()) {
246 fml::VisitFiles(fresh_dir, visitor);
247 }
248 }
249
250 std::unique_ptr<fml::Mapping> mapping = nullptr;
251 if (asset_manager_ != nullptr) {
252 mapping = asset_manager_->GetAsMapping(kAssetFileName);
253 }
254 if (mapping == nullptr) {
255 FML_LOG(INFO) << "No sksl asset found.";
256 } else {
257 FML_LOG(INFO) << "Found sksl asset. Loading SkSLs from it...";
258 rapidjson::Document json_doc;
259 rapidjson::ParseResult parse_result =
260 json_doc.Parse(reinterpret_cast<const char*>(mapping->GetMapping()),
261 mapping->GetSize());
262 if (parse_result.IsError()) {
263 FML_LOG(ERROR) << "Failed to parse json file: " << kAssetFileName;
264 } else {
265 for (auto& item : json_doc["data"].GetObject()) {
266 sk_sp<SkData> key = ParseBase32(item.name.GetString());
267 sk_sp<SkData> sksl = ParseBase64(item.value.GetString());
268 if (key != nullptr && sksl != nullptr) {
269 result.push_back({key, sksl});
270 } else {
271 FML_LOG(ERROR) << "Failed to load: " << item.name.GetString();
272 }
273 }
274 }
275 }
276
277 return result;
278}
static constexpr char kSkSLSubdirName[]
static constexpr char kAssetFileName[]
bool is_valid() const
Definition: unique_object.h:89
static void GetObject(Thread *thread, JSONStream *js)
Definition: service.cc:5046
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 defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent cache
Definition: switches.h:191
sk_sp< SkData > ParseBase32(const std::string &input)
sk_sp< SkData > ParseBase64(const std::string &input)
bool VisitFiles(const fml::UniqueFD &directory, const FileVisitor &visitor)
Definition: file_posix.cc:236
fml::UniqueFD OpenDirectoryReadOnly(const fml::UniqueFD &base_directory, const char *path)
Definition: file.cc:97
std::function< bool(const fml::UniqueFD &directory, const std::string &filename)> FileVisitor
Definition: file.h:98

◆ MarkStrategySet()

static void flutter::PersistentCache::MarkStrategySet ( )
inlinestatic

Definition at line 132 of file persistent_cache.h.

132{ strategy_set_ = true; }

◆ PrecompileKnownSkSLs()

size_t flutter::PersistentCache::PrecompileKnownSkSLs ( GrDirectContext context) const

Precompile SkSLs packaged with the application and gathered during previous runs in the given context.

Warning
The context must be the rendering context. This context may be destroyed during application suspension and subsequently recreated. The SkSLs must be precompiled again in the new context.
Parameters
contextThe rendering context to precompile shaders in.
Returns
The number of SkSLs precompiled.

Definition at line 196 of file persistent_cache.cc.

196 {
197 // clang-tidy has trouble reasoning about some of the complicated array and
198 // pointer-arithmetic code in rapidjson.
199 // NOLINTNEXTLINE(clang-analyzer-cplusplus.PlacementNew)
200 auto known_sksls = LoadSkSLs();
201 // A trace must be present even if no precompilations have been completed.
202 FML_TRACE_EVENT("flutter", "PersistentCache::PrecompileKnownSkSLs", "count",
203 known_sksls.size());
204
205 if (context == nullptr) {
206 return 0;
207 }
208
209 size_t precompiled_count = 0;
210 for (const auto& sksl : known_sksls) {
211 TRACE_EVENT0("flutter", "PrecompilingSkSL");
212 if (context->precompileShader(*sksl.key, *sksl.value)) {
213 precompiled_count++;
214 }
215 }
216
217 FML_TRACE_COUNTER("flutter", "PersistentCache::PrecompiledSkSLs",
218 reinterpret_cast<int64_t>(this), // Trace Counter ID
219 "Successful", precompiled_count);
220 return precompiled_count;
221}
bool precompileShader(const SkData &key, const SkData &data)
std::vector< SkSLCache > LoadSkSLs() const
Load all the SkSL shader caches in the right directory.
#define FML_TRACE_COUNTER(category_group, name, counter_id, arg1,...)
Definition: trace_event.h:85
#define FML_TRACE_EVENT(category_group, name,...)
Definition: trace_event.h:121

◆ Purge()

bool flutter::PersistentCache::Purge ( )

Definition at line 83 of file persistent_cache.cc.

83 {
84 // Make sure that this is called after the worker task runner setup so all the
85 // file system modifications would happen on that single thread to avoid
86 // racing.
87 FML_CHECK(GetWorkerTaskRunner());
88
89 std::promise<bool> removed;
90 GetWorkerTaskRunner()->PostTask([&removed,
91 cache_directory = cache_directory_]() {
92 if (cache_directory->is_valid()) {
93 // Only remove files but not directories.
94 FML_LOG(INFO) << "Purge persistent cache.";
95 fml::FileVisitor delete_file = [](const fml::UniqueFD& directory,
96 const std::string& filename) {
97 // Do not delete directories. Return true to continue with other files.
98 if (fml::IsDirectory(directory, filename.c_str())) {
99 return true;
100 }
101 return fml::UnlinkFile(directory, filename.c_str());
102 };
103 removed.set_value(VisitFilesRecursively(*cache_directory, delete_file));
104 } else {
105 removed.set_value(false);
106 }
107 });
108 return removed.get_future().get();
109}
virtual void PostTask(const fml::closure &task) override
Definition: task_runner.cc:24
#define FML_CHECK(condition)
Definition: logging.h:85
bool VisitFilesRecursively(const fml::UniqueFD &directory, const FileVisitor &visitor)
Definition: file.cc:71

◆ RemoveWorkerTaskRunner()

void flutter::PersistentCache::RemoveWorkerTaskRunner ( const fml::RefPtr< fml::TaskRunner > &  task_runner)

Definition at line 452 of file persistent_cache.cc.

453 {
454 std::scoped_lock lock(worker_task_runners_mutex_);
455 auto found = worker_task_runners_.find(task_runner);
456 if (found != worker_task_runners_.end()) {
457 worker_task_runners_.erase(found);
458 }
459}

◆ ResetCacheForProcess()

void flutter::PersistentCache::ResetCacheForProcess ( )
static

Definition at line 73 of file persistent_cache.cc.

73 {
74 std::scoped_lock lock(instance_mutex_);
75 gPersistentCache.reset(new PersistentCache(gIsReadOnly));
76 strategy_set_ = false;
77}

◆ ResetStoredNewShaders()

void flutter::PersistentCache::ResetStoredNewShaders ( )
inline

Definition at line 83 of file persistent_cache.h.

83{ stored_new_shaders_ = false; }

◆ SetAssetManager()

void flutter::PersistentCache::SetAssetManager ( std::shared_ptr< AssetManager value)
static

Set the asset manager from which PersistentCache can load SkLSs. A nullptr can be provided to clear the asset manager.

Definition at line 472 of file persistent_cache.cc.

472 {
473 TRACE_EVENT_INSTANT0("flutter", "PersistentCache::SetAssetManager");
474 asset_manager_ = std::move(value);
475}
uint8_t value
#define TRACE_EVENT_INSTANT0(category_group, name)
Definition: trace_event.h:175

◆ SetCacheDirectoryPath()

void flutter::PersistentCache::SetCacheDirectoryPath ( std::string  path)
static

Definition at line 79 of file persistent_cache.cc.

79 {
80 cache_base_path_ = std::move(path);
81}
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
Definition: switches.h:57

◆ SetCacheSkSL()

void flutter::PersistentCache::SetCacheSkSL ( bool  value)
static

Definition at line 56 of file persistent_cache.cc.

56 {
57 if (strategy_set_ && value != cache_sksl_) {
58 FML_LOG(ERROR) << "Cache SkSL can only be set before the "
59 "GrContextOptions::fShaderCacheStrategy is set.";
60 return;
61 }
62 cache_sksl_ = value;
63}

◆ SetIsDumpingSkp()

void flutter::PersistentCache::SetIsDumpingSkp ( bool  value)
inline

Definition at line 86 of file persistent_cache.h.

86{ is_dumping_skp_ = value; }

◆ SkKeyToFilePath()

std::string flutter::PersistentCache::SkKeyToFilePath ( const SkData key)
static

Definition at line 38 of file persistent_cache.cc.

38 {
39 if (key.data() == nullptr || key.size() == 0) {
40 return "";
41 }
42
43 uint8_t sha_digest[SHA_DIGEST_LENGTH];
44 SHA1(static_cast<const uint8_t*>(key.data()), key.size(), sha_digest);
45
46 std::string_view view(reinterpret_cast<const char*>(sha_digest),
47 SHA_DIGEST_LENGTH);
48 return fml::HexEncode(view);
49}
std::string HexEncode(std::string_view input)
Definition: hex_codec.cc:14

◆ StoredNewShaders()

bool flutter::PersistentCache::StoredNewShaders ( ) const
inline

Definition at line 82 of file persistent_cache.h.

82{ return stored_new_shaders_; }

Friends And Related Function Documentation

◆ testing::ShellTest

friend class testing::ShellTest
friend

Definition at line 177 of file persistent_cache.h.

Member Data Documentation

◆ gIsReadOnly

bool flutter::PersistentCache::gIsReadOnly = false
static

Definition at line 39 of file persistent_cache.h.

◆ kAssetFileName

constexpr char flutter::PersistentCache::kAssetFileName[] = "io.flutter.shaders.json"
staticconstexpr

Definition at line 135 of file persistent_cache.h.

◆ kSkSLSubdirName

constexpr char flutter::PersistentCache::kSkSLSubdirName[] = "sksl"
staticconstexpr

Definition at line 134 of file persistent_cache.h.


The documentation for this class was generated from the following files: