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/fml/macros.h" 13 #include "flutter/fml/synchronization/thread_annotations.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 flutter { 19 20 /// A cache of SkData that gets stored to disk. 21 /// 22 /// This is mainly used for Shaders but is also written to by Dart. It is 23 /// thread-safe for reading and writing from multiple threads. 24 class PersistentCache : public GrContextOptions::PersistentCache { 25 public: 26 // Mutable static switch that can be set before GetCacheForProcess. If true, 27 // we'll only read existing caches but not generate new ones. Some clients 28 // (e.g., embedded devices) prefer generating persistent cache files for the 29 // specific device beforehand, and ship them as readonly files in OTA 30 // packages. 31 static bool gIsReadOnly; 32 33 static PersistentCache* GetCacheForProcess(); 34 35 static void SetCacheDirectoryPath(std::string path); 36 37 ~PersistentCache() override; 38 39 void AddWorkerTaskRunner(fml::RefPtr<fml::TaskRunner> task_runner); 40 41 void RemoveWorkerTaskRunner(fml::RefPtr<fml::TaskRunner> task_runner); 42 43 // Whether Skia tries to store any shader into this persistent cache after 44 // |ResetStoredNewShaders| is called. This flag is usually reset before each 45 // frame so we can know if Skia tries to compile new shaders in that frame. StoredNewShaders()46 bool StoredNewShaders() const { return stored_new_shaders_; } ResetStoredNewShaders()47 void ResetStoredNewShaders() { stored_new_shaders_ = false; } 48 void DumpSkp(const SkData& data); IsDumpingSkp()49 bool IsDumpingSkp() const { return is_dumping_skp_; } SetIsDumpingSkp(bool value)50 void SetIsDumpingSkp(bool value) { is_dumping_skp_ = value; } 51 52 private: 53 static std::string cache_base_path_; 54 55 const bool is_read_only_; 56 const std::shared_ptr<fml::UniqueFD> cache_directory_; 57 mutable std::mutex worker_task_runners_mutex_; 58 std::multiset<fml::RefPtr<fml::TaskRunner>> worker_task_runners_ 59 FML_GUARDED_BY(worker_task_runners_mutex_); 60 61 bool stored_new_shaders_ = false; 62 bool is_dumping_skp_ = false; 63 64 bool IsValid() const; 65 66 PersistentCache(bool read_only = false); 67 68 // |GrContextOptions::PersistentCache| 69 sk_sp<SkData> load(const SkData& key) override; 70 71 // |GrContextOptions::PersistentCache| 72 void store(const SkData& key, const SkData& data) override; 73 74 fml::RefPtr<fml::TaskRunner> GetWorkerTaskRunner() const; 75 76 FML_DISALLOW_COPY_AND_ASSIGN(PersistentCache); 77 }; 78 79 } // namespace flutter 80 81 #endif // FLUTTER_SHELL_COMMON_PERSISTENT_CACHE_H_ 82