| // 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_FLOW_RASTER_CACHE_KEY_H_ | 
 | #define FLUTTER_FLOW_RASTER_CACHE_KEY_H_ | 
 |  | 
 | #include <optional> | 
 | #include <unordered_map> | 
 | #include <utility> | 
 | #include <vector> | 
 |  | 
 | #include "flutter/fml/hash_combine.h" | 
 | #include "flutter/fml/logging.h" | 
 | #include "third_party/skia/include/core/SkMatrix.h" | 
 |  | 
 | namespace flutter { | 
 |  | 
 | class Layer; | 
 |  | 
 | enum class RasterCacheKeyType { kLayer, kDisplayList, kLayerChildren }; | 
 |  | 
 | class RasterCacheKeyID { | 
 |  public: | 
 |   static constexpr uint64_t kDefaultUniqueID = 0; | 
 |  | 
 |   RasterCacheKeyID(uint64_t unique_id, RasterCacheKeyType type) | 
 |       : unique_id_(unique_id), type_(type) {} | 
 |  | 
 |   RasterCacheKeyID(std::vector<RasterCacheKeyID> child_ids, | 
 |                    RasterCacheKeyType type) | 
 |       : unique_id_(kDefaultUniqueID), | 
 |         type_(type), | 
 |         child_ids_(std::move(child_ids)) {} | 
 |  | 
 |   uint64_t unique_id() const { return unique_id_; } | 
 |  | 
 |   RasterCacheKeyType type() const { return type_; } | 
 |  | 
 |   const std::vector<RasterCacheKeyID>& child_ids() const { return child_ids_; } | 
 |  | 
 |   static std::optional<std::vector<RasterCacheKeyID>> LayerChildrenIds( | 
 |       const Layer* layer); | 
 |  | 
 |   std::size_t GetHash() const { | 
 |     if (cached_hash_) { | 
 |       return cached_hash_.value(); | 
 |     } | 
 |     std::size_t seed = fml::HashCombine(); | 
 |     fml::HashCombineSeed(seed, unique_id_); | 
 |     fml::HashCombineSeed(seed, type_); | 
 |     for (auto& child_id : child_ids_) { | 
 |       fml::HashCombineSeed(seed, child_id.GetHash()); | 
 |     } | 
 |     cached_hash_ = seed; | 
 |     return seed; | 
 |   } | 
 |  | 
 |   bool operator==(const RasterCacheKeyID& other) const { | 
 |     return unique_id_ == other.unique_id_ && type_ == other.type_ && | 
 |            GetHash() == other.GetHash() && child_ids_ == other.child_ids_; | 
 |   } | 
 |  | 
 |   bool operator!=(const RasterCacheKeyID& other) const { | 
 |     return !operator==(other); | 
 |   } | 
 |  | 
 |  private: | 
 |   const uint64_t unique_id_; | 
 |   const RasterCacheKeyType type_; | 
 |   const std::vector<RasterCacheKeyID> child_ids_; | 
 |   mutable std::optional<std::size_t> cached_hash_; | 
 | }; | 
 |  | 
 | enum class RasterCacheKeyKind { kLayerMetrics, kDisplayListMetrics }; | 
 |  | 
 | class RasterCacheKey { | 
 |  public: | 
 |   RasterCacheKey(uint64_t unique_id, | 
 |                  RasterCacheKeyType type, | 
 |                  const SkMatrix& ctm) | 
 |       : RasterCacheKey(RasterCacheKeyID(unique_id, type), ctm) {} | 
 |  | 
 |   RasterCacheKey(RasterCacheKeyID id, const SkMatrix& ctm) | 
 |       : id_(std::move(id)), matrix_(ctm) { | 
 |     matrix_[SkMatrix::kMTransX] = 0; | 
 |     matrix_[SkMatrix::kMTransY] = 0; | 
 |   } | 
 |  | 
 |   const RasterCacheKeyID& id() const { return id_; } | 
 |   const SkMatrix& matrix() const { return matrix_; } | 
 |  | 
 |   RasterCacheKeyKind kind() const { | 
 |     switch (id_.type()) { | 
 |       case RasterCacheKeyType::kDisplayList: | 
 |         return RasterCacheKeyKind::kDisplayListMetrics; | 
 |       case RasterCacheKeyType::kLayer: | 
 |       case RasterCacheKeyType::kLayerChildren: | 
 |         return RasterCacheKeyKind::kLayerMetrics; | 
 |     } | 
 |   } | 
 |  | 
 |   struct Hash { | 
 |     std::size_t operator()(RasterCacheKey const& key) const { | 
 |       return key.id_.GetHash(); | 
 |     } | 
 |   }; | 
 |  | 
 |   struct Equal { | 
 |     constexpr bool operator()(const RasterCacheKey& lhs, | 
 |                               const RasterCacheKey& rhs) const { | 
 |       return lhs.id_ == rhs.id_ && lhs.matrix_ == rhs.matrix_; | 
 |     } | 
 |   }; | 
 |  | 
 |   template <class Value> | 
 |   using Map = std::unordered_map<RasterCacheKey, Value, Hash, Equal>; | 
 |  | 
 |  private: | 
 |   RasterCacheKeyID id_; | 
 |  | 
 |   // ctm where only fractional (0-1) translations are preserved: | 
 |   //   matrix_ = ctm; | 
 |   //   matrix_[SkMatrix::kMTransX] = SkScalarFraction(ctm.getTranslateX()); | 
 |   //   matrix_[SkMatrix::kMTransY] = SkScalarFraction(ctm.getTranslateY()); | 
 |   SkMatrix matrix_; | 
 | }; | 
 |  | 
 | }  // namespace flutter | 
 |  | 
 | #endif  // FLUTTER_FLOW_RASTER_CACHE_KEY_H_ |