1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_TILES_SOFTWARE_IMAGE_DECODE_CACHE_H_
#define CC_TILES_SOFTWARE_IMAGE_DECODE_CACHE_H_
#include <stdint.h>
#include <memory>
#include <unordered_map>
#include <vector>
#include "base/containers/lru_cache.h"
#include "base/numerics/safe_math.h"
#include "base/thread_annotations.h"
#include "base/trace_event/memory_dump_provider.h"
#include "cc/cc_export.h"
#include "cc/paint/draw_image.h"
#include "cc/tiles/image_decode_cache.h"
#include "cc/tiles/software_image_decode_cache_utils.h"
namespace cc {
class CC_EXPORT SoftwareImageDecodeCache
: public ImageDecodeCache,
public base::trace_event::MemoryDumpProvider {
public:
using Utils = SoftwareImageDecodeCacheUtils;
using CacheKey = Utils::CacheKey;
using CacheKeyHash = Utils::CacheKeyHash;
// Identifies whether a decode task performed decode work, or was fulfilled /
// failed trivially.
enum class TaskProcessingResult { kFullDecode, kLockOnly, kCancelled };
SoftwareImageDecodeCache(SkColorType color_type,
size_t locked_memory_limit_bytes);
~SoftwareImageDecodeCache() override;
// ImageDecodeCache overrides.
// |client_id| is not used by the SoftwareImageDecodeCache for both of these
// tasks.
TaskResult GetTaskForImageAndRef(ClientId client_id,
const DrawImage& image,
const TracingInfo& tracing_info) override;
TaskResult GetOutOfRasterDecodeTaskForImageAndRef(
ClientId client_id,
const DrawImage& image,
bool speculative = false) override;
void UnrefImage(const DrawImage& image) override;
DecodedDrawImage GetDecodedImageForDraw(const DrawImage& image) override;
void DrawWithImageFinished(const DrawImage& image,
const DecodedDrawImage& decoded_image) override;
void ReduceCacheUsage() override;
// Software doesn't keep outstanding images pinned, so this is a no-op.
void SetShouldAggressivelyFreeResources(
bool aggressively_free_resources) override {}
void ClearCache() override;
size_t GetMaximumMemoryLimitBytes() const override;
bool UseCacheForDrawImage(const DrawImage& image) const override;
void RecordStats() override {}
ClientId GenerateClientId() override;
// Decode the given image and store it in the cache. This is only called by an
// image decode task from a worker thread.
TaskProcessingResult DecodeImageInTask(const CacheKey& key,
const PaintImage& paint_image,
TaskType task_type);
void OnImageDecodeTaskCompleted(const CacheKey& key, TaskType task_type);
// MemoryDumpProvider overrides.
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
size_t GetNumCacheEntriesForTesting();
size_t GetMaxNumCacheEntriesForTesting();
private:
using CacheEntry = Utils::CacheEntry;
// MemoryBudget is a convenience class for memory bookkeeping and ensuring
// that we don't go over the limit when pre-decoding.
class MemoryBudget {
public:
explicit MemoryBudget(size_t limit_bytes);
size_t AvailableMemoryBytes() const;
void AddUsage(size_t usage);
void SubtractUsage(size_t usage);
void ResetUsage();
size_t total_limit_bytes() const { return limit_bytes_; }
size_t GetCurrentUsageSafe() const;
private:
const size_t limit_bytes_;
base::CheckedNumeric<size_t> current_usage_bytes_;
};
using ImageLRUCache = base::
HashingLRUCache<CacheKey, std::unique_ptr<CacheEntry>, CacheKeyHash>;
// Get the decoded draw image for the given key and paint_image. Note that
// when used internally, we still require that DrawWithImageFinished() is
// called afterwards.
DecodedDrawImage GetDecodedImageForDrawInternal(const CacheKey& key,
const PaintImage& paint_image)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Removes unlocked decoded images until the number of decoded images is
// reduced within the given limit.
void ReduceCacheUsageUntilWithinLimit(size_t limit)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Helper method to get the different tasks. Note that this should be used as
// if it was public (ie, all of the locks need to be properly acquired).
TaskResult GetTaskForImageAndRefInternal(const DrawImage& image,
const TracingInfo& tracing_info,
TaskType type,
bool speculative)
LOCKS_EXCLUDED(lock_);
CacheEntry* AddCacheEntry(const CacheKey& key)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
TaskProcessingResult DecodeImageIfNecessary(const CacheKey& key,
const PaintImage& paint_image,
CacheEntry* cache_entry)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
void AddBudgetForImage(const CacheKey& key, CacheEntry* entry)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
void RemoveBudgetForImage(const CacheKey& key, CacheEntry* entry)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
std::optional<CacheKey> FindCachedCandidate(const CacheKey& key)
EXCLUSIVE_LOCKS_REQUIRED(lock_);
void UnrefImage(const CacheKey& key) EXCLUSIVE_LOCKS_REQUIRED(lock_);
SkColorType GetColorTypeForPaintImage(
const TargetColorParams& target_color_params,
const PaintImage& paint_image);
base::Lock lock_;
// Decoded images and ref counts (predecode path).
ImageLRUCache decoded_images_ GUARDED_BY(lock_);
// A map of PaintImage::FrameKey to the ImageKeys for cached decodes of this
// PaintImage.
std::unordered_map<PaintImage::FrameKey,
std::vector<CacheKey>,
PaintImage::FrameKeyHash>
frame_key_to_image_keys_ GUARDED_BY(lock_);
// Should be GUARDED_BY(lock_), except that accessing
// |locked_images_budget_.total_limit_bytes()| is fine without the lock, as
// it is const and thread safe.
MemoryBudget locked_images_budget_;
const SkColorType color_type_;
const PaintImage::GeneratorClientId generator_client_id_;
const size_t max_items_in_cache_;
};
} // namespace cc
#endif // CC_TILES_SOFTWARE_IMAGE_DECODE_CACHE_H_
|