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

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: test fix Created 3 years, 11 months 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
« no previous file with comments | « cc/tiles/software_image_decode_cache.h ('k') | cc/tiles/tile_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( 206 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
202 this); 207 this);
203 // Unregister this component with memory_coordinator::ClientRegistry. 208 // Unregister this component with memory_coordinator::ClientRegistry.
204 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this); 209 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this);
205 } 210 }
206 211
207 bool SoftwareImageDecodeCache::GetTaskForImageAndRef( 212 bool SoftwareImageDecodeCache::GetTaskForImageAndRef(
208 const DrawImage& image, 213 const DrawImage& image,
209 const TracingInfo& tracing_info, 214 const TracingInfo& tracing_info,
210 scoped_refptr<TileTask>* task) { 215 scoped_refptr<TileTask>* task) {
216 return GetTaskForImageAndRefInternal(
217 image, tracing_info, DecodeTaskType::USE_IN_RASTER_TASKS, task);
218 }
219
220 bool SoftwareImageDecodeCache::GetOutOfRasterDecodeTaskForImageAndRef(
221 const DrawImage& image,
222 scoped_refptr<TileTask>* task) {
223 return GetTaskForImageAndRefInternal(
224 image, TracingInfo(), DecodeTaskType::USE_OUT_OF_RASTER_TASKS, task);
225 }
226
227 bool SoftwareImageDecodeCache::GetTaskForImageAndRefInternal(
228 const DrawImage& image,
229 const TracingInfo& tracing_info,
230 DecodeTaskType task_type,
231 scoped_refptr<TileTask>* task) {
211 // If the image already exists or if we're going to create a task for it, then 232 // If the image already exists or if we're going to create a task for it, then
212 // we'll likely need to ref this image (the exception is if we're prerolling 233 // we'll likely need to ref this image (the exception is if we're prerolling
213 // the image only). That means the image is or will be in the cache. When the 234 // the image only). That means the image is or will be in the cache. When the
214 // ref goes to 0, it will be unpinned but will remain in the cache. If the 235 // ref goes to 0, it will be unpinned but will remain in the cache. If the
215 // image does not fit into the budget, then we don't ref this image, since it 236 // image does not fit into the budget, then we don't ref this image, since it
216 // will be decoded at raster time which is when it will be temporarily put in 237 // will be decoded at raster time which is when it will be temporarily put in
217 // the cache. 238 // the cache.
218 ImageKey key = ImageKey::FromDrawImage(image); 239 ImageKey key = ImageKey::FromDrawImage(image);
219 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 240 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
220 "SoftwareImageDecodeCache::GetTaskForImageAndRef", "key", 241 "SoftwareImageDecodeCache::GetTaskForImageAndRef", "key",
(...skipping 30 matching lines...) Expand all
251 272
252 // If the image fits in memory, then we at least tried to lock it and 273 // If the image fits in memory, then we at least tried to lock it and
253 // failed. This means that it's not valid anymore. 274 // failed. This means that it's not valid anymore.
254 if (new_image_fits_in_memory) { 275 if (new_image_fits_in_memory) {
255 RecordLockExistingCachedImageHistogram(tracing_info.requesting_tile_bin, 276 RecordLockExistingCachedImageHistogram(tracing_info.requesting_tile_bin,
256 false); 277 false);
257 decoded_images_.Erase(decoded_it); 278 decoded_images_.Erase(decoded_it);
258 } 279 }
259 } 280 }
260 281
261 // If the task exists, return it. 282 DCHECK(task_type == DecodeTaskType::USE_IN_RASTER_TASKS ||
262 scoped_refptr<TileTask>& existing_task = pending_image_tasks_[key]; 283 task_type == DecodeTaskType::USE_OUT_OF_RASTER_TASKS);
284 // If the task exists, return it. Note that if we always need to create a new
285 // task, then just set |existing_task| to reference the passed in task (which
286 // is set to nullptr above).
287 scoped_refptr<TileTask>& existing_task =
288 (task_type == DecodeTaskType::USE_IN_RASTER_TASKS)
289 ? pending_in_raster_image_tasks_[key]
290 : pending_out_of_raster_image_tasks_[key];
263 if (existing_task) { 291 if (existing_task) {
264 RefImage(key); 292 RefImage(key);
265 *task = existing_task; 293 *task = existing_task;
266 SanityCheckState(__LINE__, true); 294 SanityCheckState(__LINE__, true);
267 return true; 295 return true;
268 } 296 }
269 297
270 // At this point, we have to create a new image/task, so we need to abort if 298 // At this point, we have to create a new image/task, so we need to abort if
271 // it doesn't fit into memory and there are currently no raster tasks that 299 // it doesn't fit into memory and there are currently no raster tasks that
272 // would have already accounted for memory. The latter part is possible if 300 // would have already accounted for memory. The latter part is possible if
273 // there's a running raster task that could not be canceled, and still has a 301 // there's a running raster task that could not be canceled, and still has a
274 // ref to the image that is now being reffed for the new schedule. 302 // ref to the image that is now being reffed for the new schedule.
275 if (!new_image_fits_in_memory && (decoded_images_ref_counts_.find(key) == 303 if (!new_image_fits_in_memory && (decoded_images_ref_counts_.find(key) ==
276 decoded_images_ref_counts_.end())) { 304 decoded_images_ref_counts_.end())) {
277 *task = nullptr; 305 *task = nullptr;
278 SanityCheckState(__LINE__, true); 306 SanityCheckState(__LINE__, true);
279 return false; 307 return false;
280 } 308 }
281 309
282 // Actually create the task. RefImage will account for memory on the first 310 // Actually create the task. RefImage will account for memory on the first
283 // ref. 311 // ref.
284 RefImage(key); 312 RefImage(key);
285 existing_task = make_scoped_refptr( 313 existing_task = make_scoped_refptr(
286 new ImageDecodeTaskImpl(this, key, image, tracing_info)); 314 new ImageDecodeTaskImpl(this, key, image, task_type, tracing_info));
287 *task = existing_task; 315 *task = existing_task;
288 SanityCheckState(__LINE__, true); 316 SanityCheckState(__LINE__, true);
289 return true; 317 return true;
290 } 318 }
291 319
292 void SoftwareImageDecodeCache::RefImage(const ImageKey& key) { 320 void SoftwareImageDecodeCache::RefImage(const ImageKey& key) {
293 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 321 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
294 "SoftwareImageDecodeCache::RefImage", "key", key.ToString()); 322 "SoftwareImageDecodeCache::RefImage", "key", key.ToString());
295 lock_.AssertAcquired(); 323 lock_.AssertAcquired();
296 int ref = ++decoded_images_ref_counts_[key]; 324 int ref = ++decoded_images_ref_counts_[key];
(...skipping 30 matching lines...) Expand all
327 SanityCheckState(__LINE__, true); 355 SanityCheckState(__LINE__, true);
328 return; 356 return;
329 } 357 }
330 DCHECK(decoded_image_it->second->is_locked()); 358 DCHECK(decoded_image_it->second->is_locked());
331 decoded_image_it->second->Unlock(); 359 decoded_image_it->second->Unlock();
332 } 360 }
333 SanityCheckState(__LINE__, true); 361 SanityCheckState(__LINE__, true);
334 } 362 }
335 363
336 void SoftwareImageDecodeCache::DecodeImage(const ImageKey& key, 364 void SoftwareImageDecodeCache::DecodeImage(const ImageKey& key,
337 const DrawImage& image) { 365 const DrawImage& image,
366 DecodeTaskType task_type) {
338 TRACE_EVENT1("cc", "SoftwareImageDecodeCache::DecodeImage", "key", 367 TRACE_EVENT1("cc", "SoftwareImageDecodeCache::DecodeImage", "key",
339 key.ToString()); 368 key.ToString());
340 base::AutoLock lock(lock_); 369 base::AutoLock lock(lock_);
341 AutoRemoveKeyFromTaskMap remove_key_from_task_map(&pending_image_tasks_, key); 370 AutoRemoveKeyFromTaskMap remove_key_from_task_map(
371 (task_type == DecodeTaskType::USE_IN_RASTER_TASKS)
372 ? &pending_in_raster_image_tasks_
373 : &pending_out_of_raster_image_tasks_,
374 key);
342 375
343 // We could have finished all of the raster tasks (cancelled) while the task 376 // We could have finished all of the raster tasks (cancelled) while the task
344 // was just starting to run. Since this task already started running, it 377 // was just starting to run. Since this task already started running, it
345 // wasn't cancelled. So, if the ref count for the image is 0 then we can just 378 // wasn't cancelled. So, if the ref count for the image is 0 then we can just
346 // abort. 379 // abort.
347 if (decoded_images_ref_counts_.find(key) == 380 if (decoded_images_ref_counts_.find(key) ==
348 decoded_images_ref_counts_.end()) { 381 decoded_images_ref_counts_.end()) {
349 return; 382 return;
350 } 383 }
351 384
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 if (it->second->is_locked()) { 794 if (it->second->is_locked()) {
762 ++it; 795 ++it;
763 continue; 796 continue;
764 } 797 }
765 798
766 it = decoded_images_.Erase(it); 799 it = decoded_images_.Erase(it);
767 --num_to_remove; 800 --num_to_remove;
768 } 801 }
769 } 802 }
770 803
771 void SoftwareImageDecodeCache::RemovePendingTask(const ImageKey& key) { 804 void SoftwareImageDecodeCache::RemovePendingTask(const ImageKey& key,
805 DecodeTaskType task_type) {
772 base::AutoLock lock(lock_); 806 base::AutoLock lock(lock_);
773 pending_image_tasks_.erase(key); 807 switch (task_type) {
808 case DecodeTaskType::USE_IN_RASTER_TASKS:
809 pending_in_raster_image_tasks_.erase(key);
810 break;
811 case DecodeTaskType::USE_OUT_OF_RASTER_TASKS:
812 pending_out_of_raster_image_tasks_.erase(key);
813 break;
814 }
774 } 815 }
775 816
776 bool SoftwareImageDecodeCache::OnMemoryDump( 817 bool SoftwareImageDecodeCache::OnMemoryDump(
777 const base::trace_event::MemoryDumpArgs& args, 818 const base::trace_event::MemoryDumpArgs& args,
778 base::trace_event::ProcessMemoryDump* pmd) { 819 base::trace_event::ProcessMemoryDump* pmd) {
779 base::AutoLock lock(lock_); 820 base::AutoLock lock(lock_);
780 821
781 if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) { 822 if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) {
782 std::string dump_name = base::StringPrintf( 823 std::string dump_name = base::StringPrintf(
783 "cc/image_memory/cache_0x%" PRIXPTR, reinterpret_cast<uintptr_t>(this)); 824 "cc/image_memory/cache_0x%" PRIXPTR, reinterpret_cast<uintptr_t>(this));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 for (const auto& image_pair : decoded_images_) { 871 for (const auto& image_pair : decoded_images_) {
831 const auto& key = image_pair.first; 872 const auto& key = image_pair.first;
832 const auto& image = image_pair.second; 873 const auto& image = image_pair.second;
833 874
834 auto ref_it = decoded_images_ref_counts_.find(key); 875 auto ref_it = decoded_images_ref_counts_.find(key);
835 if (image->is_locked()) { 876 if (image->is_locked()) {
836 budget.AddUsage(key.locked_bytes()); 877 budget.AddUsage(key.locked_bytes());
837 DCHECK(ref_it != decoded_images_ref_counts_.end()) << line; 878 DCHECK(ref_it != decoded_images_ref_counts_.end()) << line;
838 } else { 879 } else {
839 DCHECK(ref_it == decoded_images_ref_counts_.end() || 880 DCHECK(ref_it == decoded_images_ref_counts_.end() ||
840 pending_image_tasks_.find(key) != pending_image_tasks_.end()) 881 pending_in_raster_image_tasks_.find(key) !=
882 pending_in_raster_image_tasks_.end() ||
883 pending_out_of_raster_image_tasks_.find(key) !=
884 pending_out_of_raster_image_tasks_.end())
841 << line; 885 << line;
842 } 886 }
843 } 887 }
844 DCHECK_GE(budget.AvailableMemoryBytes(), 888 DCHECK_GE(budget.AvailableMemoryBytes(),
845 locked_images_budget_.AvailableMemoryBytes()) 889 locked_images_budget_.AvailableMemoryBytes())
846 << line; 890 << line;
847 #endif // DCHECK_IS_ON() 891 #endif // DCHECK_IS_ON()
848 } 892 }
849 893
850 // SoftwareImageDecodeCacheKey 894 // SoftwareImageDecodeCacheKey
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 break; 1157 break;
1114 case base::MemoryState::UNKNOWN: 1158 case base::MemoryState::UNKNOWN:
1115 NOTREACHED(); 1159 NOTREACHED();
1116 return; 1160 return;
1117 } 1161 }
1118 } 1162 }
1119 ReduceCacheUsage(); 1163 ReduceCacheUsage();
1120 } 1164 }
1121 1165
1122 } // namespace cc 1166 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tiles/software_image_decode_cache.h ('k') | cc/tiles/tile_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698