// 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_ #if !SLIMPELLER #include #include #include #include #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 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& child_ids() const { return child_ids_; } static std::optional> 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 child_ids_; mutable std::optional 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 using Map = std::unordered_map; 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 // !SLIMPELLER #endif // FLUTTER_FLOW_RASTER_CACHE_KEY_H_