Skip to content

Commit

Permalink
Add read-only persistent cache (flutter#8049)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
liyuqian authored Mar 8, 2019
1 parent 4c94049 commit 87edd94
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 4 deletions.
14 changes: 11 additions & 3 deletions shell/common/persistent_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,21 @@ static std::string SkKeyToFilePath(const SkData& data) {
return encode_result.second;
}

bool PersistentCache::gIsReadOnly = false;

PersistentCache* PersistentCache::GetCacheForProcess() {
static std::unique_ptr<PersistentCache> 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();
}

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,
Expand All @@ -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. "
Expand Down Expand Up @@ -130,6 +134,10 @@ static void PersistentCacheStore(fml::RefPtr<fml::TaskRunner> worker,

// |GrContextOptions::PersistentCache|
void PersistentCache::store(const SkData& key, const SkData& data) {
if (is_read_only_) {
return;
}

if (!IsValid()) {
return;
}
Expand Down
11 changes: 10 additions & 1 deletion shell/common/persistent_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -31,14 +38,16 @@ class PersistentCache : public GrContextOptions::PersistentCache {

private:
static std::string cache_base_path_;

const bool is_read_only_;
std::shared_ptr<fml::UniqueFD> cache_directory_;
mutable std::mutex worker_task_runners_mutex_;
std::multiset<fml::RefPtr<fml::TaskRunner>> worker_task_runners_
FML_GUARDED_BY(worker_task_runners_mutex_);

bool IsValid() const;

PersistentCache();
PersistentCache(bool read_only = false);

// |GrContextOptions::PersistentCache|
sk_sp<SkData> load(const SkData& key) override;
Expand Down
4 changes: 4 additions & 0 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 4 additions & 0 deletions shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 87edd94

Please sign in to comment.