Flutter Engine
persistent_cache.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_SHELL_COMMON_PERSISTENT_CACHE_H_
6 #define FLUTTER_SHELL_COMMON_PERSISTENT_CACHE_H_
7 
8 #include <memory>
9 #include <mutex>
10 #include <set>
11 
12 #include "flutter/assets/asset_manager.h"
13 #include "flutter/fml/macros.h"
14 #include "flutter/fml/task_runner.h"
15 #include "flutter/fml/unique_fd.h"
16 #include "third_party/skia/include/gpu/GrContextOptions.h"
17 
18 namespace testing {
19 class ShellTest;
20 }
21 
22 namespace flutter {
23 
24 /// A cache of SkData that gets stored to disk.
25 ///
26 /// This is mainly used for Shaders but is also written to by Dart. It is
27 /// thread-safe for reading and writing from multiple threads.
28 class PersistentCache : public GrContextOptions::PersistentCache {
29  public:
30  // Mutable static switch that can be set before GetCacheForProcess. If true,
31  // we'll only read existing caches but not generate new ones. Some clients
32  // (e.g., embedded devices) prefer generating persistent cache files for the
33  // specific device beforehand, and ship them as readonly files in OTA
34  // packages.
35  static bool gIsReadOnly;
36 
37  static PersistentCache* GetCacheForProcess();
38  static void ResetCacheForProcess();
39 
40  // This must be called before |GetCacheForProcess|. Otherwise, it won't
41  // affect the cache directory returned by |GetCacheForProcess|.
42  static void SetCacheDirectoryPath(std::string path);
43 
44  // Convert a binary SkData key into a Base32 encoded string.
45  //
46  // This is used to specify persistent cache filenames and service protocol
47  // json keys.
48  static std::string SkKeyToFilePath(const SkData& data);
49 
50  ~PersistentCache() override;
51 
52  void AddWorkerTaskRunner(fml::RefPtr<fml::TaskRunner> task_runner);
53 
54  void RemoveWorkerTaskRunner(fml::RefPtr<fml::TaskRunner> task_runner);
55 
56  // Whether Skia tries to store any shader into this persistent cache after
57  // |ResetStoredNewShaders| is called. This flag is usually reset before each
58  // frame so we can know if Skia tries to compile new shaders in that frame.
59  bool StoredNewShaders() const { return stored_new_shaders_; }
60  void ResetStoredNewShaders() { stored_new_shaders_ = false; }
61  void DumpSkp(const SkData& data);
62  bool IsDumpingSkp() const { return is_dumping_skp_; }
63  void SetIsDumpingSkp(bool value) { is_dumping_skp_ = value; }
64 
65  // Remove all files inside the persistent cache directory.
66  // Return whether the purge is successful.
67  bool Purge();
68 
69  // |GrContextOptions::PersistentCache|
70  sk_sp<SkData> load(const SkData& key) override;
71 
72  using SkSLCache = std::pair<sk_sp<SkData>, sk_sp<SkData>>;
73 
74  /// Load all the SkSL shader caches in the right directory.
75  std::vector<SkSLCache> LoadSkSLs();
76 
77  /// Set the asset manager from which PersistentCache can load SkLSs. A nullptr
78  /// can be provided to clear the asset manager.
79  static void SetAssetManager(std::shared_ptr<AssetManager> value);
80 
81  static bool cache_sksl() { return cache_sksl_; }
82  static void SetCacheSkSL(bool value);
83  static void MarkStrategySet() { strategy_set_ = true; }
84 
85  static constexpr char kSkSLSubdirName[] = "sksl";
86  static constexpr char kAssetFileName[] = "io.flutter.shaders.json";
87 
88  private:
89  static std::string cache_base_path_;
90 
91  static std::shared_ptr<AssetManager> asset_manager_;
92 
93  static std::mutex instance_mutex_;
94  static std::unique_ptr<PersistentCache> gPersistentCache;
95 
96  // Mutable static switch that can be set before GetCacheForProcess is called
97  // and GrContextOptions.fShaderCacheStrategy is set. If true, it means that
98  // we'll set `GrContextOptions::fShaderCacheStrategy` to `kSkSL`, and all the
99  // persistent cache should be stored and loaded from the "sksl" directory.
100  static std::atomic<bool> cache_sksl_;
101 
102  // Guard flag to make sure that cache_sksl_ is not modified after
103  // strategy_set_ becomes true.
104  static std::atomic<bool> strategy_set_;
105 
106  const bool is_read_only_;
107  const std::shared_ptr<fml::UniqueFD> cache_directory_;
108  const std::shared_ptr<fml::UniqueFD> sksl_cache_directory_;
109  mutable std::mutex worker_task_runners_mutex_;
110  std::multiset<fml::RefPtr<fml::TaskRunner>> worker_task_runners_;
111 
112  bool stored_new_shaders_ = false;
113  bool is_dumping_skp_ = false;
114 
115  static sk_sp<SkData> LoadFile(const fml::UniqueFD& dir,
116  const std::string& filen_ame);
117 
118  bool IsValid() const;
119 
120  PersistentCache(bool read_only = false);
121 
122  // |GrContextOptions::PersistentCache|
123  void store(const SkData& key, const SkData& data) override;
124 
125  fml::RefPtr<fml::TaskRunner> GetWorkerTaskRunner() const;
126 
127  friend class testing::ShellTest;
128 
130 };
131 
132 } // namespace flutter
133 
134 #endif // FLUTTER_SHELL_COMMON_PERSISTENT_CACHE_H_
DEF_SWITCHES_START snapshot asset path
Definition: switches.h:32
uint8_t value
std::pair< sk_sp< SkData >, sk_sp< SkData > > SkSLCache
void SetIsDumpingSkp(bool value)
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:27