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_FLOW_RASTER_CACHE_KEY_H_ |
6 | #define FLUTTER_FLOW_RASTER_CACHE_KEY_H_ |
7 | |
8 | #include <optional> |
9 | #include <unordered_map> |
10 | #include <utility> |
11 | #include <vector> |
12 | |
13 | #include "flutter/fml/hash_combine.h" |
14 | #include "flutter/fml/logging.h" |
15 | #include "third_party/skia/include/core/SkMatrix.h" |
16 | |
17 | namespace flutter { |
18 | |
19 | class Layer; |
20 | |
21 | enum class RasterCacheKeyType { kLayer, kDisplayList, kLayerChildren }; |
22 | |
23 | class RasterCacheKeyID { |
24 | public: |
25 | static constexpr uint64_t kDefaultUniqueID = 0; |
26 | |
27 | RasterCacheKeyID(uint64_t unique_id, RasterCacheKeyType type) |
28 | : unique_id_(unique_id), type_(type) {} |
29 | |
30 | RasterCacheKeyID(std::vector<RasterCacheKeyID> child_ids, |
31 | RasterCacheKeyType type) |
32 | : unique_id_(kDefaultUniqueID), |
33 | type_(type), |
34 | child_ids_(std::move(child_ids)) {} |
35 | |
36 | uint64_t unique_id() const { return unique_id_; } |
37 | |
38 | RasterCacheKeyType type() const { return type_; } |
39 | |
40 | const std::vector<RasterCacheKeyID>& child_ids() const { return child_ids_; } |
41 | |
42 | static std::optional<std::vector<RasterCacheKeyID>> LayerChildrenIds( |
43 | const Layer* layer); |
44 | |
45 | std::size_t GetHash() const { |
46 | if (cached_hash_) { |
47 | return cached_hash_.value(); |
48 | } |
49 | std::size_t seed = fml::HashCombine(); |
50 | fml::HashCombineSeed(seed, arg: unique_id_); |
51 | fml::HashCombineSeed(seed, arg: type_); |
52 | for (auto& child_id : child_ids_) { |
53 | fml::HashCombineSeed(seed, arg: child_id.GetHash()); |
54 | } |
55 | cached_hash_ = seed; |
56 | return seed; |
57 | } |
58 | |
59 | bool operator==(const RasterCacheKeyID& other) const { |
60 | return unique_id_ == other.unique_id_ && type_ == other.type_ && |
61 | GetHash() == other.GetHash() && child_ids_ == other.child_ids_; |
62 | } |
63 | |
64 | bool operator!=(const RasterCacheKeyID& other) const { |
65 | return !operator==(other); |
66 | } |
67 | |
68 | private: |
69 | const uint64_t unique_id_; |
70 | const RasterCacheKeyType type_; |
71 | const std::vector<RasterCacheKeyID> child_ids_; |
72 | mutable std::optional<std::size_t> cached_hash_; |
73 | }; |
74 | |
75 | enum class RasterCacheKeyKind { kLayerMetrics, kDisplayListMetrics }; |
76 | |
77 | class RasterCacheKey { |
78 | public: |
79 | RasterCacheKey(uint64_t unique_id, |
80 | RasterCacheKeyType type, |
81 | const SkMatrix& ctm) |
82 | : RasterCacheKey(RasterCacheKeyID(unique_id, type), ctm) {} |
83 | |
84 | RasterCacheKey(RasterCacheKeyID id, const SkMatrix& ctm) |
85 | : id_(std::move(id)), matrix_(ctm) { |
86 | matrix_[SkMatrix::kMTransX] = 0; |
87 | matrix_[SkMatrix::kMTransY] = 0; |
88 | } |
89 | |
90 | const RasterCacheKeyID& id() const { return id_; } |
91 | const SkMatrix& matrix() const { return matrix_; } |
92 | |
93 | RasterCacheKeyKind kind() const { |
94 | switch (id_.type()) { |
95 | case RasterCacheKeyType::kDisplayList: |
96 | return RasterCacheKeyKind::kDisplayListMetrics; |
97 | case RasterCacheKeyType::kLayer: |
98 | case RasterCacheKeyType::kLayerChildren: |
99 | return RasterCacheKeyKind::kLayerMetrics; |
100 | } |
101 | } |
102 | |
103 | struct Hash { |
104 | std::size_t operator()(RasterCacheKey const& key) const { |
105 | return key.id_.GetHash(); |
106 | } |
107 | }; |
108 | |
109 | struct Equal { |
110 | constexpr bool operator()(const RasterCacheKey& lhs, |
111 | const RasterCacheKey& rhs) const { |
112 | return lhs.id_ == rhs.id_ && lhs.matrix_ == rhs.matrix_; |
113 | } |
114 | }; |
115 | |
116 | template <class Value> |
117 | using Map = std::unordered_map<RasterCacheKey, Value, Hash, Equal>; |
118 | |
119 | private: |
120 | RasterCacheKeyID id_; |
121 | |
122 | // ctm where only fractional (0-1) translations are preserved: |
123 | // matrix_ = ctm; |
124 | // matrix_[SkMatrix::kMTransX] = SkScalarFraction(ctm.getTranslateX()); |
125 | // matrix_[SkMatrix::kMTransY] = SkScalarFraction(ctm.getTranslateY()); |
126 | SkMatrix matrix_; |
127 | }; |
128 | |
129 | } // namespace flutter |
130 | |
131 | #endif // FLUTTER_FLOW_RASTER_CACHE_KEY_H_ |
132 | |