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

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

Issue 2537683002: cc: Add image decode queue functionality to image manager. (Closed)
Patch Set: image-queue: 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_cache.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>
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 SoftwareImageDecodeCache* cache_; 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(SoftwareImageDecodeCache* cache, 94 ImageDecodeTaskImpl(SoftwareImageDecodeCache* cache,
95 const SoftwareImageDecodeCache::ImageKey& image_key, 95 const SoftwareImageDecodeCache::ImageKey& image_key,
96 const DrawImage& image, 96 const DrawImage& image,
97 const SoftwareImageDecodeCache::DecodeTaskType task_type,
97 const ImageDecodeCache::TracingInfo& tracing_info) 98 const ImageDecodeCache::TracingInfo& tracing_info)
98 : TileTask(true), 99 : TileTask(true),
99 cache_(cache), 100 cache_(cache),
100 image_key_(image_key), 101 image_key_(image_key),
101 image_(image), 102 image_(image),
103 task_type_(task_type),
102 tracing_info_(tracing_info) {} 104 tracing_info_(tracing_info) {}
103 105
104 // Overridden from Task: 106 // Overridden from Task:
105 void RunOnWorkerThread() override { 107 void RunOnWorkerThread() override {
106 TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", 108 TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode",
107 "software", "source_prepare_tiles_id", 109 "software", "source_prepare_tiles_id",
108 tracing_info_.prepare_tiles_id); 110 tracing_info_.prepare_tiles_id);
109 devtools_instrumentation::ScopedImageDecodeTask image_decode_task( 111 devtools_instrumentation::ScopedImageDecodeTask image_decode_task(
110 image_.image().get(), 112 image_.image().get(),
111 devtools_instrumentation::ScopedImageDecodeTask::SOFTWARE); 113 devtools_instrumentation::ScopedImageDecodeTask::SOFTWARE);
112 cache_->DecodeImage(image_key_, image_); 114 cache_->DecodeImage(image_key_, image_, task_type_);
113 } 115 }
114 116
115 // Overridden from TileTask: 117 // Overridden from TileTask:
116 void OnTaskCompleted() override { cache_->RemovePendingTask(image_key_); } 118 void OnTaskCompleted() override {
119 cache_->RemovePendingTask(image_key_, task_type_);
120 }
117 121
118 protected: 122 protected:
119 ~ImageDecodeTaskImpl() override {} 123 ~ImageDecodeTaskImpl() override {}
120 124
121 private: 125 private:
122 SoftwareImageDecodeCache* cache_; 126 SoftwareImageDecodeCache* cache_;
123 SoftwareImageDecodeCache::ImageKey image_key_; 127 SoftwareImageDecodeCache::ImageKey image_key_;
124 DrawImage image_; 128 DrawImage image_;
129 SoftwareImageDecodeCache::DecodeTaskType task_type_;
125 const ImageDecodeCache::TracingInfo tracing_info_; 130 const ImageDecodeCache::TracingInfo tracing_info_;
126 131
127 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); 132 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
128 }; 133 };
129 134
130 SkSize GetScaleAdjustment(const ImageDecodeCacheKey& key) { 135 SkSize GetScaleAdjustment(const ImageDecodeCacheKey& key) {
131 // If the requested filter quality did not require scale, then the adjustment 136 // If the requested filter quality did not require scale, then the adjustment
132 // is identity. 137 // is identity.
133 if (key.can_use_original_decode() || key.should_use_subrect()) { 138 if (key.can_use_original_decode() || key.should_use_subrect()) {
134 return SkSize::Make(1.f, 1.f); 139 return SkSize::Make(1.f, 1.f);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( 205 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
201 this); 206 this);
202 // Unregister this component with memory_coordinator::ClientRegistry. 207 // Unregister this component with memory_coordinator::ClientRegistry.
203 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this); 208 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this);
204 } 209 }
205 210
206 bool SoftwareImageDecodeCache::GetTaskForImageAndRef( 211 bool SoftwareImageDecodeCache::GetTaskForImageAndRef(
207 const DrawImage& image, 212 const DrawImage& image,
208 const TracingInfo& tracing_info, 213 const TracingInfo& tracing_info,
209 scoped_refptr<TileTask>* task) { 214 scoped_refptr<TileTask>* task) {
215 return GetTaskForImageAndRefInternal(image, tracing_info, USE_IN_RASTER_TASKS,
216 task);
217 }
218
219 bool SoftwareImageDecodeCache::GetOutOfRasterDecodeTaskForImageAndRef(
220 const DrawImage& image,
221 scoped_refptr<TileTask>* task) {
222 return GetTaskForImageAndRefInternal(image, TracingInfo(),
223 USE_OUT_OF_RASTER_TASKS, task);
224 }
225
226 bool SoftwareImageDecodeCache::GetTaskForImageAndRefInternal(
227 const DrawImage& image,
228 const TracingInfo& tracing_info,
229 DecodeTaskType task_type,
230 scoped_refptr<TileTask>* task) {
210 // If the image already exists or if we're going to create a task for it, then 231 // If the image already exists or if we're going to create a task for it, then
211 // we'll likely need to ref this image (the exception is if we're prerolling 232 // we'll likely need to ref this image (the exception is if we're prerolling
212 // the image only). That means the image is or will be in the cache. When the 233 // the image only). That means the image is or will be in the cache. When the
213 // ref goes to 0, it will be unpinned but will remain in the cache. If the 234 // ref goes to 0, it will be unpinned but will remain in the cache. If the
214 // image does not fit into the budget, then we don't ref this image, since it 235 // image does not fit into the budget, then we don't ref this image, since it
215 // will be decoded at raster time which is when it will be temporarily put in 236 // will be decoded at raster time which is when it will be temporarily put in
216 // the cache. 237 // the cache.
217 ImageKey key = ImageKey::FromDrawImage(image); 238 ImageKey key = ImageKey::FromDrawImage(image);
218 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 239 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
219 "SoftwareImageDecodeCache::GetTaskForImageAndRef", "key", 240 "SoftwareImageDecodeCache::GetTaskForImageAndRef", "key",
(...skipping 30 matching lines...) Expand all
250 271
251 // If the image fits in memory, then we at least tried to lock it and 272 // If the image fits in memory, then we at least tried to lock it and
252 // failed. This means that it's not valid anymore. 273 // failed. This means that it's not valid anymore.
253 if (new_image_fits_in_memory) { 274 if (new_image_fits_in_memory) {
254 RecordLockExistingCachedImageHistogram(tracing_info.requesting_tile_bin, 275 RecordLockExistingCachedImageHistogram(tracing_info.requesting_tile_bin,
255 false); 276 false);
256 decoded_images_.Erase(decoded_it); 277 decoded_images_.Erase(decoded_it);
257 } 278 }
258 } 279 }
259 280
260 // If the task exists, return it. 281 DCHECK(task_type == USE_IN_RASTER_TASKS ||
261 scoped_refptr<TileTask>& existing_task = pending_image_tasks_[key]; 282 task_type == USE_OUT_OF_RASTER_TASKS);
283 // If the task exists, return it. Note that if we always need to create a new
284 // task, then just set |existing_task| to reference the passed in task (which
285 // is set to nullptr above).
286 scoped_refptr<TileTask>& existing_task =
287 (task_type == USE_IN_RASTER_TASKS)
288 ? pending_in_raster_image_tasks_[key]
289 : pending_out_of_raster_image_tasks_[key];
262 if (existing_task) { 290 if (existing_task) {
263 RefImage(key); 291 RefImage(key);
264 *task = existing_task; 292 *task = existing_task;
265 SanityCheckState(__LINE__, true); 293 SanityCheckState(__LINE__, true);
266 return true; 294 return true;
267 } 295 }
268 296
269 // At this point, we have to create a new image/task, so we need to abort if 297 // At this point, we have to create a new image/task, so we need to abort if
270 // it doesn't fit into memory and there are currently no raster tasks that 298 // it doesn't fit into memory and there are currently no raster tasks that
271 // would have already accounted for memory. The latter part is possible if 299 // would have already accounted for memory. The latter part is possible if
272 // there's a running raster task that could not be canceled, and still has a 300 // there's a running raster task that could not be canceled, and still has a
273 // ref to the image that is now being reffed for the new schedule. 301 // ref to the image that is now being reffed for the new schedule.
274 if (!new_image_fits_in_memory && (decoded_images_ref_counts_.find(key) == 302 if (!new_image_fits_in_memory && (decoded_images_ref_counts_.find(key) ==
275 decoded_images_ref_counts_.end())) { 303 decoded_images_ref_counts_.end())) {
276 *task = nullptr; 304 *task = nullptr;
277 SanityCheckState(__LINE__, true); 305 SanityCheckState(__LINE__, true);
278 return false; 306 return false;
279 } 307 }
280 308
281 // Actually create the task. RefImage will account for memory on the first 309 // Actually create the task. RefImage will account for memory on the first
282 // ref. 310 // ref.
283 RefImage(key); 311 RefImage(key);
284 existing_task = make_scoped_refptr( 312 existing_task = make_scoped_refptr(
285 new ImageDecodeTaskImpl(this, key, image, tracing_info)); 313 new ImageDecodeTaskImpl(this, key, image, task_type, tracing_info));
286 *task = existing_task; 314 *task = existing_task;
287 SanityCheckState(__LINE__, true); 315 SanityCheckState(__LINE__, true);
288 return true; 316 return true;
289 } 317 }
290 318
291 void SoftwareImageDecodeCache::RefImage(const ImageKey& key) { 319 void SoftwareImageDecodeCache::RefImage(const ImageKey& key) {
292 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 320 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
293 "SoftwareImageDecodeCache::RefImage", "key", key.ToString()); 321 "SoftwareImageDecodeCache::RefImage", "key", key.ToString());
294 lock_.AssertAcquired(); 322 lock_.AssertAcquired();
295 int ref = ++decoded_images_ref_counts_[key]; 323 int ref = ++decoded_images_ref_counts_[key];
(...skipping 30 matching lines...) Expand all
326 SanityCheckState(__LINE__, true); 354 SanityCheckState(__LINE__, true);
327 return; 355 return;
328 } 356 }
329 DCHECK(decoded_image_it->second->is_locked()); 357 DCHECK(decoded_image_it->second->is_locked());
330 decoded_image_it->second->Unlock(); 358 decoded_image_it->second->Unlock();
331 } 359 }
332 SanityCheckState(__LINE__, true); 360 SanityCheckState(__LINE__, true);
333 } 361 }
334 362
335 void SoftwareImageDecodeCache::DecodeImage(const ImageKey& key, 363 void SoftwareImageDecodeCache::DecodeImage(const ImageKey& key,
336 const DrawImage& image) { 364 const DrawImage& image,
365 DecodeTaskType task_type) {
337 TRACE_EVENT1("cc", "SoftwareImageDecodeCache::DecodeImage", "key", 366 TRACE_EVENT1("cc", "SoftwareImageDecodeCache::DecodeImage", "key",
338 key.ToString()); 367 key.ToString());
339 base::AutoLock lock(lock_); 368 base::AutoLock lock(lock_);
340 AutoRemoveKeyFromTaskMap remove_key_from_task_map(&pending_image_tasks_, key); 369 AutoRemoveKeyFromTaskMap remove_key_from_task_map(
370 (task_type == USE_IN_RASTER_TASKS) ? &pending_in_raster_image_tasks_
371 : &pending_out_of_raster_image_tasks_,
372 key);
341 373
342 // We could have finished all of the raster tasks (cancelled) while the task 374 // We could have finished all of the raster tasks (cancelled) while the task
343 // was just starting to run. Since this task already started running, it 375 // was just starting to run. Since this task already started running, it
344 // wasn't cancelled. So, if the ref count for the image is 0 then we can just 376 // wasn't cancelled. So, if the ref count for the image is 0 then we can just
345 // abort. 377 // abort.
346 if (decoded_images_ref_counts_.find(key) == 378 if (decoded_images_ref_counts_.find(key) ==
347 decoded_images_ref_counts_.end()) { 379 decoded_images_ref_counts_.end()) {
348 return; 380 return;
349 } 381 }
350 382
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 if (it->second->is_locked()) { 792 if (it->second->is_locked()) {
761 ++it; 793 ++it;
762 continue; 794 continue;
763 } 795 }
764 796
765 it = decoded_images_.Erase(it); 797 it = decoded_images_.Erase(it);
766 --num_to_remove; 798 --num_to_remove;
767 } 799 }
768 } 800 }
769 801
770 void SoftwareImageDecodeCache::RemovePendingTask(const ImageKey& key) { 802 void SoftwareImageDecodeCache::RemovePendingTask(const ImageKey& key,
803 DecodeTaskType task_type) {
771 base::AutoLock lock(lock_); 804 base::AutoLock lock(lock_);
772 pending_image_tasks_.erase(key); 805 switch (task_type) {
806 case USE_IN_RASTER_TASKS:
807 pending_in_raster_image_tasks_.erase(key);
808 break;
809 case USE_OUT_OF_RASTER_TASKS:
810 pending_out_of_raster_image_tasks_.erase(key);
811 break;
812 }
773 } 813 }
774 814
775 bool SoftwareImageDecodeCache::OnMemoryDump( 815 bool SoftwareImageDecodeCache::OnMemoryDump(
776 const base::trace_event::MemoryDumpArgs& args, 816 const base::trace_event::MemoryDumpArgs& args,
777 base::trace_event::ProcessMemoryDump* pmd) { 817 base::trace_event::ProcessMemoryDump* pmd) {
778 base::AutoLock lock(lock_); 818 base::AutoLock lock(lock_);
779 819
780 if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) { 820 if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) {
781 std::string dump_name = base::StringPrintf( 821 std::string dump_name = base::StringPrintf(
782 "cc/image_memory/cache_0x%" PRIXPTR, reinterpret_cast<uintptr_t>(this)); 822 "cc/image_memory/cache_0x%" PRIXPTR, reinterpret_cast<uintptr_t>(this));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 for (const auto& image_pair : decoded_images_) { 869 for (const auto& image_pair : decoded_images_) {
830 const auto& key = image_pair.first; 870 const auto& key = image_pair.first;
831 const auto& image = image_pair.second; 871 const auto& image = image_pair.second;
832 872
833 auto ref_it = decoded_images_ref_counts_.find(key); 873 auto ref_it = decoded_images_ref_counts_.find(key);
834 if (image->is_locked()) { 874 if (image->is_locked()) {
835 budget.AddUsage(key.locked_bytes()); 875 budget.AddUsage(key.locked_bytes());
836 DCHECK(ref_it != decoded_images_ref_counts_.end()) << line; 876 DCHECK(ref_it != decoded_images_ref_counts_.end()) << line;
837 } else { 877 } else {
838 DCHECK(ref_it == decoded_images_ref_counts_.end() || 878 DCHECK(ref_it == decoded_images_ref_counts_.end() ||
839 pending_image_tasks_.find(key) != pending_image_tasks_.end()) 879 pending_in_raster_image_tasks_.find(key) !=
880 pending_in_raster_image_tasks_.end() ||
881 pending_out_of_raster_image_tasks_.find(key) !=
882 pending_out_of_raster_image_tasks_.end())
840 << line; 883 << line;
841 } 884 }
842 } 885 }
843 DCHECK_GE(budget.AvailableMemoryBytes(), 886 DCHECK_GE(budget.AvailableMemoryBytes(),
844 locked_images_budget_.AvailableMemoryBytes()) 887 locked_images_budget_.AvailableMemoryBytes())
845 << line; 888 << line;
846 #endif // DCHECK_IS_ON() 889 #endif // DCHECK_IS_ON()
847 } 890 }
848 891
849 // SoftwareImageDecodeCacheKey 892 // SoftwareImageDecodeCacheKey
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 break; 1155 break;
1113 case base::MemoryState::UNKNOWN: 1156 case base::MemoryState::UNKNOWN:
1114 NOTREACHED(); 1157 NOTREACHED();
1115 return; 1158 return;
1116 } 1159 }
1117 } 1160 }
1118 ReduceCacheUsage(); 1161 ReduceCacheUsage();
1119 } 1162 }
1120 1163
1121 } // namespace cc 1164 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698