Flutter Engine
flutter::PersistentCache Class Reference

#include <persistent_cache.h>

Inheritance diagram for flutter::PersistentCache:

Public Types

using SkSLCache = std::pair< sk_sp< SkData >, sk_sp< SkData > >
 

Public Member Functions

 ~PersistentCache () override
 
void AddWorkerTaskRunner (fml::RefPtr< fml::TaskRunner > task_runner)
 
void RemoveWorkerTaskRunner (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< SkData > load (const SkData &key) override
 
std::vector< SkSLCacheLoadSkSLs ()
 Load all the SkSL shader caches in the right directory. More...
 

Static Public Member Functions

static PersistentCacheGetCacheForProcess ()
 
static void ResetCacheForProcess ()
 
static void SetCacheDirectoryPath (std::string path)
 
static std::string SkKeyToFilePath (const SkData &data)
 
static void SetAssetManager (std::shared_ptr< AssetManager > value)
 
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
 

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 28 of file persistent_cache.h.

Member Typedef Documentation

◆ SkSLCache

using flutter::PersistentCache::SkSLCache = std::pair<sk_sp<SkData>, sk_sp<SkData> >

Definition at line 72 of file persistent_cache.h.

Constructor & Destructor Documentation

◆ ~PersistentCache()

flutter::PersistentCache::~PersistentCache ( )
overridedefault

Referenced by LoadSkSLs().

Member Function Documentation

◆ AddWorkerTaskRunner()

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

Definition at line 363 of file persistent_cache.cc.

Referenced by flutter::Shell::IsSetup().

364  {
365  std::scoped_lock lock(worker_task_runners_mutex_);
366  worker_task_runners_.insert(task_runner);
367 }

◆ cache_sksl()

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

◆ DumpSkp()

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

Definition at line 345 of file persistent_cache.cc.

References FML_LOG, fml::TimePoint::Now(), flutter::PersistentCacheStore(), fml::TimePoint::ToEpochDelta(), and fml::TimeDelta::ToNanoseconds().

Referenced by flutter::Rasterizer::Draw().

345  {
346  if (is_read_only_ || !IsValid()) {
347  FML_LOG(ERROR) << "Could not dump SKP from read-only or invalid persistent "
348  "cache.";
349  return;
350  }
351 
352  std::stringstream name_stream;
354  name_stream << "shader_dump_" << std::to_string(ticks) << ".skp";
355  std::string file_name = name_stream.str();
356  FML_LOG(INFO) << "Dumping " << file_name;
357  auto mapping = std::make_unique<fml::DataMapping>(
358  std::vector<uint8_t>{data.bytes(), data.bytes() + data.size()});
359  PersistentCacheStore(GetWorkerTaskRunner(), cache_directory_,
360  std::move(file_name), std::move(mapping));
361 }
TimeDelta ToEpochDelta() const
Definition: time_point.h:40
#define FML_LOG(severity)
Definition: logging.h:65
static void PersistentCacheStore(fml::RefPtr< fml::TaskRunner > worker, std::shared_ptr< fml::UniqueFD > cache_directory, std::string key, std::unique_ptr< fml::Mapping > value)
constexpr int64_t ToNanoseconds() const
Definition: time_delta.h:61
static TimePoint Now()
Definition: time_point.cc:26

◆ GetCacheForProcess()

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

◆ IsDumpingSkp()

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

Definition at line 62 of file persistent_cache.h.

Referenced by flutter::Rasterizer::Draw().

62 { return is_dumping_skp_; }

◆ load()

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

Definition at line 271 of file persistent_cache.cc.

References SkKeyToFilePath(), and TRACE_EVENT0.

271  {
272  TRACE_EVENT0("flutter", "PersistentCacheLoad");
273  if (!IsValid()) {
274  return nullptr;
275  }
276  auto file_name = SkKeyToFilePath(key);
277  if (file_name.size() == 0) {
278  return nullptr;
279  }
280  auto result = PersistentCache::LoadFile(*cache_directory_, file_name);
281  if (result != nullptr) {
282  TRACE_EVENT0("flutter", "PersistentCacheLoadHit");
283  }
284  return result;
285 }
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
static std::string SkKeyToFilePath(const SkData &data)

◆ LoadSkSLs()

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

Load all the SkSL shader caches in the right directory.

Definition at line 182 of file persistent_cache.cc.

References FML_LOG, fml::UniqueObject< T, Traits >::is_valid(), kAssetFileName, kSkSLSubdirName, fml::OpenDirectoryReadOnly(), fml::OpenFileReadOnly(), flutter::ParseBase32(), flutter::ParseBase64(), TRACE_EVENT0, fml::VisitFiles(), and ~PersistentCache().

Referenced by flutter::testing::CheckTwoSkSLsAreLoaded(), flutter::Shell::GetMainDisplayRefreshRate(), flutter::GPUSurfaceGL::GPUSurfaceGL(), and flutter::testing::TEST_F().

182  {
183  TRACE_EVENT0("flutter", "PersistentCache::LoadSkSLs");
184  std::vector<PersistentCache::SkSLCache> result;
185  fml::FileVisitor visitor = [&result](const fml::UniqueFD& directory,
186  const std::string& filename) {
187  sk_sp<SkData> key = ParseBase32(filename);
188  sk_sp<SkData> data = LoadFile(directory, filename);
189  if (key != nullptr && data != nullptr) {
190  result.push_back({key, data});
191  } else {
192  FML_LOG(ERROR) << "Failed to load: " << filename;
193  }
194  return true;
195  };
196 
197  // Only visit sksl_cache_directory_ if this persistent cache is valid.
198  // However, we'd like to continue visit the asset dir even if this persistent
199  // cache is invalid.
200  if (IsValid()) {
201  // In case `rewinddir` doesn't work reliably, load SkSLs from a freshly
202  // opened directory (https://github.com/flutter/flutter/issues/65258).
203  fml::UniqueFD fresh_dir =
204  fml::OpenDirectoryReadOnly(*cache_directory_, kSkSLSubdirName);
205  if (fresh_dir.is_valid()) {
206  fml::VisitFiles(fresh_dir, visitor);
207  }
208  }
209 
210  std::unique_ptr<fml::Mapping> mapping = nullptr;
211  if (asset_manager_ != nullptr) {
212  mapping = asset_manager_->GetAsMapping(kAssetFileName);
213  }
214  if (mapping == nullptr) {
215  FML_LOG(INFO) << "No sksl asset found.";
216  } else {
217  FML_LOG(INFO) << "Found sksl asset. Loading SkSLs from it...";
218  rapidjson::Document json_doc;
219  rapidjson::ParseResult parse_result =
220  json_doc.Parse(reinterpret_cast<const char*>(mapping->GetMapping()),
221  mapping->GetSize());
222  if (parse_result != rapidjson::ParseErrorCode::kParseErrorNone) {
223  FML_LOG(ERROR) << "Failed to parse json file: " << kAssetFileName;
224  } else {
225  for (auto& item : json_doc["data"].GetObject()) {
226  sk_sp<SkData> key = ParseBase32(item.name.GetString());
227  sk_sp<SkData> sksl = ParseBase64(item.value.GetString());
228  if (key != nullptr && sksl != nullptr) {
229  result.push_back({key, sksl});
230  } else {
231  FML_LOG(ERROR) << "Failed to load: " << item.name.GetString();
232  }
233  }
234  }
235  }
236 
237  return result;
238 }
sk_sp< SkData > ParseBase64(const std::string &input)
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
std::function< bool(const fml::UniqueFD &directory, const std::string &filename)> FileVisitor
Definition: file.h:98
sk_sp< SkData > ParseBase32(const std::string &input)
#define FML_LOG(severity)
Definition: logging.h:65
static constexpr char kAssetFileName[]
bool is_valid() const
Definition: unique_object.h:89
static constexpr char kSkSLSubdirName[]
bool VisitFiles(const fml::UniqueFD &directory, const FileVisitor &visitor)
Definition: file_posix.cc:233
fml::UniqueFD OpenDirectoryReadOnly(const fml::UniqueFD &base_directory, const char *path)
Definition: file.cc:97

◆ MarkStrategySet()

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

◆ Purge()

bool flutter::PersistentCache::Purge ( )

Definition at line 81 of file persistent_cache.cc.

References cache_sksl(), fml::CreateDirectory(), FML_CHECK, FML_LOG, fml::paths::GetCachesDirectory(), flutter::GetFlutterEngineVersion(), flutter::GetSkiaVersion(), fml::UniqueObject< T, Traits >::is_valid(), fml::IsDirectory(), fml::kRead, fml::kReadWrite, kSkSLSubdirName, fml::OpenDirectory(), fml::OpenDirectoryReadOnly(), fml::TaskRunner::PostTask(), fml::RemoveDirectoryRecursively(), fml::UnlinkFile(), fml::VisitFiles(), and fml::VisitFilesRecursively().

Referenced by flutter::Shell::IsSetup().

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

◆ RemoveWorkerTaskRunner()

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

Definition at line 369 of file persistent_cache.cc.

Referenced by flutter::Shell::~Shell().

370  {
371  std::scoped_lock lock(worker_task_runners_mutex_);
372  auto found = worker_task_runners_.find(task_runner);
373  if (found != worker_task_runners_.end()) {
374  worker_task_runners_.erase(found);
375  }
376 }

◆ ResetCacheForProcess()

void flutter::PersistentCache::ResetCacheForProcess ( )
static

Definition at line 71 of file persistent_cache.cc.

References gIsReadOnly.

Referenced by flutter::testing::TEST_F().

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

◆ ResetStoredNewShaders()

void flutter::PersistentCache::ResetStoredNewShaders ( )
inline

Definition at line 60 of file persistent_cache.h.

Referenced by flutter::Rasterizer::Draw().

60 { 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 389 of file persistent_cache.cc.

References TRACE_EVENT_INSTANT0, and value.

Referenced by flutter::testing::ResetAssetManager(), and flutter::RunConfiguration::RunConfiguration().

389  {
390  TRACE_EVENT_INSTANT0("flutter", "PersistentCache::SetAssetManager");
391  asset_manager_ = value;
392 }
#define TRACE_EVENT_INSTANT0(category_group, name)
Definition: trace_event.h:104
uint8_t value

◆ SetCacheDirectoryPath()

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

Definition at line 77 of file persistent_cache.cc.

References flutter::path.

Referenced by FlutterEngineInitialize(), and flutter::testing::TEST_F().

77  {
78  cache_base_path_ = path;
79 }
DEF_SWITCHES_START snapshot asset path
Definition: switches.h:32

◆ SetCacheSkSL()

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

Definition at line 54 of file persistent_cache.cc.

References FML_LOG, and value.

Referenced by flutter::Shell::Create().

54  {
55  if (strategy_set_ && value != cache_sksl_) {
56  FML_LOG(ERROR) << "Cache SkSL can only be set before the "
57  "GrContextOptions::fShaderCacheStrategy is set.";
58  return;
59  }
60  cache_sksl_ = value;
61 }
#define FML_LOG(severity)
Definition: logging.h:65
uint8_t value

◆ SetIsDumpingSkp()

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

Definition at line 63 of file persistent_cache.h.

References value.

Referenced by flutter::Shell::IsSetup().

63 { is_dumping_skp_ = value; }
uint8_t value

◆ SkKeyToFilePath()

std::string flutter::PersistentCache::SkKeyToFilePath ( const SkData &  data)
static

Definition at line 32 of file persistent_cache.cc.

References fml::Base32Encode(), and gIsReadOnly.

Referenced by flutter::Shell::GetMainDisplayRefreshRate(), load(), flutter::PersistentCacheStore(), and flutter::testing::TEST_F().

32  {
33  if (data.data() == nullptr || data.size() == 0) {
34  return "";
35  }
36 
37  std::string_view view(reinterpret_cast<const char*>(data.data()),
38  data.size());
39 
40  auto encode_result = fml::Base32Encode(view);
41 
42  if (!encode_result.first) {
43  return "";
44  }
45 
46  return encode_result.second;
47 }
std::pair< bool, std::string > Base32Encode(std::string_view input)
Definition: base32.cc:14

◆ StoredNewShaders()

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

Definition at line 59 of file persistent_cache.h.

Referenced by flutter::Rasterizer::Draw().

59 { return stored_new_shaders_; }

Friends And Related Function Documentation

◆ testing::ShellTest

friend class testing::ShellTest
friend

Definition at line 127 of file persistent_cache.h.

Member Data Documentation

◆ gIsReadOnly

bool flutter::PersistentCache::gIsReadOnly = false
static

◆ kAssetFileName

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

Definition at line 86 of file persistent_cache.h.

Referenced by LoadSkSLs(), and flutter::testing::TEST_F().

◆ kSkSLSubdirName

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

Definition at line 85 of file persistent_cache.h.

Referenced by LoadSkSLs(), Purge(), and flutter::testing::TEST_F().


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