OLD | NEW |
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/image_decode_controller.h" | 5 #include "cc/tiles/image_decode_controller.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/memory/discardable_memory.h" | 10 #include "base/memory/discardable_memory.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 uint64_t prepare_tiles_id, | 101 uint64_t prepare_tiles_id, |
102 scoped_refptr<ImageDecodeTask>* task) { | 102 scoped_refptr<ImageDecodeTask>* task) { |
103 // If the image already exists or if we're going to create a task for it, then | 103 // If the image already exists or if we're going to create a task for it, then |
104 // we'll likely need to ref this image (the exception is if we're prerolling | 104 // we'll likely need to ref this image (the exception is if we're prerolling |
105 // the image only). That means the image is or will be in the cache. When the | 105 // the image only). That means the image is or will be in the cache. When the |
106 // ref goes to 0, it will be unpinned but will remain in the cache. If the | 106 // ref goes to 0, it will be unpinned but will remain in the cache. If the |
107 // image does not fit into the budget, then we don't ref this image, since it | 107 // image does not fit into the budget, then we don't ref this image, since it |
108 // will be decoded at raster time which is when it will be temporarily put in | 108 // will be decoded at raster time which is when it will be temporarily put in |
109 // the cache. | 109 // the cache. |
110 ImageKey key = ImageKey::FromDrawImage(image); | 110 ImageKey key = ImageKey::FromDrawImage(image); |
111 TRACE_EVENT1("cc", "ImageDecodeController::GetTaskForImageAndRef", "key", | 111 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 112 "ImageDecodeController::GetTaskForImageAndRef", "key", |
112 key.ToString()); | 113 key.ToString()); |
113 // If we're not going to do a scale, we will just create a task to preroll the | 114 // If we're not going to do a scale, we will just create a task to preroll the |
114 // image the first time we see it. This doesn't need to account for memory. | 115 // image the first time we see it. This doesn't need to account for memory. |
115 // TODO(vmpstr): We can also lock the original sized image, in which case it | 116 // TODO(vmpstr): We can also lock the original sized image, in which case it |
116 // does require memory bookkeeping. | 117 // does require memory bookkeeping. |
117 if (!CanHandleImage(key, image)) { | 118 if (!CanHandleImage(key, image)) { |
118 base::AutoLock lock(lock_); | 119 base::AutoLock lock(lock_); |
119 if (prerolled_images_.count(key.image_id()) == 0) { | 120 if (prerolled_images_.count(key.image_id()) == 0) { |
120 scoped_refptr<ImageDecodeTask>& existing_task = pending_image_tasks_[key]; | 121 scoped_refptr<ImageDecodeTask>& existing_task = pending_image_tasks_[key]; |
121 if (!existing_task) { | 122 if (!existing_task) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 // ref. | 175 // ref. |
175 RefImage(key); | 176 RefImage(key); |
176 existing_task = make_scoped_refptr( | 177 existing_task = make_scoped_refptr( |
177 new ImageDecodeTaskImpl(this, key, image, prepare_tiles_id)); | 178 new ImageDecodeTaskImpl(this, key, image, prepare_tiles_id)); |
178 *task = existing_task; | 179 *task = existing_task; |
179 SanityCheckState(__LINE__, true); | 180 SanityCheckState(__LINE__, true); |
180 return true; | 181 return true; |
181 } | 182 } |
182 | 183 |
183 void ImageDecodeController::RefImage(const ImageKey& key) { | 184 void ImageDecodeController::RefImage(const ImageKey& key) { |
184 TRACE_EVENT1("cc", "ImageDecodeController::RefImage", "key", key.ToString()); | 185 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 186 "ImageDecodeController::RefImage", "key", key.ToString()); |
185 lock_.AssertAcquired(); | 187 lock_.AssertAcquired(); |
186 int ref = ++decoded_images_ref_counts_[key]; | 188 int ref = ++decoded_images_ref_counts_[key]; |
187 if (ref == 1) { | 189 if (ref == 1) { |
188 DCHECK_GE(locked_images_budget_.AvailableMemoryBytes(), key.target_bytes()); | 190 DCHECK_GE(locked_images_budget_.AvailableMemoryBytes(), key.target_bytes()); |
189 locked_images_budget_.AddUsage(key.target_bytes()); | 191 locked_images_budget_.AddUsage(key.target_bytes()); |
190 } | 192 } |
191 } | 193 } |
192 | 194 |
193 void ImageDecodeController::UnrefImage(const DrawImage& image) { | 195 void ImageDecodeController::UnrefImage(const DrawImage& image) { |
194 // When we unref the image, there are several situations we need to consider: | 196 // When we unref the image, there are several situations we need to consider: |
195 // 1. The ref did not reach 0, which means we have to keep the image locked. | 197 // 1. The ref did not reach 0, which means we have to keep the image locked. |
196 // 2. The ref reached 0, we should unlock it. | 198 // 2. The ref reached 0, we should unlock it. |
197 // 2a. The image isn't in the locked cache because we didn't get to decode | 199 // 2a. The image isn't in the locked cache because we didn't get to decode |
198 // it yet. | 200 // it yet. |
199 // 2b. Unlock the image but keep it in list. | 201 // 2b. Unlock the image but keep it in list. |
200 const ImageKey& key = ImageKey::FromDrawImage(image); | 202 const ImageKey& key = ImageKey::FromDrawImage(image); |
201 DCHECK(CanHandleImage(key, image)); | 203 DCHECK(CanHandleImage(key, image)); |
202 TRACE_EVENT1("cc", "ImageDecodeController::UnrefImage", "key", | 204 TRACE_EVENT1("disabled-by-default-cc.debug", |
203 key.ToString()); | 205 "ImageDecodeController::UnrefImage", "key", key.ToString()); |
204 | 206 |
205 base::AutoLock lock(lock_); | 207 base::AutoLock lock(lock_); |
206 auto ref_count_it = decoded_images_ref_counts_.find(key); | 208 auto ref_count_it = decoded_images_ref_counts_.find(key); |
207 DCHECK(ref_count_it != decoded_images_ref_counts_.end()); | 209 DCHECK(ref_count_it != decoded_images_ref_counts_.end()); |
208 | 210 |
209 --ref_count_it->second; | 211 --ref_count_it->second; |
210 if (ref_count_it->second == 0) { | 212 if (ref_count_it->second == 0) { |
211 decoded_images_ref_counts_.erase(ref_count_it); | 213 decoded_images_ref_counts_.erase(ref_count_it); |
212 locked_images_budget_.SubtractUsage(key.target_bytes()); | 214 locked_images_budget_.SubtractUsage(key.target_bytes()); |
213 | 215 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 } | 286 } |
285 decoded_images_.erase(image_it); | 287 decoded_images_.erase(image_it); |
286 } | 288 } |
287 decoded_images_.push_back(AnnotatedDecodedImage(key, decoded_image)); | 289 decoded_images_.push_back(AnnotatedDecodedImage(key, decoded_image)); |
288 SanityCheckState(__LINE__, true); | 290 SanityCheckState(__LINE__, true); |
289 } | 291 } |
290 | 292 |
291 scoped_refptr<ImageDecodeController::DecodedImage> | 293 scoped_refptr<ImageDecodeController::DecodedImage> |
292 ImageDecodeController::DecodeImageInternal(const ImageKey& key, | 294 ImageDecodeController::DecodeImageInternal(const ImageKey& key, |
293 const SkImage* image) { | 295 const SkImage* image) { |
294 TRACE_EVENT1("cc", "ImageDecodeController::DecodeImageInternal", "key", | 296 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 297 "ImageDecodeController::DecodeImageInternal", "key", |
295 key.ToString()); | 298 key.ToString()); |
296 | 299 |
297 // Get the decoded image first (at the original scale). | 300 // Get the decoded image first (at the original scale). |
298 SkImageInfo decoded_info = SkImageInfo::MakeN32Premul( | 301 SkImageInfo decoded_info = SkImageInfo::MakeN32Premul( |
299 key.src_rect().width(), key.src_rect().height()); | 302 key.src_rect().width(), key.src_rect().height()); |
300 scoped_ptr<uint8_t[]> decoded_pixels; | 303 scoped_ptr<uint8_t[]> decoded_pixels; |
301 { | 304 { |
302 TRACE_EVENT0( | 305 TRACE_EVENT0( |
303 "cc", | 306 "disabled-by-default-cc.debug", |
304 "ImageDecodeController::DecodeImageInternal - allocate decoded pixels"); | 307 "ImageDecodeController::DecodeImageInternal - allocate decoded pixels"); |
305 decoded_pixels.reset( | 308 decoded_pixels.reset( |
306 new uint8_t[decoded_info.minRowBytes() * decoded_info.height()]); | 309 new uint8_t[decoded_info.minRowBytes() * decoded_info.height()]); |
307 } | 310 } |
308 { | 311 { |
309 TRACE_EVENT0("cc", | 312 TRACE_EVENT0("disabled-by-default-cc.debug", |
310 "ImageDecodeController::DecodeImageInternal - read pixels"); | 313 "ImageDecodeController::DecodeImageInternal - read pixels"); |
311 bool result = image->readPixels( | 314 bool result = image->readPixels( |
312 decoded_info, decoded_pixels.get(), decoded_info.minRowBytes(), | 315 decoded_info, decoded_pixels.get(), decoded_info.minRowBytes(), |
313 key.src_rect().x(), key.src_rect().y(), SkImage::kAllow_CachingHint); | 316 key.src_rect().x(), key.src_rect().y(), SkImage::kAllow_CachingHint); |
314 DCHECK(result); | 317 DCHECK(result); |
315 } | 318 } |
316 | 319 |
317 SkPixmap decoded_pixmap(decoded_info, decoded_pixels.get(), | 320 SkPixmap decoded_pixmap(decoded_info, decoded_pixels.get(), |
318 decoded_info.minRowBytes()); | 321 decoded_info.minRowBytes()); |
319 | 322 |
320 // Now scale the pixels into the destination size. | 323 // Now scale the pixels into the destination size. |
321 SkImageInfo scaled_info = SkImageInfo::MakeN32Premul( | 324 SkImageInfo scaled_info = SkImageInfo::MakeN32Premul( |
322 key.target_size().width(), key.target_size().height()); | 325 key.target_size().width(), key.target_size().height()); |
323 scoped_ptr<base::DiscardableMemory> scaled_pixels; | 326 scoped_ptr<base::DiscardableMemory> scaled_pixels; |
324 { | 327 { |
325 TRACE_EVENT0( | 328 TRACE_EVENT0( |
326 "cc", | 329 "disabled-by-default-cc.debug", |
327 "ImageDecodeController::DecodeImageInternal - allocate scaled pixels"); | 330 "ImageDecodeController::DecodeImageInternal - allocate scaled pixels"); |
328 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() | 331 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() |
329 ->AllocateLockedDiscardableMemory( | 332 ->AllocateLockedDiscardableMemory( |
330 scaled_info.minRowBytes() * scaled_info.height()); | 333 scaled_info.minRowBytes() * scaled_info.height()); |
331 } | 334 } |
332 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), | 335 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), |
333 scaled_info.minRowBytes()); | 336 scaled_info.minRowBytes()); |
334 // TODO(vmpstr): Start handling more than just high filter quality. | 337 // TODO(vmpstr): Start handling more than just high filter quality. |
335 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality()); | 338 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality()); |
336 { | 339 { |
337 TRACE_EVENT0("cc", | 340 TRACE_EVENT0("disabled-by-default-cc.debug", |
338 "ImageDecodeController::DecodeImageInternal - scale pixels"); | 341 "ImageDecodeController::DecodeImageInternal - scale pixels"); |
339 bool result = | 342 bool result = |
340 decoded_pixmap.scalePixels(scaled_pixmap, kHigh_SkFilterQuality); | 343 decoded_pixmap.scalePixels(scaled_pixmap, kHigh_SkFilterQuality); |
341 DCHECK(result); | 344 DCHECK(result); |
342 } | 345 } |
343 return make_scoped_refptr( | 346 return make_scoped_refptr( |
344 new DecodedImage(scaled_info, std::move(scaled_pixels), | 347 new DecodedImage(scaled_info, std::move(scaled_pixels), |
345 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()))); | 348 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()))); |
346 } | 349 } |
347 | 350 |
348 DecodedDrawImage ImageDecodeController::GetDecodedImageForDraw( | 351 DecodedDrawImage ImageDecodeController::GetDecodedImageForDraw( |
349 const DrawImage& draw_image) { | 352 const DrawImage& draw_image) { |
350 ImageKey key = ImageKey::FromDrawImage(draw_image); | 353 ImageKey key = ImageKey::FromDrawImage(draw_image); |
351 TRACE_EVENT1("cc", "ImageDecodeController::GetDecodedImageAndRef", "key", | 354 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 355 "ImageDecodeController::GetDecodedImageAndRef", "key", |
352 key.ToString()); | 356 key.ToString()); |
353 if (!CanHandleImage(key, draw_image)) | 357 if (!CanHandleImage(key, draw_image)) |
354 return DecodedDrawImage(draw_image.image(), draw_image.filter_quality()); | 358 return DecodedDrawImage(draw_image.image(), draw_image.filter_quality()); |
355 | 359 |
356 base::AutoLock lock(lock_); | 360 base::AutoLock lock(lock_); |
357 auto decoded_images_it = FindImage(&decoded_images_, key); | 361 auto decoded_images_it = FindImage(&decoded_images_, key); |
358 // If we found the image and it's locked, then return it. If it's not locked, | 362 // If we found the image and it's locked, then return it. If it's not locked, |
359 // erase it from the cache since it might be put into the at-raster cache. | 363 // erase it from the cache since it might be put into the at-raster cache. |
360 scoped_refptr<DecodedImage> decoded_image; | 364 scoped_refptr<DecodedImage> decoded_image; |
361 if (decoded_images_it != decoded_images_.end()) { | 365 if (decoded_images_it != decoded_images_.end()) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 auto decoded_draw_image = | 433 auto decoded_draw_image = |
430 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(), | 434 DecodedDrawImage(decoded_image->image(), decoded_image->src_rect_offset(), |
431 GetScaleAdjustment(key), kLow_SkFilterQuality); | 435 GetScaleAdjustment(key), kLow_SkFilterQuality); |
432 decoded_draw_image.set_at_raster_decode(true); | 436 decoded_draw_image.set_at_raster_decode(true); |
433 return decoded_draw_image; | 437 return decoded_draw_image; |
434 } | 438 } |
435 | 439 |
436 void ImageDecodeController::DrawWithImageFinished( | 440 void ImageDecodeController::DrawWithImageFinished( |
437 const DrawImage& image, | 441 const DrawImage& image, |
438 const DecodedDrawImage& decoded_image) { | 442 const DecodedDrawImage& decoded_image) { |
439 TRACE_EVENT1("cc", "ImageDecodeController::DrawWithImageFinished", "key", | 443 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 444 "ImageDecodeController::DrawWithImageFinished", "key", |
440 ImageKey::FromDrawImage(image).ToString()); | 445 ImageKey::FromDrawImage(image).ToString()); |
441 ImageKey key = ImageKey::FromDrawImage(image); | 446 ImageKey key = ImageKey::FromDrawImage(image); |
442 if (!CanHandleImage(key, image)) | 447 if (!CanHandleImage(key, image)) |
443 return; | 448 return; |
444 | 449 |
445 if (decoded_image.is_at_raster_decode()) | 450 if (decoded_image.is_at_raster_decode()) |
446 UnrefAtRasterImage(key); | 451 UnrefAtRasterImage(key); |
447 else | 452 else |
448 UnrefImage(image); | 453 UnrefImage(image); |
449 SanityCheckState(__LINE__, false); | 454 SanityCheckState(__LINE__, false); |
450 } | 455 } |
451 | 456 |
452 void ImageDecodeController::RefAtRasterImage(const ImageKey& key) { | 457 void ImageDecodeController::RefAtRasterImage(const ImageKey& key) { |
453 TRACE_EVENT1("cc", "ImageDecodeController::RefAtRasterImage", "key", | 458 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 459 "ImageDecodeController::RefAtRasterImage", "key", |
454 key.ToString()); | 460 key.ToString()); |
455 DCHECK(FindImage(&at_raster_decoded_images_, key) != | 461 DCHECK(FindImage(&at_raster_decoded_images_, key) != |
456 at_raster_decoded_images_.end()); | 462 at_raster_decoded_images_.end()); |
457 ++at_raster_decoded_images_ref_counts_[key]; | 463 ++at_raster_decoded_images_ref_counts_[key]; |
458 } | 464 } |
459 | 465 |
460 void ImageDecodeController::UnrefAtRasterImage(const ImageKey& key) { | 466 void ImageDecodeController::UnrefAtRasterImage(const ImageKey& key) { |
461 TRACE_EVENT1("cc", "ImageDecodeController::UnrefAtRasterImage", "key", | 467 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 468 "ImageDecodeController::UnrefAtRasterImage", "key", |
462 key.ToString()); | 469 key.ToString()); |
463 base::AutoLock lock(lock_); | 470 base::AutoLock lock(lock_); |
464 | 471 |
465 auto ref_it = at_raster_decoded_images_ref_counts_.find(key); | 472 auto ref_it = at_raster_decoded_images_ref_counts_.find(key); |
466 DCHECK(ref_it != at_raster_decoded_images_ref_counts_.end()); | 473 DCHECK(ref_it != at_raster_decoded_images_ref_counts_.end()); |
467 --ref_it->second; | 474 --ref_it->second; |
468 if (ref_it->second == 0) { | 475 if (ref_it->second == 0) { |
469 at_raster_decoded_images_ref_counts_.erase(ref_it); | 476 at_raster_decoded_images_ref_counts_.erase(ref_it); |
470 auto at_raster_image_it = FindImage(&at_raster_decoded_images_, key); | 477 auto at_raster_image_it = FindImage(&at_raster_decoded_images_, key); |
471 DCHECK(at_raster_image_it != at_raster_decoded_images_.end()); | 478 DCHECK(at_raster_image_it != at_raster_decoded_images_.end()); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 | 736 |
730 void ImageDecodeController::MemoryBudget::ResetUsage() { | 737 void ImageDecodeController::MemoryBudget::ResetUsage() { |
731 current_usage_bytes_ = 0; | 738 current_usage_bytes_ = 0; |
732 } | 739 } |
733 | 740 |
734 size_t ImageDecodeController::MemoryBudget::GetCurrentUsageSafe() const { | 741 size_t ImageDecodeController::MemoryBudget::GetCurrentUsageSafe() const { |
735 return current_usage_bytes_.ValueOrDie(); | 742 return current_usage_bytes_.ValueOrDie(); |
736 } | 743 } |
737 | 744 |
738 } // namespace cc | 745 } // namespace cc |
OLD | NEW |