Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: cc/tiles/software_image_decode_cache.cc

Issue 2541183002: cc: Rename ImageDecodeController to ImageDecodeCache. (Closed)
Patch Set: rename: update Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/tiles/software_image_decode_controller.h" 5 #include "cc/tiles/software_image_decode_cache.h"
6 6
7 #include <inttypes.h> 7 #include <inttypes.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <functional> 11 #include <functional>
12 12
13 #include "base/format_macros.h" 13 #include "base/format_macros.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/discardable_memory.h" 15 #include "base/memory/discardable_memory.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 // don't need to scale the image, consider caching only the needed subrect. 50 // don't need to scale the image, consider caching only the needed subrect.
51 // The second part that much be true is that we cache only the needed subrect if 51 // The second part that much be true is that we cache only the needed subrect if
52 // the total size needed for the subrect is at most kMemoryRatioToSubrect * 52 // the total size needed for the subrect is at most kMemoryRatioToSubrect *
53 // (size needed for the full original image). 53 // (size needed for the full original image).
54 const size_t kMemoryThresholdToSubrect = 64 * 1024 * 1024; 54 const size_t kMemoryThresholdToSubrect = 64 * 1024 * 1024;
55 const float kMemoryRatioToSubrect = 0.5f; 55 const float kMemoryRatioToSubrect = 0.5f;
56 56
57 class AutoRemoveKeyFromTaskMap { 57 class AutoRemoveKeyFromTaskMap {
58 public: 58 public:
59 AutoRemoveKeyFromTaskMap( 59 AutoRemoveKeyFromTaskMap(
60 std::unordered_map<SoftwareImageDecodeController::ImageKey, 60 std::unordered_map<SoftwareImageDecodeCache::ImageKey,
61 scoped_refptr<TileTask>, 61 scoped_refptr<TileTask>,
62 SoftwareImageDecodeController::ImageKeyHash>* task_map, 62 SoftwareImageDecodeCache::ImageKeyHash>* task_map,
63 const SoftwareImageDecodeController::ImageKey& key) 63 const SoftwareImageDecodeCache::ImageKey& key)
64 : task_map_(task_map), key_(key) {} 64 : task_map_(task_map), key_(key) {}
65 ~AutoRemoveKeyFromTaskMap() { task_map_->erase(key_); } 65 ~AutoRemoveKeyFromTaskMap() { task_map_->erase(key_); }
66 66
67 private: 67 private:
68 std::unordered_map<SoftwareImageDecodeController::ImageKey, 68 std::unordered_map<SoftwareImageDecodeCache::ImageKey,
69 scoped_refptr<TileTask>, 69 scoped_refptr<TileTask>,
70 SoftwareImageDecodeController::ImageKeyHash>* task_map_; 70 SoftwareImageDecodeCache::ImageKeyHash>* task_map_;
71 const SoftwareImageDecodeController::ImageKey& key_; 71 const SoftwareImageDecodeCache::ImageKey& key_;
72 }; 72 };
73 73
74 class AutoDrawWithImageFinished { 74 class AutoDrawWithImageFinished {
75 public: 75 public:
76 AutoDrawWithImageFinished(SoftwareImageDecodeController* controller, 76 AutoDrawWithImageFinished(SoftwareImageDecodeCache* cache,
77 const DrawImage& draw_image, 77 const DrawImage& draw_image,
78 const DecodedDrawImage& decoded_draw_image) 78 const DecodedDrawImage& decoded_draw_image)
79 : controller_(controller), 79 : cache_(cache),
80 draw_image_(draw_image), 80 draw_image_(draw_image),
81 decoded_draw_image_(decoded_draw_image) {} 81 decoded_draw_image_(decoded_draw_image) {}
82 ~AutoDrawWithImageFinished() { 82 ~AutoDrawWithImageFinished() {
83 controller_->DrawWithImageFinished(draw_image_, decoded_draw_image_); 83 cache_->DrawWithImageFinished(draw_image_, decoded_draw_image_);
84 } 84 }
85 85
86 private: 86 private:
87 SoftwareImageDecodeController* controller_; 87 SoftwareImageDecodeCache* cache_;
88 const DrawImage& draw_image_; 88 const DrawImage& draw_image_;
89 const DecodedDrawImage& decoded_draw_image_; 89 const DecodedDrawImage& decoded_draw_image_;
90 }; 90 };
91 91
92 class ImageDecodeTaskImpl : public TileTask { 92 class ImageDecodeTaskImpl : public TileTask {
93 public: 93 public:
94 ImageDecodeTaskImpl(SoftwareImageDecodeController* controller, 94 ImageDecodeTaskImpl(SoftwareImageDecodeCache* cache,
95 const SoftwareImageDecodeController::ImageKey& image_key, 95 const SoftwareImageDecodeCache::ImageKey& image_key,
96 const DrawImage& image, 96 const DrawImage& image,
97 const ImageDecodeController::TracingInfo& tracing_info) 97 const ImageDecodeCache::TracingInfo& tracing_info)
98 : TileTask(true), 98 : TileTask(true),
99 controller_(controller), 99 cache_(cache),
100 image_key_(image_key), 100 image_key_(image_key),
101 image_(image), 101 image_(image),
102 tracing_info_(tracing_info) {} 102 tracing_info_(tracing_info) {}
103 103
104 // Overridden from Task: 104 // Overridden from Task:
105 void RunOnWorkerThread() override { 105 void RunOnWorkerThread() override {
106 TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", 106 TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode",
107 "software", "source_prepare_tiles_id", 107 "software", "source_prepare_tiles_id",
108 tracing_info_.prepare_tiles_id); 108 tracing_info_.prepare_tiles_id);
109 devtools_instrumentation::ScopedImageDecodeTask image_decode_task( 109 devtools_instrumentation::ScopedImageDecodeTask image_decode_task(
110 image_.image().get(), 110 image_.image().get(),
111 devtools_instrumentation::ScopedImageDecodeTask::SOFTWARE); 111 devtools_instrumentation::ScopedImageDecodeTask::SOFTWARE);
112 controller_->DecodeImage(image_key_, image_); 112 cache_->DecodeImage(image_key_, image_);
113 } 113 }
114 114
115 // Overridden from TileTask: 115 // Overridden from TileTask:
116 void OnTaskCompleted() override { 116 void OnTaskCompleted() override { cache_->RemovePendingTask(image_key_); }
117 controller_->RemovePendingTask(image_key_);
118 }
119 117
120 protected: 118 protected:
121 ~ImageDecodeTaskImpl() override {} 119 ~ImageDecodeTaskImpl() override {}
122 120
123 private: 121 private:
124 SoftwareImageDecodeController* controller_; 122 SoftwareImageDecodeCache* cache_;
125 SoftwareImageDecodeController::ImageKey image_key_; 123 SoftwareImageDecodeCache::ImageKey image_key_;
126 DrawImage image_; 124 DrawImage image_;
127 const ImageDecodeController::TracingInfo tracing_info_; 125 const ImageDecodeCache::TracingInfo tracing_info_;
128 126
129 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); 127 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
130 }; 128 };
131 129
132 SkSize GetScaleAdjustment(const ImageDecodeControllerKey& key) { 130 SkSize GetScaleAdjustment(const ImageDecodeCacheKey& key) {
133 // If the requested filter quality did not require scale, then the adjustment 131 // If the requested filter quality did not require scale, then the adjustment
134 // is identity. 132 // is identity.
135 if (key.can_use_original_decode() || key.should_use_subrect()) { 133 if (key.can_use_original_decode() || key.should_use_subrect()) {
136 return SkSize::Make(1.f, 1.f); 134 return SkSize::Make(1.f, 1.f);
137 } else if (key.filter_quality() == kMedium_SkFilterQuality) { 135 } else if (key.filter_quality() == kMedium_SkFilterQuality) {
138 return MipMapUtil::GetScaleAdjustmentForSize(key.src_rect().size(), 136 return MipMapUtil::GetScaleAdjustmentForSize(key.src_rect().size(),
139 key.target_size()); 137 key.target_size());
140 } else { 138 } else {
141 float x_scale = 139 float x_scale =
142 key.target_size().width() / static_cast<float>(key.src_rect().width()); 140 key.target_size().width() / static_cast<float>(key.src_rect().width());
143 float y_scale = key.target_size().height() / 141 float y_scale = key.target_size().height() /
144 static_cast<float>(key.src_rect().height()); 142 static_cast<float>(key.src_rect().height());
145 return SkSize::Make(x_scale, y_scale); 143 return SkSize::Make(x_scale, y_scale);
146 } 144 }
147 } 145 }
148 146
149 SkFilterQuality GetDecodedFilterQuality(const ImageDecodeControllerKey& key) { 147 SkFilterQuality GetDecodedFilterQuality(const ImageDecodeCacheKey& key) {
150 return std::min(key.filter_quality(), kLow_SkFilterQuality); 148 return std::min(key.filter_quality(), kLow_SkFilterQuality);
151 } 149 }
152 150
153 SkImageInfo CreateImageInfo(size_t width, 151 SkImageInfo CreateImageInfo(size_t width,
154 size_t height, 152 size_t height,
155 ResourceFormat format) { 153 ResourceFormat format) {
156 return SkImageInfo::Make(width, height, 154 return SkImageInfo::Make(width, height,
157 ResourceFormatToClosestSkColorType(format), 155 ResourceFormatToClosestSkColorType(format),
158 kPremul_SkAlphaType); 156 kPremul_SkAlphaType);
159 } 157 }
160 158
161 void RecordLockExistingCachedImageHistogram(TilePriority::PriorityBin bin, 159 void RecordLockExistingCachedImageHistogram(TilePriority::PriorityBin bin,
162 bool success) { 160 bool success) {
163 switch (bin) { 161 switch (bin) {
164 case TilePriority::NOW: 162 case TilePriority::NOW:
165 UMA_HISTOGRAM_BOOLEAN("Renderer4.LockExistingCachedImage.Software.NOW", 163 UMA_HISTOGRAM_BOOLEAN("Renderer4.LockExistingCachedImage.Software.NOW",
166 success); 164 success);
167 case TilePriority::SOON: 165 case TilePriority::SOON:
168 UMA_HISTOGRAM_BOOLEAN("Renderer4.LockExistingCachedImage.Software.SOON", 166 UMA_HISTOGRAM_BOOLEAN("Renderer4.LockExistingCachedImage.Software.SOON",
169 success); 167 success);
170 case TilePriority::EVENTUALLY: 168 case TilePriority::EVENTUALLY:
171 UMA_HISTOGRAM_BOOLEAN( 169 UMA_HISTOGRAM_BOOLEAN(
172 "Renderer4.LockExistingCachedImage.Software.EVENTUALLY", success); 170 "Renderer4.LockExistingCachedImage.Software.EVENTUALLY", success);
173 } 171 }
174 } 172 }
175 173
176 } // namespace 174 } // namespace
177 175
178 SoftwareImageDecodeController::SoftwareImageDecodeController( 176 SoftwareImageDecodeCache::SoftwareImageDecodeCache(
179 ResourceFormat format, 177 ResourceFormat format,
180 size_t locked_memory_limit_bytes) 178 size_t locked_memory_limit_bytes)
181 : decoded_images_(ImageMRUCache::NO_AUTO_EVICT), 179 : decoded_images_(ImageMRUCache::NO_AUTO_EVICT),
182 at_raster_decoded_images_(ImageMRUCache::NO_AUTO_EVICT), 180 at_raster_decoded_images_(ImageMRUCache::NO_AUTO_EVICT),
183 locked_images_budget_(locked_memory_limit_bytes), 181 locked_images_budget_(locked_memory_limit_bytes),
184 format_(format), 182 format_(format),
185 max_items_in_cache_(kNormalMaxItemsInCache) { 183 max_items_in_cache_(kNormalMaxItemsInCache) {
186 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). 184 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
187 // Don't register a dump provider in these cases. 185 // Don't register a dump provider in these cases.
188 if (base::ThreadTaskRunnerHandle::IsSet()) { 186 if (base::ThreadTaskRunnerHandle::IsSet()) {
189 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( 187 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
190 this, "cc::SoftwareImageDecodeController", 188 this, "cc::SoftwareImageDecodeCache",
191 base::ThreadTaskRunnerHandle::Get()); 189 base::ThreadTaskRunnerHandle::Get());
192 } 190 }
193 // Register this component with base::MemoryCoordinatorClientRegistry. 191 // Register this component with base::MemoryCoordinatorClientRegistry.
194 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); 192 base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
195 } 193 }
196 194
197 SoftwareImageDecodeController::~SoftwareImageDecodeController() { 195 SoftwareImageDecodeCache::~SoftwareImageDecodeCache() {
198 DCHECK_EQ(0u, decoded_images_ref_counts_.size()); 196 DCHECK_EQ(0u, decoded_images_ref_counts_.size());
199 DCHECK_EQ(0u, at_raster_decoded_images_ref_counts_.size()); 197 DCHECK_EQ(0u, at_raster_decoded_images_ref_counts_.size());
200 198
201 // It is safe to unregister, even if we didn't register in the constructor. 199 // It is safe to unregister, even if we didn't register in the constructor.
202 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( 200 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
203 this); 201 this);
204 // Unregister this component with memory_coordinator::ClientRegistry. 202 // Unregister this component with memory_coordinator::ClientRegistry.
205 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this); 203 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this);
206 } 204 }
207 205
208 bool SoftwareImageDecodeController::GetTaskForImageAndRef( 206 bool SoftwareImageDecodeCache::GetTaskForImageAndRef(
209 const DrawImage& image, 207 const DrawImage& image,
210 const TracingInfo& tracing_info, 208 const TracingInfo& tracing_info,
211 scoped_refptr<TileTask>* task) { 209 scoped_refptr<TileTask>* task) {
212 // If the image already exists or if we're going to create a task for it, then 210 // If the image already exists or if we're going to create a task for it, then
213 // we'll likely need to ref this image (the exception is if we're prerolling 211 // we'll likely need to ref this image (the exception is if we're prerolling
214 // the image only). That means the image is or will be in the cache. When the 212 // the image only). That means the image is or will be in the cache. When the
215 // ref goes to 0, it will be unpinned but will remain in the cache. If the 213 // ref goes to 0, it will be unpinned but will remain in the cache. If the
216 // image does not fit into the budget, then we don't ref this image, since it 214 // image does not fit into the budget, then we don't ref this image, since it
217 // will be decoded at raster time which is when it will be temporarily put in 215 // will be decoded at raster time which is when it will be temporarily put in
218 // the cache. 216 // the cache.
219 ImageKey key = ImageKey::FromDrawImage(image); 217 ImageKey key = ImageKey::FromDrawImage(image);
220 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 218 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
221 "SoftwareImageDecodeController::GetTaskForImageAndRef", "key", 219 "SoftwareImageDecodeCache::GetTaskForImageAndRef", "key",
222 key.ToString()); 220 key.ToString());
223 221
224 // If the target size is empty, we can skip this image during draw (and thus 222 // If the target size is empty, we can skip this image during draw (and thus
225 // we don't need to decode it or ref it). 223 // we don't need to decode it or ref it).
226 if (key.target_size().IsEmpty()) { 224 if (key.target_size().IsEmpty()) {
227 *task = nullptr; 225 *task = nullptr;
228 return false; 226 return false;
229 } 227 }
230 228
231 base::AutoLock lock(lock_); 229 base::AutoLock lock(lock_);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 // Actually create the task. RefImage will account for memory on the first 281 // Actually create the task. RefImage will account for memory on the first
284 // ref. 282 // ref.
285 RefImage(key); 283 RefImage(key);
286 existing_task = make_scoped_refptr( 284 existing_task = make_scoped_refptr(
287 new ImageDecodeTaskImpl(this, key, image, tracing_info)); 285 new ImageDecodeTaskImpl(this, key, image, tracing_info));
288 *task = existing_task; 286 *task = existing_task;
289 SanityCheckState(__LINE__, true); 287 SanityCheckState(__LINE__, true);
290 return true; 288 return true;
291 } 289 }
292 290
293 void SoftwareImageDecodeController::RefImage(const ImageKey& key) { 291 void SoftwareImageDecodeCache::RefImage(const ImageKey& key) {
294 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 292 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
295 "SoftwareImageDecodeController::RefImage", "key", 293 "SoftwareImageDecodeCache::RefImage", "key", key.ToString());
296 key.ToString());
297 lock_.AssertAcquired(); 294 lock_.AssertAcquired();
298 int ref = ++decoded_images_ref_counts_[key]; 295 int ref = ++decoded_images_ref_counts_[key];
299 if (ref == 1) { 296 if (ref == 1) {
300 DCHECK_GE(locked_images_budget_.AvailableMemoryBytes(), key.locked_bytes()); 297 DCHECK_GE(locked_images_budget_.AvailableMemoryBytes(), key.locked_bytes());
301 locked_images_budget_.AddUsage(key.locked_bytes()); 298 locked_images_budget_.AddUsage(key.locked_bytes());
302 } 299 }
303 } 300 }
304 301
305 void SoftwareImageDecodeController::UnrefImage(const DrawImage& image) { 302 void SoftwareImageDecodeCache::UnrefImage(const DrawImage& image) {
306 // When we unref the image, there are several situations we need to consider: 303 // When we unref the image, there are several situations we need to consider:
307 // 1. The ref did not reach 0, which means we have to keep the image locked. 304 // 1. The ref did not reach 0, which means we have to keep the image locked.
308 // 2. The ref reached 0, we should unlock it. 305 // 2. The ref reached 0, we should unlock it.
309 // 2a. The image isn't in the locked cache because we didn't get to decode 306 // 2a. The image isn't in the locked cache because we didn't get to decode
310 // it yet (or failed to decode it). 307 // it yet (or failed to decode it).
311 // 2b. Unlock the image but keep it in list. 308 // 2b. Unlock the image but keep it in list.
312 const ImageKey& key = ImageKey::FromDrawImage(image); 309 const ImageKey& key = ImageKey::FromDrawImage(image);
313 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 310 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
314 "SoftwareImageDecodeController::UnrefImage", "key", 311 "SoftwareImageDecodeCache::UnrefImage", "key", key.ToString());
315 key.ToString());
316 312
317 base::AutoLock lock(lock_); 313 base::AutoLock lock(lock_);
318 auto ref_count_it = decoded_images_ref_counts_.find(key); 314 auto ref_count_it = decoded_images_ref_counts_.find(key);
319 DCHECK(ref_count_it != decoded_images_ref_counts_.end()); 315 DCHECK(ref_count_it != decoded_images_ref_counts_.end());
320 316
321 --ref_count_it->second; 317 --ref_count_it->second;
322 if (ref_count_it->second == 0) { 318 if (ref_count_it->second == 0) {
323 decoded_images_ref_counts_.erase(ref_count_it); 319 decoded_images_ref_counts_.erase(ref_count_it);
324 locked_images_budget_.SubtractUsage(key.locked_bytes()); 320 locked_images_budget_.SubtractUsage(key.locked_bytes());
325 321
326 auto decoded_image_it = decoded_images_.Peek(key); 322 auto decoded_image_it = decoded_images_.Peek(key);
327 // If we've never decoded the image before ref reached 0, then we wouldn't 323 // If we've never decoded the image before ref reached 0, then we wouldn't
328 // have it in our cache. This would happen if we canceled tasks. 324 // have it in our cache. This would happen if we canceled tasks.
329 if (decoded_image_it == decoded_images_.end()) { 325 if (decoded_image_it == decoded_images_.end()) {
330 SanityCheckState(__LINE__, true); 326 SanityCheckState(__LINE__, true);
331 return; 327 return;
332 } 328 }
333 DCHECK(decoded_image_it->second->is_locked()); 329 DCHECK(decoded_image_it->second->is_locked());
334 decoded_image_it->second->Unlock(); 330 decoded_image_it->second->Unlock();
335 } 331 }
336 SanityCheckState(__LINE__, true); 332 SanityCheckState(__LINE__, true);
337 } 333 }
338 334
339 void SoftwareImageDecodeController::DecodeImage(const ImageKey& key, 335 void SoftwareImageDecodeCache::DecodeImage(const ImageKey& key,
340 const DrawImage& image) { 336 const DrawImage& image) {
341 TRACE_EVENT1("cc", "SoftwareImageDecodeController::DecodeImage", "key", 337 TRACE_EVENT1("cc", "SoftwareImageDecodeCache::DecodeImage", "key",
342 key.ToString()); 338 key.ToString());
343 base::AutoLock lock(lock_); 339 base::AutoLock lock(lock_);
344 AutoRemoveKeyFromTaskMap remove_key_from_task_map(&pending_image_tasks_, key); 340 AutoRemoveKeyFromTaskMap remove_key_from_task_map(&pending_image_tasks_, key);
345 341
346 // We could have finished all of the raster tasks (cancelled) while the task 342 // We could have finished all of the raster tasks (cancelled) while the task
347 // was just starting to run. Since this task already started running, it 343 // was just starting to run. Since this task already started running, it
348 // wasn't cancelled. So, if the ref count for the image is 0 then we can just 344 // wasn't cancelled. So, if the ref count for the image is 0 then we can just
349 // abort. 345 // abort.
350 if (decoded_images_ref_counts_.find(key) == 346 if (decoded_images_ref_counts_.find(key) ==
351 decoded_images_ref_counts_.end()) { 347 decoded_images_ref_counts_.end()) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 // ref counts. Unlock it immediately in this case. 384 // ref counts. Unlock it immediately in this case.
389 if (decoded_images_ref_counts_.find(key) == 385 if (decoded_images_ref_counts_.find(key) ==
390 decoded_images_ref_counts_.end()) { 386 decoded_images_ref_counts_.end()) {
391 decoded_image->Unlock(); 387 decoded_image->Unlock();
392 } 388 }
393 389
394 decoded_images_.Put(key, std::move(decoded_image)); 390 decoded_images_.Put(key, std::move(decoded_image));
395 SanityCheckState(__LINE__, true); 391 SanityCheckState(__LINE__, true);
396 } 392 }
397 393
398 std::unique_ptr<SoftwareImageDecodeController::DecodedImage> 394 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
399 SoftwareImageDecodeController::DecodeImageInternal( 395 SoftwareImageDecodeCache::DecodeImageInternal(const ImageKey& key,
400 const ImageKey& key, 396 const DrawImage& draw_image) {
401 const DrawImage& draw_image) {
402 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 397 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
403 "SoftwareImageDecodeController::DecodeImageInternal", "key", 398 "SoftwareImageDecodeCache::DecodeImageInternal", "key",
404 key.ToString()); 399 key.ToString());
405 sk_sp<const SkImage> image = draw_image.image(); 400 sk_sp<const SkImage> image = draw_image.image();
406 if (!image) 401 if (!image)
407 return nullptr; 402 return nullptr;
408 403
409 switch (key.filter_quality()) { 404 switch (key.filter_quality()) {
410 case kNone_SkFilterQuality: 405 case kNone_SkFilterQuality:
411 case kLow_SkFilterQuality: 406 case kLow_SkFilterQuality:
412 if (key.should_use_subrect()) 407 if (key.should_use_subrect())
413 return GetSubrectImageDecode(key, std::move(image)); 408 return GetSubrectImageDecode(key, std::move(image));
414 return GetOriginalImageDecode(std::move(image)); 409 return GetOriginalImageDecode(std::move(image));
415 case kMedium_SkFilterQuality: 410 case kMedium_SkFilterQuality:
416 case kHigh_SkFilterQuality: 411 case kHigh_SkFilterQuality:
417 return GetScaledImageDecode(key, std::move(image)); 412 return GetScaledImageDecode(key, std::move(image));
418 default: 413 default:
419 NOTREACHED(); 414 NOTREACHED();
420 return nullptr; 415 return nullptr;
421 } 416 }
422 } 417 }
423 418
424 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( 419 DecodedDrawImage SoftwareImageDecodeCache::GetDecodedImageForDraw(
425 const DrawImage& draw_image) { 420 const DrawImage& draw_image) {
426 ImageKey key = ImageKey::FromDrawImage(draw_image); 421 ImageKey key = ImageKey::FromDrawImage(draw_image);
427 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 422 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
428 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", 423 "SoftwareImageDecodeCache::GetDecodedImageForDraw", "key",
429 key.ToString()); 424 key.ToString());
430 // If the target size is empty, we can skip this image draw. 425 // If the target size is empty, we can skip this image draw.
431 if (key.target_size().IsEmpty()) 426 if (key.target_size().IsEmpty())
432 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); 427 return DecodedDrawImage(nullptr, kNone_SkFilterQuality);
433 428
434 return GetDecodedImageForDrawInternal(key, draw_image); 429 return GetDecodedImageForDrawInternal(key, draw_image);
435 } 430 }
436 431
437 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal( 432 DecodedDrawImage SoftwareImageDecodeCache::GetDecodedImageForDrawInternal(
438 const ImageKey& key, 433 const ImageKey& key,
439 const DrawImage& draw_image) { 434 const DrawImage& draw_image) {
440 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 435 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
441 "SoftwareImageDecodeController::GetDecodedImageForDrawInternal", 436 "SoftwareImageDecodeCache::GetDecodedImageForDrawInternal",
442 "key", key.ToString()); 437 "key", key.ToString());
443 base::AutoLock lock(lock_); 438 base::AutoLock lock(lock_);
444 auto decoded_images_it = decoded_images_.Get(key); 439 auto decoded_images_it = decoded_images_.Get(key);
445 // If we found the image and it's locked, then return it. If it's not locked, 440 // If we found the image and it's locked, then return it. If it's not locked,
446 // erase it from the cache since it might be put into the at-raster cache. 441 // erase it from the cache since it might be put into the at-raster cache.
447 std::unique_ptr<DecodedImage> scoped_decoded_image; 442 std::unique_ptr<DecodedImage> scoped_decoded_image;
448 DecodedImage* decoded_image = nullptr; 443 DecodedImage* decoded_image = nullptr;
449 if (decoded_images_it != decoded_images_.end()) { 444 if (decoded_images_it != decoded_images_.end()) {
450 decoded_image = decoded_images_it->second.get(); 445 decoded_image = decoded_images_it->second.get();
451 if (decoded_image->is_locked()) { 446 if (decoded_image->is_locked()) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 RefAtRasterImage(key); 518 RefAtRasterImage(key);
524 SanityCheckState(__LINE__, true); 519 SanityCheckState(__LINE__, true);
525 decoded_image->mark_used(); 520 decoded_image->mark_used();
526 auto decoded_draw_image = 521 auto decoded_draw_image =
527 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(), 522 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(),
528 GetScaleAdjustment(key), GetDecodedFilterQuality(key)); 523 GetScaleAdjustment(key), GetDecodedFilterQuality(key));
529 decoded_draw_image.set_at_raster_decode(true); 524 decoded_draw_image.set_at_raster_decode(true);
530 return decoded_draw_image; 525 return decoded_draw_image;
531 } 526 }
532 527
533 std::unique_ptr<SoftwareImageDecodeController::DecodedImage> 528 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
534 SoftwareImageDecodeController::GetOriginalImageDecode( 529 SoftwareImageDecodeCache::GetOriginalImageDecode(sk_sp<const SkImage> image) {
535 sk_sp<const SkImage> image) {
536 SkImageInfo decoded_info = 530 SkImageInfo decoded_info =
537 CreateImageInfo(image->width(), image->height(), format_); 531 CreateImageInfo(image->width(), image->height(), format_);
538 std::unique_ptr<base::DiscardableMemory> decoded_pixels; 532 std::unique_ptr<base::DiscardableMemory> decoded_pixels;
539 { 533 {
540 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 534 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
541 "SoftwareImageDecodeController::GetOriginalImageDecode - " 535 "SoftwareImageDecodeCache::GetOriginalImageDecode - "
542 "allocate decoded pixels"); 536 "allocate decoded pixels");
543 decoded_pixels = 537 decoded_pixels =
544 base::DiscardableMemoryAllocator::GetInstance() 538 base::DiscardableMemoryAllocator::GetInstance()
545 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() * 539 ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() *
546 decoded_info.height()); 540 decoded_info.height());
547 } 541 }
548 { 542 {
549 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 543 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
550 "SoftwareImageDecodeController::GetOriginalImageDecode - " 544 "SoftwareImageDecodeCache::GetOriginalImageDecode - "
551 "read pixels"); 545 "read pixels");
552 bool result = image->readPixels(decoded_info, decoded_pixels->data(), 546 bool result = image->readPixels(decoded_info, decoded_pixels->data(),
553 decoded_info.minRowBytes(), 0, 0, 547 decoded_info.minRowBytes(), 0, 0,
554 SkImage::kDisallow_CachingHint); 548 SkImage::kDisallow_CachingHint);
555 549
556 if (!result) { 550 if (!result) {
557 decoded_pixels->Unlock(); 551 decoded_pixels->Unlock();
558 return nullptr; 552 return nullptr;
559 } 553 }
560 } 554 }
561 return base::MakeUnique<DecodedImage>(decoded_info, std::move(decoded_pixels), 555 return base::MakeUnique<DecodedImage>(decoded_info, std::move(decoded_pixels),
562 SkSize::Make(0, 0), 556 SkSize::Make(0, 0),
563 next_tracing_id_.GetNext()); 557 next_tracing_id_.GetNext());
564 } 558 }
565 559
566 std::unique_ptr<SoftwareImageDecodeController::DecodedImage> 560 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
567 SoftwareImageDecodeController::GetSubrectImageDecode( 561 SoftwareImageDecodeCache::GetSubrectImageDecode(const ImageKey& key,
568 const ImageKey& key, 562 sk_sp<const SkImage> image) {
569 sk_sp<const SkImage> image) {
570 // Construct a key to use in GetDecodedImageForDrawInternal(). 563 // Construct a key to use in GetDecodedImageForDrawInternal().
571 // This allows us to reuse an image in any cache if available. 564 // This allows us to reuse an image in any cache if available.
572 gfx::Rect full_image_rect(image->width(), image->height()); 565 gfx::Rect full_image_rect(image->width(), image->height());
573 DrawImage original_size_draw_image(std::move(image), 566 DrawImage original_size_draw_image(std::move(image),
574 gfx::RectToSkIRect(full_image_rect), 567 gfx::RectToSkIRect(full_image_rect),
575 kNone_SkFilterQuality, SkMatrix::I()); 568 kNone_SkFilterQuality, SkMatrix::I());
576 ImageKey original_size_key = 569 ImageKey original_size_key =
577 ImageKey::FromDrawImage(original_size_draw_image); 570 ImageKey::FromDrawImage(original_size_draw_image);
578 // Sanity checks. 571 // Sanity checks.
579 DCHECK(original_size_key.can_use_original_decode()) 572 DCHECK(original_size_key.can_use_original_decode())
580 << original_size_key.ToString(); 573 << original_size_key.ToString();
581 DCHECK(full_image_rect.size() == original_size_key.target_size()); 574 DCHECK(full_image_rect.size() == original_size_key.target_size());
582 575
583 auto decoded_draw_image = GetDecodedImageForDrawInternal( 576 auto decoded_draw_image = GetDecodedImageForDrawInternal(
584 original_size_key, original_size_draw_image); 577 original_size_key, original_size_draw_image);
585 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image, 578 AutoDrawWithImageFinished auto_finish_draw(this, original_size_draw_image,
586 decoded_draw_image); 579 decoded_draw_image);
587 if (!decoded_draw_image.image()) 580 if (!decoded_draw_image.image())
588 return nullptr; 581 return nullptr;
589 582
590 SkImageInfo subrect_info = CreateImageInfo( 583 SkImageInfo subrect_info = CreateImageInfo(
591 key.target_size().width(), key.target_size().height(), format_); 584 key.target_size().width(), key.target_size().height(), format_);
592 std::unique_ptr<base::DiscardableMemory> subrect_pixels; 585 std::unique_ptr<base::DiscardableMemory> subrect_pixels;
593 { 586 {
594 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 587 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
595 "SoftwareImageDecodeController::GetSubrectImageDecode - " 588 "SoftwareImageDecodeCache::GetSubrectImageDecode - "
596 "allocate subrect pixels"); 589 "allocate subrect pixels");
597 // TODO(vmpstr): This is using checked math to diagnose a problem reported 590 // TODO(vmpstr): This is using checked math to diagnose a problem reported
598 // in crbug.com/662217. If this is causing crashes, then it should be fixed 591 // in crbug.com/662217. If this is causing crashes, then it should be fixed
599 // elsewhere by skipping images that are too large. 592 // elsewhere by skipping images that are too large.
600 base::CheckedNumeric<size_t> byte_size = subrect_info.minRowBytes(); 593 base::CheckedNumeric<size_t> byte_size = subrect_info.minRowBytes();
601 byte_size *= subrect_info.height(); 594 byte_size *= subrect_info.height();
602 subrect_pixels = 595 subrect_pixels =
603 base::DiscardableMemoryAllocator::GetInstance() 596 base::DiscardableMemoryAllocator::GetInstance()
604 ->AllocateLockedDiscardableMemory(byte_size.ValueOrDie()); 597 ->AllocateLockedDiscardableMemory(byte_size.ValueOrDie());
605 } 598 }
606 { 599 {
607 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 600 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
608 "SoftwareImageDecodeController::GetOriginalImageDecode - " 601 "SoftwareImageDecodeCache::GetOriginalImageDecode - "
609 "read pixels"); 602 "read pixels");
610 bool result = decoded_draw_image.image()->readPixels( 603 bool result = decoded_draw_image.image()->readPixels(
611 subrect_info, subrect_pixels->data(), subrect_info.minRowBytes(), 604 subrect_info, subrect_pixels->data(), subrect_info.minRowBytes(),
612 key.src_rect().x(), key.src_rect().y(), SkImage::kDisallow_CachingHint); 605 key.src_rect().x(), key.src_rect().y(), SkImage::kDisallow_CachingHint);
613 // We have a decoded image, and we're reading into already allocated memory. 606 // We have a decoded image, and we're reading into already allocated memory.
614 // This should never fail. 607 // This should never fail.
615 DCHECK(result); 608 DCHECK(result);
616 } 609 }
617 return base::WrapUnique( 610 return base::WrapUnique(
618 new DecodedImage(subrect_info, std::move(subrect_pixels), 611 new DecodedImage(subrect_info, std::move(subrect_pixels),
619 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), 612 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()),
620 next_tracing_id_.GetNext())); 613 next_tracing_id_.GetNext()));
621 } 614 }
622 615
623 std::unique_ptr<SoftwareImageDecodeController::DecodedImage> 616 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
624 SoftwareImageDecodeController::GetScaledImageDecode( 617 SoftwareImageDecodeCache::GetScaledImageDecode(const ImageKey& key,
625 const ImageKey& key, 618 sk_sp<const SkImage> image) {
626 sk_sp<const SkImage> image) {
627 // Construct a key to use in GetDecodedImageForDrawInternal(). 619 // Construct a key to use in GetDecodedImageForDrawInternal().
628 // This allows us to reuse an image in any cache if available. 620 // This allows us to reuse an image in any cache if available.
629 gfx::Rect full_image_rect(image->width(), image->height()); 621 gfx::Rect full_image_rect(image->width(), image->height());
630 DrawImage original_size_draw_image(std::move(image), 622 DrawImage original_size_draw_image(std::move(image),
631 gfx::RectToSkIRect(full_image_rect), 623 gfx::RectToSkIRect(full_image_rect),
632 kNone_SkFilterQuality, SkMatrix::I()); 624 kNone_SkFilterQuality, SkMatrix::I());
633 ImageKey original_size_key = 625 ImageKey original_size_key =
634 ImageKey::FromDrawImage(original_size_draw_image); 626 ImageKey::FromDrawImage(original_size_draw_image);
635 // Sanity checks. 627 // Sanity checks.
636 DCHECK(original_size_key.can_use_original_decode()) 628 DCHECK(original_size_key.can_use_original_decode())
(...skipping 16 matching lines...) Expand all
653 DCHECK(result) << key.ToString(); 645 DCHECK(result) << key.ToString();
654 } 646 }
655 647
656 DCHECK(!key.target_size().IsEmpty()); 648 DCHECK(!key.target_size().IsEmpty());
657 SkImageInfo scaled_info = CreateImageInfo( 649 SkImageInfo scaled_info = CreateImageInfo(
658 key.target_size().width(), key.target_size().height(), format_); 650 key.target_size().width(), key.target_size().height(), format_);
659 std::unique_ptr<base::DiscardableMemory> scaled_pixels; 651 std::unique_ptr<base::DiscardableMemory> scaled_pixels;
660 { 652 {
661 TRACE_EVENT0( 653 TRACE_EVENT0(
662 TRACE_DISABLED_BY_DEFAULT("cc.debug"), 654 TRACE_DISABLED_BY_DEFAULT("cc.debug"),
663 "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels"); 655 "SoftwareImageDecodeCache::ScaleImage - allocate scaled pixels");
664 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() 656 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
665 ->AllocateLockedDiscardableMemory( 657 ->AllocateLockedDiscardableMemory(
666 scaled_info.minRowBytes() * scaled_info.height()); 658 scaled_info.minRowBytes() * scaled_info.height());
667 } 659 }
668 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), 660 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
669 scaled_info.minRowBytes()); 661 scaled_info.minRowBytes());
670 DCHECK(key.filter_quality() == kHigh_SkFilterQuality || 662 DCHECK(key.filter_quality() == kHigh_SkFilterQuality ||
671 key.filter_quality() == kMedium_SkFilterQuality); 663 key.filter_quality() == kMedium_SkFilterQuality);
672 { 664 {
673 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 665 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
674 "SoftwareImageDecodeController::ScaleImage - scale pixels"); 666 "SoftwareImageDecodeCache::ScaleImage - scale pixels");
675 bool result = 667 bool result =
676 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); 668 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality());
677 DCHECK(result) << key.ToString(); 669 DCHECK(result) << key.ToString();
678 } 670 }
679 671
680 return base::MakeUnique<DecodedImage>( 672 return base::MakeUnique<DecodedImage>(
681 scaled_info, std::move(scaled_pixels), 673 scaled_info, std::move(scaled_pixels),
682 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), 674 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()),
683 next_tracing_id_.GetNext()); 675 next_tracing_id_.GetNext());
684 } 676 }
685 677
686 void SoftwareImageDecodeController::DrawWithImageFinished( 678 void SoftwareImageDecodeCache::DrawWithImageFinished(
687 const DrawImage& image, 679 const DrawImage& image,
688 const DecodedDrawImage& decoded_image) { 680 const DecodedDrawImage& decoded_image) {
689 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 681 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
690 "SoftwareImageDecodeController::DrawWithImageFinished", "key", 682 "SoftwareImageDecodeCache::DrawWithImageFinished", "key",
691 ImageKey::FromDrawImage(image).ToString()); 683 ImageKey::FromDrawImage(image).ToString());
692 ImageKey key = ImageKey::FromDrawImage(image); 684 ImageKey key = ImageKey::FromDrawImage(image);
693 if (!decoded_image.image()) 685 if (!decoded_image.image())
694 return; 686 return;
695 687
696 if (decoded_image.is_at_raster_decode()) 688 if (decoded_image.is_at_raster_decode())
697 UnrefAtRasterImage(key); 689 UnrefAtRasterImage(key);
698 else 690 else
699 UnrefImage(image); 691 UnrefImage(image);
700 SanityCheckState(__LINE__, false); 692 SanityCheckState(__LINE__, false);
701 } 693 }
702 694
703 void SoftwareImageDecodeController::RefAtRasterImage(const ImageKey& key) { 695 void SoftwareImageDecodeCache::RefAtRasterImage(const ImageKey& key) {
704 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 696 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
705 "SoftwareImageDecodeController::RefAtRasterImage", "key", 697 "SoftwareImageDecodeCache::RefAtRasterImage", "key",
706 key.ToString()); 698 key.ToString());
707 DCHECK(at_raster_decoded_images_.Peek(key) != 699 DCHECK(at_raster_decoded_images_.Peek(key) !=
708 at_raster_decoded_images_.end()); 700 at_raster_decoded_images_.end());
709 ++at_raster_decoded_images_ref_counts_[key]; 701 ++at_raster_decoded_images_ref_counts_[key];
710 } 702 }
711 703
712 void SoftwareImageDecodeController::UnrefAtRasterImage(const ImageKey& key) { 704 void SoftwareImageDecodeCache::UnrefAtRasterImage(const ImageKey& key) {
713 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 705 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
714 "SoftwareImageDecodeController::UnrefAtRasterImage", "key", 706 "SoftwareImageDecodeCache::UnrefAtRasterImage", "key",
715 key.ToString()); 707 key.ToString());
716 base::AutoLock lock(lock_); 708 base::AutoLock lock(lock_);
717 709
718 auto ref_it = at_raster_decoded_images_ref_counts_.find(key); 710 auto ref_it = at_raster_decoded_images_ref_counts_.find(key);
719 DCHECK(ref_it != at_raster_decoded_images_ref_counts_.end()); 711 DCHECK(ref_it != at_raster_decoded_images_ref_counts_.end());
720 --ref_it->second; 712 --ref_it->second;
721 if (ref_it->second == 0) { 713 if (ref_it->second == 0) {
722 at_raster_decoded_images_ref_counts_.erase(ref_it); 714 at_raster_decoded_images_ref_counts_.erase(ref_it);
723 auto at_raster_image_it = at_raster_decoded_images_.Peek(key); 715 auto at_raster_image_it = at_raster_decoded_images_.Peek(key);
724 DCHECK(at_raster_image_it != at_raster_decoded_images_.end()); 716 DCHECK(at_raster_image_it != at_raster_decoded_images_.end());
(...skipping 25 matching lines...) Expand all
750 DCHECK(decoded_images_ref_counts_.find(key) == 742 DCHECK(decoded_images_ref_counts_.find(key) ==
751 decoded_images_ref_counts_.end()); 743 decoded_images_ref_counts_.end());
752 at_raster_image_it->second->Unlock(); 744 at_raster_image_it->second->Unlock();
753 decoded_images_.Erase(image_it); 745 decoded_images_.Erase(image_it);
754 decoded_images_.Put(key, std::move(at_raster_image_it->second)); 746 decoded_images_.Put(key, std::move(at_raster_image_it->second));
755 } 747 }
756 at_raster_decoded_images_.Erase(at_raster_image_it); 748 at_raster_decoded_images_.Erase(at_raster_image_it);
757 } 749 }
758 } 750 }
759 751
760 void SoftwareImageDecodeController::ReduceCacheUsage() { 752 void SoftwareImageDecodeCache::ReduceCacheUsage() {
761 TRACE_EVENT0("cc", "SoftwareImageDecodeController::ReduceCacheUsage"); 753 TRACE_EVENT0("cc", "SoftwareImageDecodeCache::ReduceCacheUsage");
762 base::AutoLock lock(lock_); 754 base::AutoLock lock(lock_);
763 size_t num_to_remove = (decoded_images_.size() > max_items_in_cache_) 755 size_t num_to_remove = (decoded_images_.size() > max_items_in_cache_)
764 ? (decoded_images_.size() - max_items_in_cache_) 756 ? (decoded_images_.size() - max_items_in_cache_)
765 : 0; 757 : 0;
766 for (auto it = decoded_images_.rbegin(); 758 for (auto it = decoded_images_.rbegin();
767 num_to_remove != 0 && it != decoded_images_.rend();) { 759 num_to_remove != 0 && it != decoded_images_.rend();) {
768 if (it->second->is_locked()) { 760 if (it->second->is_locked()) {
769 ++it; 761 ++it;
770 continue; 762 continue;
771 } 763 }
772 764
773 it = decoded_images_.Erase(it); 765 it = decoded_images_.Erase(it);
774 --num_to_remove; 766 --num_to_remove;
775 } 767 }
776 } 768 }
777 769
778 void SoftwareImageDecodeController::RemovePendingTask(const ImageKey& key) { 770 void SoftwareImageDecodeCache::RemovePendingTask(const ImageKey& key) {
779 base::AutoLock lock(lock_); 771 base::AutoLock lock(lock_);
780 pending_image_tasks_.erase(key); 772 pending_image_tasks_.erase(key);
781 } 773 }
782 774
783 bool SoftwareImageDecodeController::OnMemoryDump( 775 bool SoftwareImageDecodeCache::OnMemoryDump(
784 const base::trace_event::MemoryDumpArgs& args, 776 const base::trace_event::MemoryDumpArgs& args,
785 base::trace_event::ProcessMemoryDump* pmd) { 777 base::trace_event::ProcessMemoryDump* pmd) {
786 base::AutoLock lock(lock_); 778 base::AutoLock lock(lock_);
787 779
788 if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) { 780 if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) {
789 std::string dump_name = 781 std::string dump_name = base::StringPrintf(
790 base::StringPrintf("cc/image_memory/controller_0x%" PRIXPTR, 782 "cc/image_memory/cache_0x%" PRIXPTR, reinterpret_cast<uintptr_t>(this));
791 reinterpret_cast<uintptr_t>(this));
792 MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name); 783 MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name);
793 dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes, 784 dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes,
794 locked_images_budget_.GetCurrentUsageSafe()); 785 locked_images_budget_.GetCurrentUsageSafe());
795 } else { 786 } else {
796 // Dump each of our caches. 787 // Dump each of our caches.
797 DumpImageMemoryForCache(decoded_images_, "cached", pmd); 788 DumpImageMemoryForCache(decoded_images_, "cached", pmd);
798 DumpImageMemoryForCache(at_raster_decoded_images_, "at_raster", pmd); 789 DumpImageMemoryForCache(at_raster_decoded_images_, "at_raster", pmd);
799 } 790 }
800 791
801 // Memory dump can't fail, always return true. 792 // Memory dump can't fail, always return true.
802 return true; 793 return true;
803 } 794 }
804 795
805 void SoftwareImageDecodeController::DumpImageMemoryForCache( 796 void SoftwareImageDecodeCache::DumpImageMemoryForCache(
806 const ImageMRUCache& cache, 797 const ImageMRUCache& cache,
807 const char* cache_name, 798 const char* cache_name,
808 base::trace_event::ProcessMemoryDump* pmd) const { 799 base::trace_event::ProcessMemoryDump* pmd) const {
809 lock_.AssertAcquired(); 800 lock_.AssertAcquired();
810 801
811 for (const auto& image_pair : cache) { 802 for (const auto& image_pair : cache) {
812 std::string dump_name = base::StringPrintf( 803 std::string dump_name = base::StringPrintf(
813 "cc/image_memory/controller_0x%" PRIXPTR "/%s/image_%" PRIu64 "_id_%d", 804 "cc/image_memory/cache_0x%" PRIXPTR "/%s/image_%" PRIu64 "_id_%d",
814 reinterpret_cast<uintptr_t>(this), cache_name, 805 reinterpret_cast<uintptr_t>(this), cache_name,
815 image_pair.second->tracing_id(), image_pair.first.image_id()); 806 image_pair.second->tracing_id(), image_pair.first.image_id());
816 // CreateMemoryAllocatorDump will automatically add tracking values for the 807 // CreateMemoryAllocatorDump will automatically add tracking values for the
817 // total size. If locked, we also add a "locked_size" below. 808 // total size. If locked, we also add a "locked_size" below.
818 MemoryAllocatorDump* dump = 809 MemoryAllocatorDump* dump =
819 image_pair.second->memory()->CreateMemoryAllocatorDump( 810 image_pair.second->memory()->CreateMemoryAllocatorDump(
820 dump_name.c_str(), pmd); 811 dump_name.c_str(), pmd);
821 DCHECK(dump); 812 DCHECK(dump);
822 if (image_pair.second->is_locked()) { 813 if (image_pair.second->is_locked()) {
823 dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes, 814 dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes,
824 image_pair.first.locked_bytes()); 815 image_pair.first.locked_bytes());
825 } 816 }
826 } 817 }
827 } 818 }
828 819
829 void SoftwareImageDecodeController::SanityCheckState(int line, 820 void SoftwareImageDecodeCache::SanityCheckState(int line, bool lock_acquired) {
830 bool lock_acquired) {
831 #if DCHECK_IS_ON() 821 #if DCHECK_IS_ON()
832 if (!lock_acquired) { 822 if (!lock_acquired) {
833 base::AutoLock lock(lock_); 823 base::AutoLock lock(lock_);
834 SanityCheckState(line, true); 824 SanityCheckState(line, true);
835 return; 825 return;
836 } 826 }
837 827
838 MemoryBudget budget(locked_images_budget_.total_limit_bytes()); 828 MemoryBudget budget(locked_images_budget_.total_limit_bytes());
839 for (const auto& image_pair : decoded_images_) { 829 for (const auto& image_pair : decoded_images_) {
840 const auto& key = image_pair.first; 830 const auto& key = image_pair.first;
841 const auto& image = image_pair.second; 831 const auto& image = image_pair.second;
842 832
843 auto ref_it = decoded_images_ref_counts_.find(key); 833 auto ref_it = decoded_images_ref_counts_.find(key);
844 if (image->is_locked()) { 834 if (image->is_locked()) {
845 budget.AddUsage(key.locked_bytes()); 835 budget.AddUsage(key.locked_bytes());
846 DCHECK(ref_it != decoded_images_ref_counts_.end()) << line; 836 DCHECK(ref_it != decoded_images_ref_counts_.end()) << line;
847 } else { 837 } else {
848 DCHECK(ref_it == decoded_images_ref_counts_.end() || 838 DCHECK(ref_it == decoded_images_ref_counts_.end() ||
849 pending_image_tasks_.find(key) != pending_image_tasks_.end()) 839 pending_image_tasks_.find(key) != pending_image_tasks_.end())
850 << line; 840 << line;
851 } 841 }
852 } 842 }
853 DCHECK_GE(budget.AvailableMemoryBytes(), 843 DCHECK_GE(budget.AvailableMemoryBytes(),
854 locked_images_budget_.AvailableMemoryBytes()) 844 locked_images_budget_.AvailableMemoryBytes())
855 << line; 845 << line;
856 #endif // DCHECK_IS_ON() 846 #endif // DCHECK_IS_ON()
857 } 847 }
858 848
859 // SoftwareImageDecodeControllerKey 849 // SoftwareImageDecodeCacheKey
860 ImageDecodeControllerKey ImageDecodeControllerKey::FromDrawImage( 850 ImageDecodeCacheKey ImageDecodeCacheKey::FromDrawImage(const DrawImage& image) {
861 const DrawImage& image) {
862 const SkSize& scale = image.scale(); 851 const SkSize& scale = image.scale();
863 // If the src_rect falls outside of the image, we need to clip it since 852 // If the src_rect falls outside of the image, we need to clip it since
864 // otherwise we might end up with uninitialized memory in the decode process. 853 // otherwise we might end up with uninitialized memory in the decode process.
865 // Note that the scale is still unchanged and the target size is now a 854 // Note that the scale is still unchanged and the target size is now a
866 // function of the new src_rect. 855 // function of the new src_rect.
867 gfx::Rect src_rect = gfx::IntersectRects( 856 gfx::Rect src_rect = gfx::IntersectRects(
868 gfx::SkIRectToRect(image.src_rect()), 857 gfx::SkIRectToRect(image.src_rect()),
869 gfx::Rect(image.image()->width(), image.image()->height())); 858 gfx::Rect(image.image()->width(), image.image()->height()));
870 859
871 gfx::Size target_size( 860 gfx::Size target_size(
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 target_size = gfx::Size(image.image()->width(), image.image()->height()); 935 target_size = gfx::Size(image.image()->width(), image.image()->height());
947 } 936 }
948 937
949 if (quality == kMedium_SkFilterQuality && !target_size.IsEmpty()) { 938 if (quality == kMedium_SkFilterQuality && !target_size.IsEmpty()) {
950 SkSize mip_target_size = 939 SkSize mip_target_size =
951 MipMapUtil::GetScaleAdjustmentForSize(src_rect.size(), target_size); 940 MipMapUtil::GetScaleAdjustmentForSize(src_rect.size(), target_size);
952 target_size.set_width(src_rect.width() * mip_target_size.width()); 941 target_size.set_width(src_rect.width() * mip_target_size.width());
953 target_size.set_height(src_rect.height() * mip_target_size.height()); 942 target_size.set_height(src_rect.height() * mip_target_size.height());
954 } 943 }
955 944
956 return ImageDecodeControllerKey(image.image()->uniqueID(), src_rect, 945 return ImageDecodeCacheKey(image.image()->uniqueID(), src_rect, target_size,
957 target_size, quality, can_use_original_decode, 946 quality, can_use_original_decode,
958 should_use_subrect); 947 should_use_subrect);
959 } 948 }
960 949
961 ImageDecodeControllerKey::ImageDecodeControllerKey( 950 ImageDecodeCacheKey::ImageDecodeCacheKey(uint32_t image_id,
962 uint32_t image_id, 951 const gfx::Rect& src_rect,
963 const gfx::Rect& src_rect, 952 const gfx::Size& target_size,
964 const gfx::Size& target_size, 953 SkFilterQuality filter_quality,
965 SkFilterQuality filter_quality, 954 bool can_use_original_decode,
966 bool can_use_original_decode, 955 bool should_use_subrect)
967 bool should_use_subrect)
968 : image_id_(image_id), 956 : image_id_(image_id),
969 src_rect_(src_rect), 957 src_rect_(src_rect),
970 target_size_(target_size), 958 target_size_(target_size),
971 filter_quality_(filter_quality), 959 filter_quality_(filter_quality),
972 can_use_original_decode_(can_use_original_decode), 960 can_use_original_decode_(can_use_original_decode),
973 should_use_subrect_(should_use_subrect) { 961 should_use_subrect_(should_use_subrect) {
974 if (can_use_original_decode_) { 962 if (can_use_original_decode_) {
975 hash_ = std::hash<uint32_t>()(image_id_); 963 hash_ = std::hash<uint32_t>()(image_id_);
976 } else { 964 } else {
977 // TODO(vmpstr): This is a mess. Maybe it's faster to just search the vector 965 // TODO(vmpstr): This is a mess. Maybe it's faster to just search the vector
978 // always (forwards or backwards to account for LRU). 966 // always (forwards or backwards to account for LRU).
979 uint64_t src_rect_hash = base::HashInts( 967 uint64_t src_rect_hash = base::HashInts(
980 static_cast<uint64_t>(base::HashInts(src_rect_.x(), src_rect_.y())), 968 static_cast<uint64_t>(base::HashInts(src_rect_.x(), src_rect_.y())),
981 static_cast<uint64_t>( 969 static_cast<uint64_t>(
982 base::HashInts(src_rect_.width(), src_rect_.height()))); 970 base::HashInts(src_rect_.width(), src_rect_.height())));
983 971
984 uint64_t target_size_hash = 972 uint64_t target_size_hash =
985 base::HashInts(target_size_.width(), target_size_.height()); 973 base::HashInts(target_size_.width(), target_size_.height());
986 974
987 hash_ = base::HashInts(base::HashInts(src_rect_hash, target_size_hash), 975 hash_ = base::HashInts(base::HashInts(src_rect_hash, target_size_hash),
988 base::HashInts(image_id_, filter_quality_)); 976 base::HashInts(image_id_, filter_quality_));
989 } 977 }
990 } 978 }
991 979
992 ImageDecodeControllerKey::ImageDecodeControllerKey( 980 ImageDecodeCacheKey::ImageDecodeCacheKey(const ImageDecodeCacheKey& other) =
993 const ImageDecodeControllerKey& other) = default; 981 default;
994 982
995 std::string ImageDecodeControllerKey::ToString() const { 983 std::string ImageDecodeCacheKey::ToString() const {
996 std::ostringstream str; 984 std::ostringstream str;
997 str << "id[" << image_id_ << "] src_rect[" << src_rect_.x() << "," 985 str << "id[" << image_id_ << "] src_rect[" << src_rect_.x() << ","
998 << src_rect_.y() << " " << src_rect_.width() << "x" << src_rect_.height() 986 << src_rect_.y() << " " << src_rect_.width() << "x" << src_rect_.height()
999 << "] target_size[" << target_size_.width() << "x" 987 << "] target_size[" << target_size_.width() << "x"
1000 << target_size_.height() << "] filter_quality[" << filter_quality_ 988 << target_size_.height() << "] filter_quality[" << filter_quality_
1001 << "] can_use_original_decode [" << can_use_original_decode_ 989 << "] can_use_original_decode [" << can_use_original_decode_
1002 << "] should_use_subrect [" << should_use_subrect_ << "] hash [" << hash_ 990 << "] should_use_subrect [" << should_use_subrect_ << "] hash [" << hash_
1003 << "]"; 991 << "]";
1004 return str.str(); 992 return str.str();
1005 } 993 }
1006 994
1007 // DecodedImage 995 // DecodedImage
1008 SoftwareImageDecodeController::DecodedImage::DecodedImage( 996 SoftwareImageDecodeCache::DecodedImage::DecodedImage(
1009 const SkImageInfo& info, 997 const SkImageInfo& info,
1010 std::unique_ptr<base::DiscardableMemory> memory, 998 std::unique_ptr<base::DiscardableMemory> memory,
1011 const SkSize& src_rect_offset, 999 const SkSize& src_rect_offset,
1012 uint64_t tracing_id) 1000 uint64_t tracing_id)
1013 : locked_(true), 1001 : locked_(true),
1014 image_info_(info), 1002 image_info_(info),
1015 memory_(std::move(memory)), 1003 memory_(std::move(memory)),
1016 src_rect_offset_(src_rect_offset), 1004 src_rect_offset_(src_rect_offset),
1017 tracing_id_(tracing_id) { 1005 tracing_id_(tracing_id) {
1018 SkPixmap pixmap(image_info_, memory_->data(), image_info_.minRowBytes()); 1006 SkPixmap pixmap(image_info_, memory_->data(), image_info_.minRowBytes());
1019 image_ = SkImage::MakeFromRaster( 1007 image_ = SkImage::MakeFromRaster(
1020 pixmap, [](const void* pixels, void* context) {}, nullptr); 1008 pixmap, [](const void* pixels, void* context) {}, nullptr);
1021 } 1009 }
1022 1010
1023 SoftwareImageDecodeController::DecodedImage::~DecodedImage() { 1011 SoftwareImageDecodeCache::DecodedImage::~DecodedImage() {
1024 DCHECK(!locked_); 1012 DCHECK(!locked_);
1025 // lock_count | used | last lock failed | result state 1013 // lock_count | used | last lock failed | result state
1026 // ===========+=======+==================+================== 1014 // ===========+=======+==================+==================
1027 // 1 | false | false | WASTED 1015 // 1 | false | false | WASTED
1028 // 1 | false | true | WASTED 1016 // 1 | false | true | WASTED
1029 // 1 | true | false | USED 1017 // 1 | true | false | USED
1030 // 1 | true | true | USED_RELOCK_FAILED 1018 // 1 | true | true | USED_RELOCK_FAILED
1031 // >1 | false | false | WASTED_RELOCKED 1019 // >1 | false | false | WASTED_RELOCKED
1032 // >1 | false | true | WASTED_RELOCKED 1020 // >1 | false | true | WASTED_RELOCKED
1033 // >1 | true | false | USED_RELOCKED 1021 // >1 | true | false | USED_RELOCKED
(...skipping 22 matching lines...) Expand all
1056 else 1044 else
1057 state = DECODED_IMAGE_STATE_WASTED_RELOCKED; 1045 state = DECODED_IMAGE_STATE_WASTED_RELOCKED;
1058 } 1046 }
1059 1047
1060 UMA_HISTOGRAM_ENUMERATION("Renderer4.SoftwareImageDecodeState", state, 1048 UMA_HISTOGRAM_ENUMERATION("Renderer4.SoftwareImageDecodeState", state,
1061 DECODED_IMAGE_STATE_COUNT); 1049 DECODED_IMAGE_STATE_COUNT);
1062 UMA_HISTOGRAM_BOOLEAN("Renderer4.SoftwareImageDecodeState.FirstLockWasted", 1050 UMA_HISTOGRAM_BOOLEAN("Renderer4.SoftwareImageDecodeState.FirstLockWasted",
1063 usage_stats_.first_lock_wasted); 1051 usage_stats_.first_lock_wasted);
1064 } 1052 }
1065 1053
1066 bool SoftwareImageDecodeController::DecodedImage::Lock() { 1054 bool SoftwareImageDecodeCache::DecodedImage::Lock() {
1067 DCHECK(!locked_); 1055 DCHECK(!locked_);
1068 bool success = memory_->Lock(); 1056 bool success = memory_->Lock();
1069 if (!success) { 1057 if (!success) {
1070 usage_stats_.last_lock_failed = true; 1058 usage_stats_.last_lock_failed = true;
1071 return false; 1059 return false;
1072 } 1060 }
1073 locked_ = true; 1061 locked_ = true;
1074 ++usage_stats_.lock_count; 1062 ++usage_stats_.lock_count;
1075 return true; 1063 return true;
1076 } 1064 }
1077 1065
1078 void SoftwareImageDecodeController::DecodedImage::Unlock() { 1066 void SoftwareImageDecodeCache::DecodedImage::Unlock() {
1079 DCHECK(locked_); 1067 DCHECK(locked_);
1080 memory_->Unlock(); 1068 memory_->Unlock();
1081 locked_ = false; 1069 locked_ = false;
1082 if (usage_stats_.lock_count == 1) 1070 if (usage_stats_.lock_count == 1)
1083 usage_stats_.first_lock_wasted = !usage_stats_.used; 1071 usage_stats_.first_lock_wasted = !usage_stats_.used;
1084 } 1072 }
1085 1073
1086 // MemoryBudget 1074 // MemoryBudget
1087 SoftwareImageDecodeController::MemoryBudget::MemoryBudget(size_t limit_bytes) 1075 SoftwareImageDecodeCache::MemoryBudget::MemoryBudget(size_t limit_bytes)
1088 : limit_bytes_(limit_bytes), current_usage_bytes_(0u) {} 1076 : limit_bytes_(limit_bytes), current_usage_bytes_(0u) {}
1089 1077
1090 size_t SoftwareImageDecodeController::MemoryBudget::AvailableMemoryBytes() 1078 size_t SoftwareImageDecodeCache::MemoryBudget::AvailableMemoryBytes() const {
1091 const {
1092 size_t usage = GetCurrentUsageSafe(); 1079 size_t usage = GetCurrentUsageSafe();
1093 return usage >= limit_bytes_ ? 0u : (limit_bytes_ - usage); 1080 return usage >= limit_bytes_ ? 0u : (limit_bytes_ - usage);
1094 } 1081 }
1095 1082
1096 void SoftwareImageDecodeController::MemoryBudget::AddUsage(size_t usage) { 1083 void SoftwareImageDecodeCache::MemoryBudget::AddUsage(size_t usage) {
1097 current_usage_bytes_ += usage; 1084 current_usage_bytes_ += usage;
1098 } 1085 }
1099 1086
1100 void SoftwareImageDecodeController::MemoryBudget::SubtractUsage(size_t usage) { 1087 void SoftwareImageDecodeCache::MemoryBudget::SubtractUsage(size_t usage) {
1101 DCHECK_GE(current_usage_bytes_.ValueOrDefault(0u), usage); 1088 DCHECK_GE(current_usage_bytes_.ValueOrDefault(0u), usage);
1102 current_usage_bytes_ -= usage; 1089 current_usage_bytes_ -= usage;
1103 } 1090 }
1104 1091
1105 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { 1092 void SoftwareImageDecodeCache::MemoryBudget::ResetUsage() {
1106 current_usage_bytes_ = 0; 1093 current_usage_bytes_ = 0;
1107 } 1094 }
1108 1095
1109 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() 1096 size_t SoftwareImageDecodeCache::MemoryBudget::GetCurrentUsageSafe() const {
1110 const {
1111 return current_usage_bytes_.ValueOrDie(); 1097 return current_usage_bytes_.ValueOrDie();
1112 } 1098 }
1113 1099
1114 void SoftwareImageDecodeController::OnMemoryStateChange( 1100 void SoftwareImageDecodeCache::OnMemoryStateChange(base::MemoryState state) {
1115 base::MemoryState state) {
1116 { 1101 {
1117 base::AutoLock hold(lock_); 1102 base::AutoLock hold(lock_);
1118 switch (state) { 1103 switch (state) {
1119 case base::MemoryState::NORMAL: 1104 case base::MemoryState::NORMAL:
1120 max_items_in_cache_ = kNormalMaxItemsInCache; 1105 max_items_in_cache_ = kNormalMaxItemsInCache;
1121 break; 1106 break;
1122 case base::MemoryState::THROTTLED: 1107 case base::MemoryState::THROTTLED:
1123 max_items_in_cache_ = kThrottledMaxItemsInCache; 1108 max_items_in_cache_ = kThrottledMaxItemsInCache;
1124 break; 1109 break;
1125 case base::MemoryState::SUSPENDED: 1110 case base::MemoryState::SUSPENDED:
1126 max_items_in_cache_ = kSuspendedMaxItemsInCache; 1111 max_items_in_cache_ = kSuspendedMaxItemsInCache;
1127 break; 1112 break;
1128 case base::MemoryState::UNKNOWN: 1113 case base::MemoryState::UNKNOWN:
1129 NOTREACHED(); 1114 NOTREACHED();
1130 return; 1115 return;
1131 } 1116 }
1132 } 1117 }
1133 ReduceCacheUsage(); 1118 ReduceCacheUsage();
1134 } 1119 }
1135 1120
1136 } // namespace cc 1121 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tiles/software_image_decode_cache.h ('k') | cc/tiles/software_image_decode_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698