From 692af117a21b5199ba2c45053b8d0b7ae5fac249 Mon Sep 17 00:00:00 2001 From: Yuqian Li Date: Tue, 5 Mar 2019 15:09:49 -0800 Subject: [PATCH] Add read-only persistent cache --- shell/common/persistent_cache.cc | 14 +++++++++++--- shell/common/persistent_cache.h | 11 ++++++++++- shell/platform/embedder/embedder.cc | 4 ++++ shell/platform/embedder/embedder.h | 4 ++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/shell/common/persistent_cache.cc b/shell/common/persistent_cache.cc index bab0e7ac1beee..6e52a810e59ec 100644 --- a/shell/common/persistent_cache.cc +++ b/shell/common/persistent_cache.cc @@ -35,10 +35,13 @@ static std::string SkKeyToFilePath(const SkData& data) { return encode_result.second; } +bool PersistentCache::gIsReadOnly = false; + PersistentCache* PersistentCache::GetCacheForProcess() { static std::unique_ptr gPersistentCache; static std::once_flag once = {}; - std::call_once(once, []() { gPersistentCache.reset(new PersistentCache()); }); + std::call_once( + once, []() { gPersistentCache.reset(new PersistentCache(gIsReadOnly)); }); return gPersistentCache.get(); } @@ -46,7 +49,7 @@ void PersistentCache::SetCacheDirectoryPath(std::string path) { cache_base_path_ = path; } -PersistentCache::PersistentCache() { +PersistentCache::PersistentCache(bool read_only) : is_read_only_(read_only) { fml::UniqueFD cache_base_dir; if (cache_base_path_.length()) { cache_base_dir = fml::OpenDirectory(cache_base_path_.c_str(), false, @@ -60,7 +63,8 @@ PersistentCache::PersistentCache() { CreateDirectory(cache_base_dir, {"flutter_engine", blink::GetFlutterEngineVersion(), "skia", blink::GetSkiaVersion()}, - fml::FilePermission::kReadWrite)); + read_only ? fml::FilePermission::kRead + : fml::FilePermission::kReadWrite)); } if (!IsValid()) { FML_LOG(WARNING) << "Could not acquire the persistent cache directory. " @@ -130,6 +134,10 @@ static void PersistentCacheStore(fml::RefPtr worker, // |GrContextOptions::PersistentCache| void PersistentCache::store(const SkData& key, const SkData& data) { + if (is_read_only_) { + return; + } + if (!IsValid()) { return; } diff --git a/shell/common/persistent_cache.h b/shell/common/persistent_cache.h index cc65d6ad621c3..51662994dde70 100644 --- a/shell/common/persistent_cache.h +++ b/shell/common/persistent_cache.h @@ -19,6 +19,13 @@ namespace shell { class PersistentCache : public GrContextOptions::PersistentCache { public: + // Mutable static switch that can be set before GetCacheForProcess. If true, + // we'll only read existing caches but not generate new ones. Some clients + // (e.g., embedded devices) prefer generating persistent cache files for the + // specific device beforehand, and ship them as readonly files in OTA + // packages. + static bool gIsReadOnly; + static PersistentCache* GetCacheForProcess(); static void SetCacheDirectoryPath(std::string path); @@ -31,6 +38,8 @@ class PersistentCache : public GrContextOptions::PersistentCache { private: static std::string cache_base_path_; + + const bool is_read_only_; std::shared_ptr cache_directory_; mutable std::mutex worker_task_runners_mutex_; std::multiset> worker_task_runners_ @@ -38,7 +47,7 @@ class PersistentCache : public GrContextOptions::PersistentCache { bool IsValid() const; - PersistentCache(); + PersistentCache(bool read_only = false); // |GrContextOptions::PersistentCache| sk_sp load(const SkData& key) override; diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index c4d0546474411..aa397938bb957 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -348,6 +348,10 @@ FlutterEngineResult FlutterEngineRun(size_t version, shell::PersistentCache::SetCacheDirectoryPath(persistent_cache_path); } + if (SAFE_ACCESS(args, is_persistent_cache_read_only, false)) { + shell::PersistentCache::gIsReadOnly = true; + } + fml::CommandLine command_line; if (SAFE_ACCESS(args, command_line_argc, 0) != 0 && SAFE_ACCESS(args, command_line_argv, nullptr) != nullptr) { diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index bfc3002a1da3d..0be1fae740ad2 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -549,6 +549,10 @@ typedef struct { // Flutter application (such as compiled shader programs used by Skia). // This is optional. The string must be NULL terminated. const char* persistent_cache_path; + + // If true, we'll only read the existing cache, but not write new ones. + bool is_persistent_cache_read_only; + // A callback that gets invoked by the engine when it attempts to wait for a // platform vsync event. The engine will give the platform a baton that needs // to be returned back to the engine via |FlutterEngineOnVsync|. All batons