forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpersistent_cache.h
182 lines (137 loc) · 6.35 KB
/
persistent_cache.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_COMMON_GRAPHICS_PERSISTENT_CACHE_H_
#define FLUTTER_COMMON_GRAPHICS_PERSISTENT_CACHE_H_
#include <memory>
#include <mutex>
#include <set>
#include "flutter/assets/asset_manager.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/task_runner.h"
#include "flutter/fml/unique_fd.h"
#include "third_party/skia/include/gpu/GrContextOptions.h"
class GrDirectContext;
namespace flutter {
namespace testing {
class ShellTest;
}
/// 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.
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 ResetCacheForProcess();
// This must be called before |GetCacheForProcess|. Otherwise, it won't
// affect the cache directory returned by |GetCacheForProcess|.
static void SetCacheDirectoryPath(std::string path);
// Convert a binary SkData key into a Base32 encoded string.
//
// This is used to specify persistent cache filenames and service protocol
// json keys.
static std::string SkKeyToFilePath(const SkData& key);
// Allocate a MallocMapping containing the given key and value in the file
// format used by the cache.
static std::unique_ptr<fml::MallocMapping> BuildCacheObject(
const SkData& key,
const SkData& data);
// Header written into the files used to store cached Skia objects.
struct CacheObjectHeader {
// A prefix used to identify the cache object file format.
static const uint32_t kSignature = 0xA869593F;
static const uint32_t kVersion1 = 1;
explicit CacheObjectHeader(uint32_t p_key_size) : key_size(p_key_size) {}
uint32_t signature = kSignature;
uint32_t version = kVersion1;
uint32_t key_size;
};
~PersistentCache() override;
void AddWorkerTaskRunner(const fml::RefPtr<fml::TaskRunner>& task_runner);
void RemoveWorkerTaskRunner(const fml::RefPtr<fml::TaskRunner>& task_runner);
// Whether Skia tries to store any shader into this persistent cache after
// |ResetStoredNewShaders| is called. This flag is usually reset before each
// frame so we can know if Skia tries to compile new shaders in that frame.
bool StoredNewShaders() const { return stored_new_shaders_; }
void ResetStoredNewShaders() { stored_new_shaders_ = false; }
void DumpSkp(const SkData& data);
bool IsDumpingSkp() const { return is_dumping_skp_; }
void SetIsDumpingSkp(bool value) { is_dumping_skp_ = value; }
// Remove all files inside the persistent cache directory.
// Return whether the purge is successful.
bool Purge();
// |GrContextOptions::PersistentCache|
sk_sp<SkData> load(const SkData& key) override;
struct SkSLCache {
sk_sp<SkData> key;
sk_sp<SkData> value;
};
/// Load all the SkSL shader caches in the right directory.
std::vector<SkSLCache> LoadSkSLs() const;
//----------------------------------------------------------------------------
/// @brief Precompile SkSLs packaged with the application and gathered
/// during previous runs in the given context.
///
/// @warning The context must be the rendering context. This context may be
/// destroyed during application suspension and subsequently
/// recreated. The SkSLs must be precompiled again in the new
/// context.
///
/// @param context The rendering context to precompile shaders in.
///
/// @return The number of SkSLs precompiled.
///
size_t PrecompileKnownSkSLs(GrDirectContext* context) const;
// Return mappings for all skp's accessible through the AssetManager
std::vector<std::unique_ptr<fml::Mapping>> GetSkpsFromAssetManager() const;
/// Set the asset manager from which PersistentCache can load SkLSs. A nullptr
/// can be provided to clear the asset manager.
static void SetAssetManager(std::shared_ptr<AssetManager> value);
static std::shared_ptr<AssetManager> asset_manager() {
return asset_manager_;
}
static bool cache_sksl() { return cache_sksl_; }
static void SetCacheSkSL(bool value);
static void MarkStrategySet() { strategy_set_ = true; }
static constexpr char kSkSLSubdirName[] = "sksl";
static constexpr char kAssetFileName[] = "io.flutter.shaders.json";
private:
static std::string cache_base_path_;
static std::shared_ptr<AssetManager> asset_manager_;
static std::mutex instance_mutex_;
static std::unique_ptr<PersistentCache> gPersistentCache;
// Mutable static switch that can be set before GetCacheForProcess is called
// and GrContextOptions.fShaderCacheStrategy is set. If true, it means that
// we'll set `GrContextOptions::fShaderCacheStrategy` to `kSkSL`, and all the
// persistent cache should be stored and loaded from the "sksl" directory.
static std::atomic<bool> cache_sksl_;
// Guard flag to make sure that cache_sksl_ is not modified after
// strategy_set_ becomes true.
static std::atomic<bool> strategy_set_;
const bool is_read_only_;
const std::shared_ptr<fml::UniqueFD> cache_directory_;
const std::shared_ptr<fml::UniqueFD> sksl_cache_directory_;
mutable std::mutex worker_task_runners_mutex_;
std::multiset<fml::RefPtr<fml::TaskRunner>> worker_task_runners_;
bool stored_new_shaders_ = false;
bool is_dumping_skp_ = false;
static SkSLCache LoadFile(const fml::UniqueFD& dir,
const std::string& file_name,
bool need_key);
bool IsValid() const;
explicit PersistentCache(bool read_only = false);
// |GrContextOptions::PersistentCache|
void store(const SkData& key, const SkData& data) override;
fml::RefPtr<fml::TaskRunner> GetWorkerTaskRunner() const;
friend class testing::ShellTest;
FML_DISALLOW_COPY_AND_ASSIGN(PersistentCache);
};
} // namespace flutter
#endif // FLUTTER_COMMON_GRAPHICS_PERSISTENT_CACHE_H_