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

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

Issue 1839833003: Add medium image quality to software predecode. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changing an error check to a DCHECK. Updating unit tests (including adding a new one) to reflect th… Created 4 years, 7 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
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_controller.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm>
9 #include <functional> 10 #include <functional>
10 11
11 #include "base/format_macros.h" 12 #include "base/format_macros.h"
12 #include "base/macros.h" 13 #include "base/macros.h"
13 #include "base/memory/discardable_memory.h" 14 #include "base/memory/discardable_memory.h"
14 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
15 #include "base/metrics/histogram_macros.h" 16 #include "base/metrics/histogram_macros.h"
16 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
17 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
18 #include "base/trace_event/memory_dump_manager.h" 19 #include "base/trace_event/memory_dump_manager.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 90
90 private: 91 private:
91 SoftwareImageDecodeController* controller_; 92 SoftwareImageDecodeController* controller_;
92 SoftwareImageDecodeController::ImageKey image_key_; 93 SoftwareImageDecodeController::ImageKey image_key_;
93 DrawImage image_; 94 DrawImage image_;
94 const ImageDecodeController::TracingInfo tracing_info_; 95 const ImageDecodeController::TracingInfo tracing_info_;
95 96
96 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); 97 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
97 }; 98 };
98 99
100 // Most images are scaled from the source image's size to the target size.
101 // But in the case of mipmaps, we are scaling from the mip level which is
102 // larger than we need.
103 // This function gets the scale of the mip level which will be used.
104 SkSize GetMipMapScaleAdjustment(const gfx::Size& src_size,
105 const gfx::Size& target_size) {
106 int src_height = src_size.height();
107 int src_width = src_size.width();
108 int target_height = target_size.height();
109 int target_width = target_size.width();
vmpstr 2016/05/02 19:58:26 nit: you can early out if target_width or target_h
cblume 2016/05/02 23:04:09 I had tried this but still needed a final return,
110
111 int next_mip_height = src_height;
112 int next_mip_width = src_width;
113 for (int current_mip_level = 0;; current_mip_level++) {
114 int mip_height = next_mip_height;
115 int mip_width = next_mip_width;
116
117 next_mip_height = std::max(1, src_height / (1 << (current_mip_level + 1)));
118 next_mip_width = std::max(1, src_width / (1 << (current_mip_level + 1)));
119
120 // Check if an axis on the next mip level would be smaller than the target.
121 // If so, use the current mip level.
122 // This effectively always uses the larger image and always scales down.
123 if (next_mip_height < target_height || next_mip_width < target_width) {
124 SkScalar y_scale = static_cast<float>(mip_height) / src_height;
125 SkScalar x_scale = static_cast<float>(mip_width) / src_width;
126
127 return SkSize::Make(x_scale, y_scale);
128 }
129
130 if (mip_height == 1 && mip_width == 1) {
131 // We have reached the final mip level
132 if (target_height == 1 && target_width == 1) {
vmpstr 2016/05/02 19:58:26 This is kind of meh... Do you still need this if y
cblume 2016/05/02 23:04:09 This is for the final mip level case (say 1x1), no
133 SkScalar y_scale = static_cast<float>(mip_height) / src_height;
134 SkScalar x_scale = static_cast<float>(mip_width) / src_width;
135
136 return SkSize::Make(x_scale, y_scale);
137 }
138
139 break;
140 }
141 }
142
143 return SkSize::Make(-1.f, -1.f);
144 }
145
99 SkSize GetScaleAdjustment(const ImageDecodeControllerKey& key) { 146 SkSize GetScaleAdjustment(const ImageDecodeControllerKey& key) {
100 // If the requested filter quality did not require scale, then the adjustment 147 // If the requested filter quality did not require scale, then the adjustment
101 // is identity. 148 // is identity.
102 if (key.can_use_original_decode()) 149 if (key.can_use_original_decode()) {
103 return SkSize::Make(1.f, 1.f); 150 return SkSize::Make(1.f, 1.f);
104 151 } else if (key.filter_quality() == kMedium_SkFilterQuality) {
105 float x_scale = 152 return GetMipMapScaleAdjustment(key.src_rect().size(), key.target_size());
106 key.target_size().width() / static_cast<float>(key.src_rect().width()); 153 } else {
107 float y_scale = 154 float x_scale =
108 key.target_size().height() / static_cast<float>(key.src_rect().height()); 155 key.target_size().width() / static_cast<float>(key.src_rect().width());
109 return SkSize::Make(x_scale, y_scale); 156 float y_scale = key.target_size().height() /
157 static_cast<float>(key.src_rect().height());
158 return SkSize::Make(x_scale, y_scale);
159 }
110 } 160 }
111 161
112 SkFilterQuality GetDecodedFilterQuality(const ImageDecodeControllerKey& key) { 162 SkFilterQuality GetDecodedFilterQuality(const ImageDecodeControllerKey& key) {
113 return std::min(key.filter_quality(), kLow_SkFilterQuality); 163 return std::min(key.filter_quality(), kLow_SkFilterQuality);
114 } 164 }
115 165
116 SkImageInfo CreateImageInfo(size_t width, 166 SkImageInfo CreateImageInfo(size_t width,
117 size_t height, 167 size_t height,
118 ResourceFormat format) { 168 ResourceFormat format) {
119 return SkImageInfo::Make(width, height, 169 return SkImageInfo::Make(width, height,
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 "SoftwareImageDecodeController::GetTaskForImageAndRef", "key", 231 "SoftwareImageDecodeController::GetTaskForImageAndRef", "key",
182 key.ToString()); 232 key.ToString());
183 233
184 // If the target size is empty, we can skip this image during draw (and thus 234 // If the target size is empty, we can skip this image during draw (and thus
185 // we don't need to decode it or ref it). 235 // we don't need to decode it or ref it).
186 if (key.target_size().IsEmpty()) { 236 if (key.target_size().IsEmpty()) {
187 *task = nullptr; 237 *task = nullptr;
188 return false; 238 return false;
189 } 239 }
190 240
191 // If we're not going to do a scale, we will just create a task to preroll the
192 // image the first time we see it. This doesn't need to account for memory.
193 // TODO(vmpstr): We can also lock the original sized image, in which case it
194 // does require memory bookkeeping.
195 if (!CanHandleImage(key)) {
196 base::AutoLock lock(lock_);
197 if (prerolled_images_.count(key.image_id()) == 0) {
198 scoped_refptr<TileTask>& existing_task = pending_image_tasks_[key];
199 if (!existing_task) {
200 existing_task = make_scoped_refptr(
201 new ImageDecodeTaskImpl(this, key, image, tracing_info));
202 }
203 *task = existing_task;
204 } else {
205 *task = nullptr;
206 }
207 return false;
208 }
209
210 base::AutoLock lock(lock_); 241 base::AutoLock lock(lock_);
211 242
212 // If we already have the image in cache, then we can return it. 243 // If we already have the image in cache, then we can return it.
213 auto decoded_it = decoded_images_.Get(key); 244 auto decoded_it = decoded_images_.Get(key);
214 bool new_image_fits_in_memory = 245 bool new_image_fits_in_memory =
215 locked_images_budget_.AvailableMemoryBytes() >= key.locked_bytes(); 246 locked_images_budget_.AvailableMemoryBytes() >= key.locked_bytes();
216 if (decoded_it != decoded_images_.end()) { 247 if (decoded_it != decoded_images_.end()) {
217 bool image_was_locked = decoded_it->second->is_locked(); 248 bool image_was_locked = decoded_it->second->is_locked();
218 if (image_was_locked || 249 if (image_was_locked ||
219 (new_image_fits_in_memory && decoded_it->second->Lock())) { 250 (new_image_fits_in_memory && decoded_it->second->Lock())) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 } 313 }
283 314
284 void SoftwareImageDecodeController::UnrefImage(const DrawImage& image) { 315 void SoftwareImageDecodeController::UnrefImage(const DrawImage& image) {
285 // When we unref the image, there are several situations we need to consider: 316 // When we unref the image, there are several situations we need to consider:
286 // 1. The ref did not reach 0, which means we have to keep the image locked. 317 // 1. The ref did not reach 0, which means we have to keep the image locked.
287 // 2. The ref reached 0, we should unlock it. 318 // 2. The ref reached 0, we should unlock it.
288 // 2a. The image isn't in the locked cache because we didn't get to decode 319 // 2a. The image isn't in the locked cache because we didn't get to decode
289 // it yet (or failed to decode it). 320 // it yet (or failed to decode it).
290 // 2b. Unlock the image but keep it in list. 321 // 2b. Unlock the image but keep it in list.
291 const ImageKey& key = ImageKey::FromDrawImage(image); 322 const ImageKey& key = ImageKey::FromDrawImage(image);
292 DCHECK(CanHandleImage(key)) << key.ToString();
293 TRACE_EVENT1("disabled-by-default-cc.debug", 323 TRACE_EVENT1("disabled-by-default-cc.debug",
294 "SoftwareImageDecodeController::UnrefImage", "key", 324 "SoftwareImageDecodeController::UnrefImage", "key",
295 key.ToString()); 325 key.ToString());
296 326
297 base::AutoLock lock(lock_); 327 base::AutoLock lock(lock_);
298 auto ref_count_it = decoded_images_ref_counts_.find(key); 328 auto ref_count_it = decoded_images_ref_counts_.find(key);
299 DCHECK(ref_count_it != decoded_images_ref_counts_.end()); 329 DCHECK(ref_count_it != decoded_images_ref_counts_.end());
300 330
301 --ref_count_it->second; 331 --ref_count_it->second;
302 if (ref_count_it->second == 0) { 332 if (ref_count_it->second == 0) {
(...skipping 10 matching lines...) Expand all
313 DCHECK(decoded_image_it->second->is_locked()); 343 DCHECK(decoded_image_it->second->is_locked());
314 decoded_image_it->second->Unlock(); 344 decoded_image_it->second->Unlock();
315 } 345 }
316 SanityCheckState(__LINE__, true); 346 SanityCheckState(__LINE__, true);
317 } 347 }
318 348
319 void SoftwareImageDecodeController::DecodeImage(const ImageKey& key, 349 void SoftwareImageDecodeController::DecodeImage(const ImageKey& key,
320 const DrawImage& image) { 350 const DrawImage& image) {
321 TRACE_EVENT1("cc", "SoftwareImageDecodeController::DecodeImage", "key", 351 TRACE_EVENT1("cc", "SoftwareImageDecodeController::DecodeImage", "key",
322 key.ToString()); 352 key.ToString());
323 if (!CanHandleImage(key)) {
324 image.image()->preroll();
325
326 base::AutoLock lock(lock_);
327 prerolled_images_.insert(key.image_id());
328 // Erase the pending task from the queue, since the task won't be doing
329 // anything useful after this function terminates. Since we don't preroll
330 // images twice, this is actually not necessary but it behaves similar to
331 // the other code path: when this function finishes, the task isn't in the
332 // pending_image_tasks_ list.
333 pending_image_tasks_.erase(key);
334 return;
335 }
336
337 base::AutoLock lock(lock_); 353 base::AutoLock lock(lock_);
338 AutoRemoveKeyFromTaskMap remove_key_from_task_map(&pending_image_tasks_, key); 354 AutoRemoveKeyFromTaskMap remove_key_from_task_map(&pending_image_tasks_, key);
339 355
340 // We could have finished all of the raster tasks (cancelled) while the task 356 // We could have finished all of the raster tasks (cancelled) while the task
341 // was just starting to run. Since this task already started running, it 357 // was just starting to run. Since this task already started running, it
342 // wasn't cancelled. So, if the ref count for the image is 0 then we can just 358 // wasn't cancelled. So, if the ref count for the image is 0 then we can just
343 // abort. 359 // abort.
344 if (decoded_images_ref_counts_.find(key) == 360 if (decoded_images_ref_counts_.find(key) ==
345 decoded_images_ref_counts_.end()) { 361 decoded_images_ref_counts_.end()) {
346 return; 362 return;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 if (decoded_images_ref_counts_.find(key) == 399 if (decoded_images_ref_counts_.find(key) ==
384 decoded_images_ref_counts_.end()) { 400 decoded_images_ref_counts_.end()) {
385 decoded_image->Unlock(); 401 decoded_image->Unlock();
386 } 402 }
387 403
388 decoded_images_.Put(key, std::move(decoded_image)); 404 decoded_images_.Put(key, std::move(decoded_image));
389 SanityCheckState(__LINE__, true); 405 SanityCheckState(__LINE__, true);
390 } 406 }
391 407
392 std::unique_ptr<SoftwareImageDecodeController::DecodedImage> 408 std::unique_ptr<SoftwareImageDecodeController::DecodedImage>
409 SoftwareImageDecodeController::GetMediumQualityImageDecode(
410 const ImageKey& key,
411 sk_sp<const SkImage> image) {
412 SkSize mipmap_scale =
413 GetMipMapScaleAdjustment(key.src_rect().size(), key.target_size());
414 DCHECK(mipmap_scale.width() > 0.f && mipmap_scale.height() > 0.f);
415
416 if (mipmap_scale.width() == 1.f && mipmap_scale.height() == 1.f) {
417 return GetOriginalImageDecode(key, std::move(image));
418 } else {
419 DrawImage mip_image(
420 image, gfx::RectToSkIRect(key.src_rect()), kMedium_SkFilterQuality,
421 SkMatrix::MakeScale(mipmap_scale.width(), mipmap_scale.height()));
422 auto mip_key = ImageKey::FromDrawImage(mip_image);
vmpstr 2016/05/02 19:58:26 I'm a bit confused: wouldn't the passed key alread
cblume 2016/05/02 23:04:09 Good catch. After our change to ::FromDrawImage, t
423 return GetScaledImageDecode(mip_key, std::move(image));
424 }
425 }
426
427 std::unique_ptr<SoftwareImageDecodeController::DecodedImage>
393 SoftwareImageDecodeController::DecodeImageInternal( 428 SoftwareImageDecodeController::DecodeImageInternal(
394 const ImageKey& key, 429 const ImageKey& key,
395 const DrawImage& draw_image) { 430 const DrawImage& draw_image) {
396 TRACE_EVENT1("disabled-by-default-cc.debug", 431 TRACE_EVENT1("disabled-by-default-cc.debug",
397 "SoftwareImageDecodeController::DecodeImageInternal", "key", 432 "SoftwareImageDecodeController::DecodeImageInternal", "key",
398 key.ToString()); 433 key.ToString());
399 sk_sp<const SkImage> image = draw_image.image(); 434 sk_sp<const SkImage> image = draw_image.image();
400 if (!image) 435 if (!image)
401 return nullptr; 436 return nullptr;
402 437
403 switch (key.filter_quality()) { 438 switch (key.filter_quality()) {
404 case kNone_SkFilterQuality: 439 case kNone_SkFilterQuality:
405 case kLow_SkFilterQuality: 440 case kLow_SkFilterQuality:
406 return GetOriginalImageDecode(key, std::move(image)); 441 return GetOriginalImageDecode(key, std::move(image));
407 case kMedium_SkFilterQuality: 442 case kMedium_SkFilterQuality:
408 NOTIMPLEMENTED(); 443 return GetMediumQualityImageDecode(key, std::move(image));
409 return nullptr;
410 case kHigh_SkFilterQuality: 444 case kHigh_SkFilterQuality:
411 return GetScaledImageDecode(key, std::move(image)); 445 return GetScaledImageDecode(key, std::move(image));
412 default: 446 default:
413 NOTREACHED(); 447 NOTREACHED();
414 return nullptr; 448 return nullptr;
415 } 449 }
416 } 450 }
417 451
418 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( 452 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw(
419 const DrawImage& draw_image) { 453 const DrawImage& draw_image) {
420 ImageKey key = ImageKey::FromDrawImage(draw_image); 454 ImageKey key = ImageKey::FromDrawImage(draw_image);
421 TRACE_EVENT1("disabled-by-default-cc.debug", 455 TRACE_EVENT1("disabled-by-default-cc.debug",
422 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", 456 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key",
423 key.ToString()); 457 key.ToString());
424 // If the target size is empty, we can skip this image draw. 458 // If the target size is empty, we can skip this image draw.
425 if (key.target_size().IsEmpty()) 459 if (key.target_size().IsEmpty())
426 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); 460 return DecodedDrawImage(nullptr, kNone_SkFilterQuality);
427 461
428 if (!CanHandleImage(key))
429 return DecodedDrawImage(draw_image.image(), draw_image.filter_quality());
430
431 return GetDecodedImageForDrawInternal(key, draw_image); 462 return GetDecodedImageForDrawInternal(key, draw_image);
432 } 463 }
433 464
434 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal( 465 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal(
435 const ImageKey& key, 466 const ImageKey& key,
436 const DrawImage& draw_image) { 467 const DrawImage& draw_image) {
437 TRACE_EVENT1("disabled-by-default-cc.debug", 468 TRACE_EVENT1("disabled-by-default-cc.debug",
438 "SoftwareImageDecodeController::GetDecodedImageForDrawInternal", 469 "SoftwareImageDecodeController::GetDecodedImageForDrawInternal",
439 "key", key.ToString()); 470 "key", key.ToString());
440 base::AutoLock lock(lock_); 471 base::AutoLock lock(lock_);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 { 629 {
599 TRACE_EVENT0( 630 TRACE_EVENT0(
600 "disabled-by-default-cc.debug", 631 "disabled-by-default-cc.debug",
601 "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels"); 632 "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels");
602 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() 633 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
603 ->AllocateLockedDiscardableMemory( 634 ->AllocateLockedDiscardableMemory(
604 scaled_info.minRowBytes() * scaled_info.height()); 635 scaled_info.minRowBytes() * scaled_info.height());
605 } 636 }
606 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), 637 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
607 scaled_info.minRowBytes()); 638 scaled_info.minRowBytes());
608 // TODO(vmpstr): Start handling more than just high filter quality. 639 DCHECK(key.filter_quality() == kHigh_SkFilterQuality ||
609 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality()); 640 key.filter_quality() == kMedium_SkFilterQuality);
610 { 641 {
611 TRACE_EVENT0("disabled-by-default-cc.debug", 642 TRACE_EVENT0("disabled-by-default-cc.debug",
612 "SoftwareImageDecodeController::ScaleImage - scale pixels"); 643 "SoftwareImageDecodeController::ScaleImage - scale pixels");
613 bool result = 644 bool result =
614 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); 645 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality());
615 DCHECK(result) << key.ToString(); 646 DCHECK(result) << key.ToString();
616 } 647 }
617 648
618 // Release the original sized decode. Any other intermediate result to release 649 // Release the original sized decode. Any other intermediate result to release
619 // would be the subrect memory. However, that's in a scoped_ptr and will be 650 // would be the subrect memory. However, that's in a scoped_ptr and will be
620 // deleted automatically when we return. 651 // deleted automatically when we return.
621 DrawWithImageFinished(original_size_draw_image, decoded_draw_image); 652 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
622 653
623 return base::WrapUnique( 654 return base::WrapUnique(
624 new DecodedImage(scaled_info, std::move(scaled_pixels), 655 new DecodedImage(scaled_info, std::move(scaled_pixels),
625 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), 656 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()),
626 next_tracing_id_.GetNext())); 657 next_tracing_id_.GetNext()));
627 } 658 }
628 659
629 void SoftwareImageDecodeController::DrawWithImageFinished( 660 void SoftwareImageDecodeController::DrawWithImageFinished(
630 const DrawImage& image, 661 const DrawImage& image,
631 const DecodedDrawImage& decoded_image) { 662 const DecodedDrawImage& decoded_image) {
632 TRACE_EVENT1("disabled-by-default-cc.debug", 663 TRACE_EVENT1("disabled-by-default-cc.debug",
633 "SoftwareImageDecodeController::DrawWithImageFinished", "key", 664 "SoftwareImageDecodeController::DrawWithImageFinished", "key",
634 ImageKey::FromDrawImage(image).ToString()); 665 ImageKey::FromDrawImage(image).ToString());
635 ImageKey key = ImageKey::FromDrawImage(image); 666 ImageKey key = ImageKey::FromDrawImage(image);
636 if (!decoded_image.image() || !CanHandleImage(key)) 667 if (!decoded_image.image())
637 return; 668 return;
638 669
639 if (decoded_image.is_at_raster_decode()) 670 if (decoded_image.is_at_raster_decode())
640 UnrefAtRasterImage(key); 671 UnrefAtRasterImage(key);
641 else 672 else
642 UnrefImage(image); 673 UnrefImage(image);
643 SanityCheckState(__LINE__, false); 674 SanityCheckState(__LINE__, false);
644 } 675 }
645 676
646 void SoftwareImageDecodeController::RefAtRasterImage(const ImageKey& key) { 677 void SoftwareImageDecodeController::RefAtRasterImage(const ImageKey& key) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 DCHECK(decoded_images_ref_counts_.find(key) == 724 DCHECK(decoded_images_ref_counts_.find(key) ==
694 decoded_images_ref_counts_.end()); 725 decoded_images_ref_counts_.end());
695 at_raster_image_it->second->Unlock(); 726 at_raster_image_it->second->Unlock();
696 decoded_images_.Erase(image_it); 727 decoded_images_.Erase(image_it);
697 decoded_images_.Put(key, std::move(at_raster_image_it->second)); 728 decoded_images_.Put(key, std::move(at_raster_image_it->second));
698 } 729 }
699 at_raster_decoded_images_.Erase(at_raster_image_it); 730 at_raster_decoded_images_.Erase(at_raster_image_it);
700 } 731 }
701 } 732 }
702 733
703 bool SoftwareImageDecodeController::CanHandleImage(const ImageKey& key) {
704 // TODO(vmpstr): Start handling medium filter quality as well.
705 return key.filter_quality() != kMedium_SkFilterQuality;
706 }
707
708 void SoftwareImageDecodeController::ReduceCacheUsage() { 734 void SoftwareImageDecodeController::ReduceCacheUsage() {
709 TRACE_EVENT0("cc", "SoftwareImageDecodeController::ReduceCacheUsage"); 735 TRACE_EVENT0("cc", "SoftwareImageDecodeController::ReduceCacheUsage");
710 base::AutoLock lock(lock_); 736 base::AutoLock lock(lock_);
711 size_t num_to_remove = (decoded_images_.size() > kMaxItemsInCache) 737 size_t num_to_remove = (decoded_images_.size() > kMaxItemsInCache)
712 ? (decoded_images_.size() - kMaxItemsInCache) 738 ? (decoded_images_.size() - kMaxItemsInCache)
713 : 0; 739 : 0;
714 for (auto it = decoded_images_.rbegin(); 740 for (auto it = decoded_images_.rbegin();
715 num_to_remove != 0 && it != decoded_images_.rend();) { 741 num_to_remove != 0 && it != decoded_images_.rend();) {
716 if (it->second->is_locked()) { 742 if (it->second->is_locked()) {
717 ++it; 743 ++it;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 } 872 }
847 } 873 }
848 874
849 bool can_use_original_decode = 875 bool can_use_original_decode =
850 quality == kLow_SkFilterQuality || quality == kNone_SkFilterQuality; 876 quality == kLow_SkFilterQuality || quality == kNone_SkFilterQuality;
851 877
852 // If we're going to use the original decode, then the target size should be 878 // If we're going to use the original decode, then the target size should be
853 // the full image size, since that will allow for proper memory accounting. 879 // the full image size, since that will allow for proper memory accounting.
854 // Note we skip the decode if the target size is empty altogether, so don't 880 // Note we skip the decode if the target size is empty altogether, so don't
855 // update the target size in that case. 881 // update the target size in that case.
856 if (can_use_original_decode && !target_size.IsEmpty()) 882 if (can_use_original_decode && !target_size.IsEmpty())
vmpstr 2016/05/02 19:58:26 Should the below condition also check if target_si
cblume 2016/05/02 23:04:09 Done.
857 target_size = gfx::Size(image.image()->width(), image.image()->height()); 883 target_size = gfx::Size(image.image()->width(), image.image()->height());
858 884
885 if (quality == kMedium_SkFilterQuality) {
886 SkSize mip_target_size =
887 GetMipMapScaleAdjustment(src_rect.size(), target_size);
888 target_size.set_width(src_rect.width() * mip_target_size.width());
889 target_size.set_height(src_rect.height() * mip_target_size.height());
890 }
891
859 return ImageDecodeControllerKey(image.image()->uniqueID(), src_rect, 892 return ImageDecodeControllerKey(image.image()->uniqueID(), src_rect,
860 target_size, quality, 893 target_size, quality,
861 can_use_original_decode); 894 can_use_original_decode);
862 } 895 }
863 896
864 ImageDecodeControllerKey::ImageDecodeControllerKey( 897 ImageDecodeControllerKey::ImageDecodeControllerKey(
865 uint32_t image_id, 898 uint32_t image_id,
866 const gfx::Rect& src_rect, 899 const gfx::Rect& src_rect,
867 const gfx::Size& target_size, 900 const gfx::Size& target_size,
868 SkFilterQuality filter_quality, 901 SkFilterQuality filter_quality,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { 994 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() {
962 current_usage_bytes_ = 0; 995 current_usage_bytes_ = 0;
963 } 996 }
964 997
965 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() 998 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe()
966 const { 999 const {
967 return current_usage_bytes_.ValueOrDie(); 1000 return current_usage_bytes_.ValueOrDie();
968 } 1001 }
969 1002
970 } // namespace cc 1003 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tiles/software_image_decode_controller.h ('k') | cc/tiles/software_image_decode_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698