paint_cache.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Copyright 2018 The Chromium 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. #include "cc/paint/paint_cache.h"
  5. #include "base/check_op.h"
  6. #include "base/containers/flat_set.h"
  7. #include "base/notreached.h"
  8. #include "base/synchronization/lock.h"
  9. namespace cc {
  10. namespace {
  11. template <typename T>
  12. void EraseFromMap(T* map, size_t n, const volatile PaintCacheId* ids) {
  13. for (size_t i = 0; i < n; ++i) {
  14. auto id = ids[i];
  15. map->erase(id);
  16. }
  17. }
  18. } // namespace
  19. constexpr size_t ClientPaintCache::kNoCachingBudget;
  20. ClientPaintCache::ClientPaintCache(size_t max_budget_bytes)
  21. : cache_map_(CacheMap::NO_AUTO_EVICT), max_budget_(max_budget_bytes) {}
  22. ClientPaintCache::~ClientPaintCache() = default;
  23. bool ClientPaintCache::Get(PaintCacheDataType type, PaintCacheId id) {
  24. return cache_map_.Get(std::make_pair(type, id)) != cache_map_.end();
  25. }
  26. void ClientPaintCache::Put(PaintCacheDataType type,
  27. PaintCacheId id,
  28. size_t size) {
  29. if (max_budget_ == kNoCachingBudget)
  30. return;
  31. auto key = std::make_pair(type, id);
  32. DCHECK(cache_map_.Peek(key) == cache_map_.end());
  33. pending_entries_->push_back(key);
  34. cache_map_.Put(key, size);
  35. bytes_used_ += size;
  36. }
  37. template <typename Iterator>
  38. void ClientPaintCache::EraseFromMap(Iterator it) {
  39. DCHECK_GE(bytes_used_, it->second);
  40. bytes_used_ -= it->second;
  41. cache_map_.Erase(it);
  42. }
  43. void ClientPaintCache::FinalizePendingEntries() {
  44. pending_entries_->clear();
  45. }
  46. void ClientPaintCache::AbortPendingEntries() {
  47. for (const auto& entry : pending_entries_) {
  48. auto it = cache_map_.Peek(entry);
  49. DCHECK(it != cache_map_.end());
  50. EraseFromMap(it);
  51. }
  52. pending_entries_->clear();
  53. }
  54. void ClientPaintCache::Purge(PurgedData* purged_data) {
  55. DCHECK(pending_entries_->empty());
  56. while (bytes_used_ > max_budget_) {
  57. auto it = cache_map_.rbegin();
  58. PaintCacheDataType type = it->first.first;
  59. PaintCacheId id = it->first.second;
  60. EraseFromMap(it);
  61. (*purged_data)[static_cast<uint32_t>(type)].push_back(id);
  62. }
  63. }
  64. bool ClientPaintCache::PurgeAll() {
  65. DCHECK(pending_entries_->empty());
  66. bool has_data = !cache_map_.empty();
  67. cache_map_.Clear();
  68. bytes_used_ = 0u;
  69. return has_data;
  70. }
  71. ServicePaintCache::ServicePaintCache() = default;
  72. ServicePaintCache::~ServicePaintCache() = default;
  73. void ServicePaintCache::PutPath(PaintCacheId id, SkPath path) {
  74. cached_paths_.emplace(id, std::move(path));
  75. }
  76. bool ServicePaintCache::GetPath(PaintCacheId id, SkPath* path) const {
  77. auto it = cached_paths_.find(id);
  78. if (it == cached_paths_.end())
  79. return false;
  80. *path = it->second;
  81. return true;
  82. }
  83. void ServicePaintCache::Purge(PaintCacheDataType type,
  84. size_t n,
  85. const volatile PaintCacheId* ids) {
  86. switch (type) {
  87. case PaintCacheDataType::kPath:
  88. EraseFromMap(&cached_paths_, n, ids);
  89. return;
  90. }
  91. NOTREACHED();
  92. }
  93. void ServicePaintCache::PurgeAll() {
  94. cached_paths_.clear();
  95. }
  96. } // namespace cc