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
17namespace flutter {
18
19class Layer;
20
21enum class RasterCacheKeyType { kLayer, kDisplayList, kLayerChildren };
22
23class 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
75enum class RasterCacheKeyKind { kLayerMetrics, kDisplayListMetrics };
76
77class 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

source code of flutter_engine/flutter/flow/raster_cache_key.h