[M108 Migration][VD] Avoid pending frame counter becoming negative
[platform/framework/web/chromium-efl.git] / cc / tiles / software_image_decode_cache_utils.h
1 // Copyright 2018 The Chromium Authors
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 CC_TILES_SOFTWARE_IMAGE_DECODE_CACHE_UTILS_H_
6 #define CC_TILES_SOFTWARE_IMAGE_DECODE_CACHE_UTILS_H_
7
8 #include <limits>
9 #include <memory>
10 #include <string>
11
12 #include "base/callback.h"
13 #include "base/memory/discardable_memory.h"
14 #include "base/memory/scoped_refptr.h"
15 #include "cc/cc_export.h"
16 #include "cc/paint/decoded_draw_image.h"
17 #include "cc/paint/draw_image.h"
18 #include "cc/paint/paint_image.h"
19 #include "cc/paint/target_color_params.h"
20 #include "cc/raster/tile_task.h"
21 #include "cc/tiles/image_decode_cache_utils.h"
22 #include "third_party/skia/include/core/SkImage.h"
23 #include "third_party/skia/include/core/SkImageInfo.h"
24 #include "third_party/skia/include/core/SkSize.h"
25 #include "ui/gfx/color_space.h"
26 #include "ui/gfx/geometry/rect.h"
27 #include "ui/gfx/geometry/size.h"
28
29 namespace cc {
30
31 class SoftwareImageDecodeCacheUtils {
32  private:
33   // The following should only be accessed by the software image cache.
34   friend class SoftwareImageDecodeCache;
35
36   // CacheKey is a class that gets a cache key out of a given draw
37   // image. That is, this key uniquely identifies an image in the cache. Note
38   // that it's insufficient to use SkImage's unique id, since the same image can
39   // appear in the cache multiple times at different scales and filter
40   // qualities.
41   class CC_EXPORT CacheKey {
42    public:
43     // Enum indicating the type of processing to do for this key:
44     // kOriginal - use the original decode without any subrecting or scaling.
45     // kSubrectOriginal - extract a subrect from the original decode but do not
46     //                    scale it.
47     // kSubrectAndScale - extract a subrect (if needed) from the original decode
48     //                    and scale it.
49     enum ProcessingType { kOriginal, kSubrectOriginal, kSubrectAndScale };
50
51     static CacheKey FromDrawImage(const DrawImage& image,
52                                   SkColorType color_type);
53
54     CacheKey(const CacheKey& other);
55     CacheKey& operator=(const CacheKey& other);
56
57     bool operator==(const CacheKey& other) const {
58       // The frame_key always has to be the same. However, after that all
59       // original decodes are the same, so if we can use the original decode,
60       // return true. If not, then we have to compare every field.
61       // |nearest_neighbor_| is not compared below since it is not used for
62       // scaled decodes and does not affect the contents of the cache entry
63       // (just passed to skia for the filtering to be done at raster time).
64       DCHECK(!is_nearest_neighbor_ || type_ != kSubrectAndScale);
65       return frame_key_ == other.frame_key_ && type_ == other.type_ &&
66              target_color_params_ == other.target_color_params_ &&
67              (type_ == kOriginal || (src_rect_ == other.src_rect_ &&
68                                      target_size_ == other.target_size_));
69     }
70
71     bool operator!=(const CacheKey& other) const { return !(*this == other); }
72
73     const PaintImage::FrameKey& frame_key() const { return frame_key_; }
74     PaintImage::Id stable_id() const { return stable_id_; }
75     ProcessingType type() const { return type_; }
76     bool is_nearest_neighbor() const { return is_nearest_neighbor_; }
77     bool may_be_lcp_candidate() const { return may_be_lcp_candidate_; }
78     gfx::Rect src_rect() const { return src_rect_; }
79     gfx::Size target_size() const { return target_size_; }
80     const TargetColorParams& target_color_params() const {
81       return target_color_params_;
82     }
83
84     size_t get_hash() const { return hash_; }
85
86     // Helper to figure out how much memory the locked image represented by this
87     // key would take.
88     size_t locked_bytes() const {
89       // TODO(vmpstr): Handle formats other than RGBA.
90       base::CheckedNumeric<size_t> result = 4;
91       result *= target_size_.width();
92       result *= target_size_.height();
93       return result.ValueOrDefault(std::numeric_limits<size_t>::max());
94     }
95
96     std::string ToString() const;
97
98    private:
99     CacheKey(PaintImage::FrameKey frame_key,
100              PaintImage::Id stable_id,
101              ProcessingType type,
102              bool is_nearest_neighbor,
103              bool may_be_lcp_candidate,
104              const gfx::Rect& src_rect,
105              const gfx::Size& size,
106              const TargetColorParams& target_color_params);
107
108     PaintImage::FrameKey frame_key_;
109     // The stable id is does not factor into the cache key's value for hashing
110     // and comparison (as it is redundant). It is only used to look up other
111     // cache entries of the same stable id.
112     PaintImage::Id stable_id_;
113     ProcessingType type_;
114     bool is_nearest_neighbor_;
115     bool may_be_lcp_candidate_;
116     gfx::Rect src_rect_;
117     gfx::Size target_size_;
118     TargetColorParams target_color_params_;
119     size_t hash_;
120   };
121
122   struct CacheKeyHash {
123     size_t operator()(const CacheKey& key) const { return key.get_hash(); }
124   };
125
126   // CacheEntry is a convenience storage for discardable memory. It can also
127   // construct an image out of SkImageInfo and stored discardable memory.
128   class CC_EXPORT CacheEntry {
129    public:
130     CacheEntry();
131     CacheEntry(const SkImageInfo& info,
132                std::unique_ptr<base::DiscardableMemory> memory,
133                const SkSize& src_rect_offset);
134     ~CacheEntry();
135
136     void MoveImageMemoryTo(CacheEntry* entry);
137
138     sk_sp<SkImage> image() const {
139       if (!memory)
140         return nullptr;
141       DCHECK(is_locked);
142       return image_;
143     }
144     const SkSize& src_rect_offset() const { return src_rect_offset_; }
145
146     bool Lock();
147     void Unlock();
148
149     // An ID which uniquely identifies this CacheEntry within the image decode
150     // cache. Used in memory tracing.
151     uint64_t tracing_id() const { return tracing_id_; }
152     // Mark this image as being used in either a draw or as a source for a
153     // scaled image. Either case represents this decode as being valuable and
154     // not wasted.
155     void mark_used() { usage_stats_.used = true; }
156     void mark_cached() { cached_ = true; }
157     void mark_out_of_raster() { usage_stats_.first_lock_out_of_raster = true; }
158
159     // Since this is an inner class, we expose these variables publicly for
160     // simplicity.
161     // TODO(vmpstr): A good simple clean-up would be to rethink this class
162     // and its interactions to instead expose a few functions which would also
163     // facilitate easier DCHECKs.
164     int ref_count = 0;
165     bool decode_failed = false;
166     bool is_locked = false;
167     bool is_budgeted = false;
168
169     scoped_refptr<TileTask> in_raster_task;
170     scoped_refptr<TileTask> out_of_raster_task;
171
172     std::unique_ptr<base::DiscardableMemory> memory;
173
174    private:
175     struct UsageStats {
176       // We can only create a decoded image in a locked state, so the initial
177       // lock count is 1.
178       int lock_count = 1;
179       bool used = false;
180       bool last_lock_failed = false;
181       bool first_lock_wasted = false;
182       bool first_lock_out_of_raster = false;
183     };
184
185     SkImageInfo image_info_;
186     sk_sp<SkImage> image_;
187     SkSize src_rect_offset_;
188     uint64_t tracing_id_;
189     UsageStats usage_stats_;
190     // Indicates whether this entry was ever in the cache.
191     bool cached_ = false;
192   };
193
194   // |on_no_memory| is called when memory allocation fails in this function,
195   // before retrying it once. As a consequence, this should free memory, and
196   // importantly, address space as well.
197   static std::unique_ptr<CacheEntry> DoDecodeImage(
198       const CacheKey& key,
199       const PaintImage& image,
200       SkColorType color_type,
201       PaintImage::GeneratorClientId client_id,
202       base::OnceClosure on_no_memory);
203   static std::unique_ptr<CacheEntry> GenerateCacheEntryFromCandidate(
204       const CacheKey& key,
205       const DecodedDrawImage& candidate,
206       bool needs_extract_subset,
207       SkColorType color_type);
208 };
209
210 }  // namespace cc
211
212 #endif  // CC_TILES_SOFTWARE_IMAGE_DECODE_CACHE_UTILS_H_