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

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: Rebasing Created 4 years, 8 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/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
16 #include "base/thread_task_runner_handle.h" 17 #include "base/thread_task_runner_handle.h"
17 #include "base/trace_event/memory_dump_manager.h" 18 #include "base/trace_event/memory_dump_manager.h"
18 #include "cc/debug/devtools_instrumentation.h" 19 #include "cc/debug/devtools_instrumentation.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 private: 90 private:
90 SoftwareImageDecodeController* controller_; 91 SoftwareImageDecodeController* controller_;
91 SoftwareImageDecodeController::ImageKey image_key_; 92 SoftwareImageDecodeController::ImageKey image_key_;
92 DrawImage image_; 93 DrawImage image_;
93 skia::RefPtr<const SkImage> image_ref_; 94 skia::RefPtr<const SkImage> image_ref_;
94 uint64_t source_prepare_tiles_id_; 95 uint64_t source_prepare_tiles_id_;
95 96
96 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); 97 DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
97 }; 98 };
98 99
100 SkMatrix GetMipMapScale(const SoftwareImageDecodeController::ImageKey& key) {
vmpstr 2016/04/21 20:11:30 Can you add a comment here to describe what the fu
cblume 2016/04/22 01:40:14 Done.
101 gfx::Rect src_rect = key.src_rect();
102 int src_height = src_rect.height();
103 int src_width = src_rect.width();
104
105 int next_mip_height = src_height;
106 int next_mip_width = src_width;
107 for (int current_mip_level = 0;; current_mip_level++) {
108 int mip_height = next_mip_height;
109 int mip_width = next_mip_width;
110
111 next_mip_height = std::max(1, src_height / (1 << (current_mip_level + 1)));
112 next_mip_width = std::max(1, src_width / (1 << (current_mip_level + 1)));
113
114 // Check if an axis on the next mip level would be smaller than the target.
115 // If so, use the current mip level.
116 // This effectively always uses the larger image and always scales down.
117 if (next_mip_height < key.target_size().height() ||
118 next_mip_width < key.target_size().width()) {
119 SkScalar y_scale = 1.f;
120 SkScalar x_scale = 1.f;
121 if (current_mip_level != 0) {
122 y_scale = static_cast<float>(mip_height) / src_height;
123 x_scale = static_cast<float>(mip_width) / src_width;
124 }
125
126 return SkMatrix::MakeScale(x_scale, y_scale);
127 }
128
129 if (mip_height == 1 && mip_width == 1) {
130 // We have reached the final mip level
131 break;
132 }
133 }
134
135 return SkMatrix::MakeScale(0, 0);
136 }
137
99 SkSize GetScaleAdjustment(const ImageDecodeControllerKey& key) { 138 SkSize GetScaleAdjustment(const ImageDecodeControllerKey& key) {
100 // If the requested filter quality did not require scale, then the adjustment 139 // If the requested filter quality did not require scale, then the adjustment
101 // is identity. 140 // is identity.
102 if (key.can_use_original_decode()) 141 float x_scale = 1.f;
vmpstr 2016/04/21 20:11:30 I'd kind of prefer if we keep this type of logic:
cblume 2016/04/22 01:40:14 Done.
103 return SkSize::Make(1.f, 1.f); 142 float y_scale = 1.f;
104 143
105 float x_scale = 144 if (!key.can_use_original_decode()) {
106 key.target_size().width() / static_cast<float>(key.src_rect().width()); 145 if (key.filter_quality() == kMedium_SkFilterQuality) {
107 float y_scale = 146 SkMatrix mipmap_scale = GetMipMapScale(key);
108 key.target_size().height() / static_cast<float>(key.src_rect().height()); 147 x_scale = mipmap_scale.getScaleX();
148 y_scale = mipmap_scale.getScaleY();
149 } else {
150 x_scale = key.target_size().width() /
151 static_cast<float>(key.src_rect().width());
152 y_scale = key.target_size().height() /
153 static_cast<float>(key.src_rect().height());
154 }
155 }
109 return SkSize::Make(x_scale, y_scale); 156 return SkSize::Make(x_scale, y_scale);
110 } 157 }
111 158
112 SkFilterQuality GetDecodedFilterQuality(const ImageDecodeControllerKey& key) { 159 SkFilterQuality GetDecodedFilterQuality(const ImageDecodeControllerKey& key) {
113 return std::min(key.filter_quality(), kLow_SkFilterQuality); 160 return std::min(key.filter_quality(), kLow_SkFilterQuality);
114 } 161 }
115 162
116 SkImageInfo CreateImageInfo(size_t width, 163 SkImageInfo CreateImageInfo(size_t width,
117 size_t height, 164 size_t height,
118 ResourceFormat format) { 165 ResourceFormat format) {
119 return SkImageInfo::Make(width, height, 166 return SkImageInfo::Make(width, height,
120 ResourceFormatToClosestSkColorType(format), 167 ResourceFormatToClosestSkColorType(format),
121 kPremul_SkAlphaType); 168 kPremul_SkAlphaType);
122 } 169 }
123 170
124 } // namespace 171 } // namespace
125
vmpstr 2016/04/21 20:11:31 keep whitespace
cblume 2016/04/22 01:40:14 Done.
126 SoftwareImageDecodeController::SoftwareImageDecodeController( 172 SoftwareImageDecodeController::SoftwareImageDecodeController(
127 ResourceFormat format) 173 ResourceFormat format)
128 : decoded_images_(ImageMRUCache::NO_AUTO_EVICT), 174 : decoded_images_(ImageMRUCache::NO_AUTO_EVICT),
129 at_raster_decoded_images_(ImageMRUCache::NO_AUTO_EVICT), 175 at_raster_decoded_images_(ImageMRUCache::NO_AUTO_EVICT),
130 locked_images_budget_(kLockedMemoryLimitBytes), 176 locked_images_budget_(kLockedMemoryLimitBytes),
131 format_(format) { 177 format_(format) {
132 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). 178 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
133 // Don't register a dump provider in these cases. 179 // Don't register a dump provider in these cases.
134 if (base::ThreadTaskRunnerHandle::IsSet()) { 180 if (base::ThreadTaskRunnerHandle::IsSet()) {
135 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( 181 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
(...skipping 30 matching lines...) Expand all
166 "SoftwareImageDecodeController::GetTaskForImageAndRef", "key", 212 "SoftwareImageDecodeController::GetTaskForImageAndRef", "key",
167 key.ToString()); 213 key.ToString());
168 214
169 // If the target size is empty, we can skip this image during draw (and thus 215 // If the target size is empty, we can skip this image during draw (and thus
170 // we don't need to decode it or ref it). 216 // we don't need to decode it or ref it).
171 if (key.target_size().IsEmpty()) { 217 if (key.target_size().IsEmpty()) {
172 *task = nullptr; 218 *task = nullptr;
173 return false; 219 return false;
174 } 220 }
175 221
176 // If we're not going to do a scale, we will just create a task to preroll the
177 // image the first time we see it. This doesn't need to account for memory.
178 // TODO(vmpstr): We can also lock the original sized image, in which case it
179 // does require memory bookkeeping.
180 if (!CanHandleImage(key)) {
181 base::AutoLock lock(lock_);
182 if (prerolled_images_.count(key.image_id()) == 0) {
183 scoped_refptr<TileTask>& existing_task = pending_image_tasks_[key];
184 if (!existing_task) {
185 existing_task = make_scoped_refptr(
186 new ImageDecodeTaskImpl(this, key, image, prepare_tiles_id));
187 }
188 *task = existing_task;
189 } else {
190 *task = nullptr;
191 }
192 return false;
193 }
194
195 base::AutoLock lock(lock_); 222 base::AutoLock lock(lock_);
196 223
197 // If we already have the image in cache, then we can return it. 224 // If we already have the image in cache, then we can return it.
198 auto decoded_it = decoded_images_.Get(key); 225 auto decoded_it = decoded_images_.Get(key);
199 bool new_image_fits_in_memory = 226 bool new_image_fits_in_memory =
200 locked_images_budget_.AvailableMemoryBytes() >= key.locked_bytes(); 227 locked_images_budget_.AvailableMemoryBytes() >= key.locked_bytes();
201 if (decoded_it != decoded_images_.end()) { 228 if (decoded_it != decoded_images_.end()) {
202 if (decoded_it->second->is_locked() || 229 if (decoded_it->second->is_locked() ||
203 (new_image_fits_in_memory && decoded_it->second->Lock())) { 230 (new_image_fits_in_memory && decoded_it->second->Lock())) {
204 RefImage(key); 231 RefImage(key);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 } 283 }
257 284
258 void SoftwareImageDecodeController::UnrefImage(const DrawImage& image) { 285 void SoftwareImageDecodeController::UnrefImage(const DrawImage& image) {
259 // When we unref the image, there are several situations we need to consider: 286 // When we unref the image, there are several situations we need to consider:
260 // 1. The ref did not reach 0, which means we have to keep the image locked. 287 // 1. The ref did not reach 0, which means we have to keep the image locked.
261 // 2. The ref reached 0, we should unlock it. 288 // 2. The ref reached 0, we should unlock it.
262 // 2a. The image isn't in the locked cache because we didn't get to decode 289 // 2a. The image isn't in the locked cache because we didn't get to decode
263 // it yet (or failed to decode it). 290 // it yet (or failed to decode it).
264 // 2b. Unlock the image but keep it in list. 291 // 2b. Unlock the image but keep it in list.
265 const ImageKey& key = ImageKey::FromDrawImage(image); 292 const ImageKey& key = ImageKey::FromDrawImage(image);
266 DCHECK(CanHandleImage(key)) << key.ToString();
267 TRACE_EVENT1("disabled-by-default-cc.debug", 293 TRACE_EVENT1("disabled-by-default-cc.debug",
268 "SoftwareImageDecodeController::UnrefImage", "key", 294 "SoftwareImageDecodeController::UnrefImage", "key",
269 key.ToString()); 295 key.ToString());
270 296
271 base::AutoLock lock(lock_); 297 base::AutoLock lock(lock_);
272 auto ref_count_it = decoded_images_ref_counts_.find(key); 298 auto ref_count_it = decoded_images_ref_counts_.find(key);
273 DCHECK(ref_count_it != decoded_images_ref_counts_.end()); 299 DCHECK(ref_count_it != decoded_images_ref_counts_.end());
274 300
275 --ref_count_it->second; 301 --ref_count_it->second;
276 if (ref_count_it->second == 0) { 302 if (ref_count_it->second == 0) {
(...skipping 10 matching lines...) Expand all
287 DCHECK(decoded_image_it->second->is_locked()); 313 DCHECK(decoded_image_it->second->is_locked());
288 decoded_image_it->second->Unlock(); 314 decoded_image_it->second->Unlock();
289 } 315 }
290 SanityCheckState(__LINE__, true); 316 SanityCheckState(__LINE__, true);
291 } 317 }
292 318
293 void SoftwareImageDecodeController::DecodeImage(const ImageKey& key, 319 void SoftwareImageDecodeController::DecodeImage(const ImageKey& key,
294 const DrawImage& image) { 320 const DrawImage& image) {
295 TRACE_EVENT1("cc", "SoftwareImageDecodeController::DecodeImage", "key", 321 TRACE_EVENT1("cc", "SoftwareImageDecodeController::DecodeImage", "key",
296 key.ToString()); 322 key.ToString());
297 if (!CanHandleImage(key)) {
298 image.image()->preroll();
299
300 base::AutoLock lock(lock_);
301 prerolled_images_.insert(key.image_id());
302 // Erase the pending task from the queue, since the task won't be doing
303 // anything useful after this function terminates. Since we don't preroll
304 // images twice, this is actually not necessary but it behaves similar to
305 // the other code path: when this function finishes, the task isn't in the
306 // pending_image_tasks_ list.
307 pending_image_tasks_.erase(key);
308 return;
309 }
310
311 base::AutoLock lock(lock_); 323 base::AutoLock lock(lock_);
312 AutoRemoveKeyFromTaskMap remove_key_from_task_map(&pending_image_tasks_, key); 324 AutoRemoveKeyFromTaskMap remove_key_from_task_map(&pending_image_tasks_, key);
313 325
314 // We could have finished all of the raster tasks (cancelled) while the task 326 // We could have finished all of the raster tasks (cancelled) while the task
315 // was just starting to run. Since this task already started running, it 327 // was just starting to run. Since this task already started running, it
316 // wasn't cancelled. So, if the ref count for the image is 0 then we can just 328 // wasn't cancelled. So, if the ref count for the image is 0 then we can just
317 // abort. 329 // abort.
318 if (decoded_images_ref_counts_.find(key) == 330 if (decoded_images_ref_counts_.find(key) ==
319 decoded_images_ref_counts_.end()) { 331 decoded_images_ref_counts_.end()) {
320 return; 332 return;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 if (decoded_images_ref_counts_.find(key) == 369 if (decoded_images_ref_counts_.find(key) ==
358 decoded_images_ref_counts_.end()) { 370 decoded_images_ref_counts_.end()) {
359 decoded_image->Unlock(); 371 decoded_image->Unlock();
360 } 372 }
361 373
362 decoded_images_.Put(key, std::move(decoded_image)); 374 decoded_images_.Put(key, std::move(decoded_image));
363 SanityCheckState(__LINE__, true); 375 SanityCheckState(__LINE__, true);
364 } 376 }
365 377
366 std::unique_ptr<SoftwareImageDecodeController::DecodedImage> 378 std::unique_ptr<SoftwareImageDecodeController::DecodedImage>
379 SoftwareImageDecodeController::DecodeImageMediumQuality(const ImageKey& key,
380 const SkImage& image) {
381 SkMatrix mipmap_scale = GetMipMapScale(key);
382 if (mipmap_scale.getScaleX() == 0 || mipmap_scale.getScaleY() == 0) {
vmpstr 2016/04/21 20:11:30 This should be doing an epsilon comparison since i
cblume 2016/04/22 01:40:14 This started a good conversation in my cube. Our c
383 return nullptr;
384 }
385
386 gfx::Rect src_rect = key.src_rect();
387 DrawImage mip_image(&image, gfx::RectToSkIRect(src_rect),
vmpstr 2016/04/21 20:11:31 nit: key.src_rect() directly here
cblume 2016/04/22 01:40:14 Done.
388 kMedium_SkFilterQuality, mipmap_scale);
389 auto mip_key = ImageKey::FromDrawImage(mip_image);
vmpstr 2016/04/21 20:11:30 Interesting, so you create a new DrawImage that is
cblume 2016/04/22 01:40:14 I asked the Skia team about if it runs a bilerp if
390 return GetScaledImageDecode(mip_key, image);
391 }
392
393 std::unique_ptr<SoftwareImageDecodeController::DecodedImage>
367 SoftwareImageDecodeController::DecodeImageInternal( 394 SoftwareImageDecodeController::DecodeImageInternal(
368 const ImageKey& key, 395 const ImageKey& key,
369 const DrawImage& draw_image) { 396 const DrawImage& draw_image) {
370 TRACE_EVENT1("disabled-by-default-cc.debug", 397 TRACE_EVENT1("disabled-by-default-cc.debug",
371 "SoftwareImageDecodeController::DecodeImageInternal", "key", 398 "SoftwareImageDecodeController::DecodeImageInternal", "key",
372 key.ToString()); 399 key.ToString());
373 const SkImage* image = draw_image.image(); 400 const SkImage* image = draw_image.image();
374 if (!image) 401 if (!image)
375 return nullptr; 402 return nullptr;
376 403
377 switch (key.filter_quality()) { 404 switch (key.filter_quality()) {
378 case kNone_SkFilterQuality: 405 case kNone_SkFilterQuality:
379 case kLow_SkFilterQuality: 406 case kLow_SkFilterQuality:
380 return GetOriginalImageDecode(key, *image); 407 return GetOriginalImageDecode(key, *image);
381 case kMedium_SkFilterQuality: 408 case kMedium_SkFilterQuality:
382 NOTIMPLEMENTED(); 409 return DecodeImageMediumQuality(key, *image);
vmpstr 2016/04/21 20:11:30 To be consistent, can you have this GetMediumQuali
cblume 2016/04/22 01:40:14 Done.
383 return nullptr;
384 case kHigh_SkFilterQuality: 410 case kHigh_SkFilterQuality:
385 return GetScaledImageDecode(key, *image); 411 return GetScaledImageDecode(key, *image);
386 default: 412 default:
387 NOTREACHED(); 413 NOTREACHED();
388 return nullptr; 414 return nullptr;
389 } 415 }
390 } 416 }
391 417
392 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( 418 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw(
393 const DrawImage& draw_image) { 419 const DrawImage& draw_image) {
394 ImageKey key = ImageKey::FromDrawImage(draw_image); 420 ImageKey key = ImageKey::FromDrawImage(draw_image);
395 TRACE_EVENT1("disabled-by-default-cc.debug", 421 TRACE_EVENT1("disabled-by-default-cc.debug",
396 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", 422 "SoftwareImageDecodeController::GetDecodedImageForDraw", "key",
397 key.ToString()); 423 key.ToString());
398 // If the target size is empty, we can skip this image draw. 424 // If the target size is empty, we can skip this image draw.
399 if (key.target_size().IsEmpty()) 425 if (key.target_size().IsEmpty())
400 return DecodedDrawImage(nullptr, kNone_SkFilterQuality); 426 return DecodedDrawImage(nullptr, kNone_SkFilterQuality);
401 427
402 if (!CanHandleImage(key))
403 return DecodedDrawImage(draw_image.image(), draw_image.filter_quality());
404
405 return GetDecodedImageForDrawInternal(key, draw_image); 428 return GetDecodedImageForDrawInternal(key, draw_image);
406 } 429 }
407 430
408 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal( 431 DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal(
409 const ImageKey& key, 432 const ImageKey& key,
410 const DrawImage& draw_image) { 433 const DrawImage& draw_image) {
411 TRACE_EVENT1("disabled-by-default-cc.debug", 434 TRACE_EVENT1("disabled-by-default-cc.debug",
412 "SoftwareImageDecodeController::GetDecodedImageForDrawInternal", 435 "SoftwareImageDecodeController::GetDecodedImageForDrawInternal",
413 "key", key.ToString()); 436 "key", key.ToString());
414 base::AutoLock lock(lock_); 437 base::AutoLock lock(lock_);
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 { 593 {
571 TRACE_EVENT0( 594 TRACE_EVENT0(
572 "disabled-by-default-cc.debug", 595 "disabled-by-default-cc.debug",
573 "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels"); 596 "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels");
574 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() 597 scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
575 ->AllocateLockedDiscardableMemory( 598 ->AllocateLockedDiscardableMemory(
576 scaled_info.minRowBytes() * scaled_info.height()); 599 scaled_info.minRowBytes() * scaled_info.height());
577 } 600 }
578 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(), 601 SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
579 scaled_info.minRowBytes()); 602 scaled_info.minRowBytes());
580 // TODO(vmpstr): Start handling more than just high filter quality.
581 DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality());
vmpstr 2016/04/21 20:11:31 Can you add a DCHECK(key.filter_quality() == kHig
cblume 2016/04/22 01:40:14 Done.
582 { 603 {
583 TRACE_EVENT0("disabled-by-default-cc.debug", 604 TRACE_EVENT0("disabled-by-default-cc.debug",
584 "SoftwareImageDecodeController::ScaleImage - scale pixels"); 605 "SoftwareImageDecodeController::ScaleImage - scale pixels");
585 bool result = 606 bool result =
586 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); 607 decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality());
587 DCHECK(result) << key.ToString(); 608 DCHECK(result) << key.ToString();
588 } 609 }
589 610
590 // Release the original sized decode. Any other intermediate result to release 611 // Release the original sized decode. Any other intermediate result to release
591 // would be the subrect memory. However, that's in a scoped_ptr and will be 612 // would be the subrect memory. However, that's in a scoped_ptr and will be
592 // deleted automatically when we return. 613 // deleted automatically when we return.
593 DrawWithImageFinished(original_size_draw_image, decoded_draw_image); 614 DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
594 615
595 return base::WrapUnique( 616 return base::WrapUnique(
596 new DecodedImage(scaled_info, std::move(scaled_pixels), 617 new DecodedImage(scaled_info, std::move(scaled_pixels),
597 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()), 618 SkSize::Make(-key.src_rect().x(), -key.src_rect().y()),
598 next_tracing_id_.GetNext())); 619 next_tracing_id_.GetNext()));
599 } 620 }
600 621
601 void SoftwareImageDecodeController::DrawWithImageFinished( 622 void SoftwareImageDecodeController::DrawWithImageFinished(
602 const DrawImage& image, 623 const DrawImage& image,
603 const DecodedDrawImage& decoded_image) { 624 const DecodedDrawImage& decoded_image) {
604 TRACE_EVENT1("disabled-by-default-cc.debug", 625 TRACE_EVENT1("disabled-by-default-cc.debug",
605 "SoftwareImageDecodeController::DrawWithImageFinished", "key", 626 "SoftwareImageDecodeController::DrawWithImageFinished", "key",
606 ImageKey::FromDrawImage(image).ToString()); 627 ImageKey::FromDrawImage(image).ToString());
607 ImageKey key = ImageKey::FromDrawImage(image); 628 ImageKey key = ImageKey::FromDrawImage(image);
608 if (!decoded_image.image() || !CanHandleImage(key)) 629 if (!decoded_image.image())
609 return; 630 return;
610 631
611 if (decoded_image.is_at_raster_decode()) 632 if (decoded_image.is_at_raster_decode())
612 UnrefAtRasterImage(key); 633 UnrefAtRasterImage(key);
613 else 634 else
614 UnrefImage(image); 635 UnrefImage(image);
615 SanityCheckState(__LINE__, false); 636 SanityCheckState(__LINE__, false);
616 } 637 }
617 638
618 void SoftwareImageDecodeController::RefAtRasterImage(const ImageKey& key) { 639 void SoftwareImageDecodeController::RefAtRasterImage(const ImageKey& key) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 DCHECK(decoded_images_ref_counts_.find(key) == 686 DCHECK(decoded_images_ref_counts_.find(key) ==
666 decoded_images_ref_counts_.end()); 687 decoded_images_ref_counts_.end());
667 at_raster_image_it->second->Unlock(); 688 at_raster_image_it->second->Unlock();
668 decoded_images_.Erase(image_it); 689 decoded_images_.Erase(image_it);
669 decoded_images_.Put(key, std::move(at_raster_image_it->second)); 690 decoded_images_.Put(key, std::move(at_raster_image_it->second));
670 } 691 }
671 at_raster_decoded_images_.Erase(at_raster_image_it); 692 at_raster_decoded_images_.Erase(at_raster_image_it);
672 } 693 }
673 } 694 }
674 695
675 bool SoftwareImageDecodeController::CanHandleImage(const ImageKey& key) {
676 // TODO(vmpstr): Start handling medium filter quality as well.
677 return key.filter_quality() != kMedium_SkFilterQuality;
678 }
679
680 void SoftwareImageDecodeController::ReduceCacheUsage() { 696 void SoftwareImageDecodeController::ReduceCacheUsage() {
681 TRACE_EVENT0("cc", "SoftwareImageDecodeController::ReduceCacheUsage"); 697 TRACE_EVENT0("cc", "SoftwareImageDecodeController::ReduceCacheUsage");
682 base::AutoLock lock(lock_); 698 base::AutoLock lock(lock_);
683 size_t num_to_remove = (decoded_images_.size() > kMaxItemsInCache) 699 size_t num_to_remove = (decoded_images_.size() > kMaxItemsInCache)
684 ? (decoded_images_.size() - kMaxItemsInCache) 700 ? (decoded_images_.size() - kMaxItemsInCache)
685 : 0; 701 : 0;
686 for (auto it = decoded_images_.rbegin(); 702 for (auto it = decoded_images_.rbegin();
687 num_to_remove != 0 && it != decoded_images_.rend();) { 703 num_to_remove != 0 && it != decoded_images_.rend();) {
688 if (it->second->is_locked()) { 704 if (it->second->is_locked()) {
689 ++it; 705 ++it;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { 949 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() {
934 current_usage_bytes_ = 0; 950 current_usage_bytes_ = 0;
935 } 951 }
936 952
937 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() 953 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe()
938 const { 954 const {
939 return current_usage_bytes_.ValueOrDie(); 955 return current_usage_bytes_.ValueOrDie();
940 } 956 }
941 957
942 } // namespace cc 958 } // 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