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

Unified Diff: cc/tiles/software_image_decode_controller.cc

Issue 1801933004: Refactor SoftwareImageDecodeController (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Bad return type. Created 4 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: cc/tiles/software_image_decode_controller.cc
diff --git a/cc/tiles/software_image_decode_controller.cc b/cc/tiles/software_image_decode_controller.cc
index d1e7f8083c497b3cd526ee36975cda02d00501d3..5f93e98c018f5aeb54180540397052a9a0d044da 100644
--- a/cc/tiles/software_image_decode_controller.cc
+++ b/cc/tiles/software_image_decode_controller.cc
@@ -368,6 +368,28 @@ void SoftwareImageDecodeController::DecodeImage(const ImageKey& key,
}
scoped_ptr<SoftwareImageDecodeController::DecodedImage>
+SoftwareImageDecodeController::DecodeImageMediumQuality(const ImageKey& key,
+ const SkImage& image) {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+scoped_ptr<SoftwareImageDecodeController::DecodedImage>
+SoftwareImageDecodeController::DecodeImageHighQuality(const ImageKey& key,
+ const SkImage& image) {
+ // If we get here, that means we couldn't use the original sized decode for
+ // whatever reason. However, in all cases we do need an original decode to
+ // either do a scale or to extract a subrect from the image.
+ auto decoded_image_result = DecodeImageOrUseCache(key, image);
+ if (!decoded_image_result.decoded_pixmap_.addr())
+ return nullptr;
+
+ // Now we have a decoded_pixmap which represents the src_rect at the
+ // original scale. All we need to do is scale it.
+ return ScaleImage(key, decoded_image_result);
+}
+
+scoped_ptr<SoftwareImageDecodeController::DecodedImage>
SoftwareImageDecodeController::DecodeImageInternal(
const ImageKey& key,
const DrawImage& draw_image) {
@@ -375,113 +397,23 @@ SoftwareImageDecodeController::DecodeImageInternal(
"SoftwareImageDecodeController::DecodeImageInternal", "key",
key.ToString());
const SkImage* image = draw_image.image();
-
- // If we can use the original decode, then we don't need to do scaling. We can
- // just read pixels into the final memory.
- if (key.can_use_original_decode()) {
- SkImageInfo decoded_info =
- CreateImageInfo(image->width(), image->height(), format_);
- scoped_ptr<base::DiscardableMemory> decoded_pixels;
- {
- TRACE_EVENT0(
- "disabled-by-default-cc.debug",
- "SoftwareImageDecodeController::DecodeImageInternal - allocate "
- "decoded pixels");
- decoded_pixels =
- base::DiscardableMemoryAllocator::GetInstance()
- ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() *
- decoded_info.height());
- }
- {
- TRACE_EVENT0(
- "disabled-by-default-cc.debug",
- "SoftwareImageDecodeController::DecodeImageInternal - read pixels");
- bool result = image->readPixels(decoded_info, decoded_pixels->data(),
- decoded_info.minRowBytes(), 0, 0,
- SkImage::kDisallow_CachingHint);
-
- if (!result) {
- decoded_pixels->Unlock();
- return nullptr;
- }
- }
-
- return make_scoped_ptr(new DecodedImage(
- decoded_info, std::move(decoded_pixels), SkSize::Make(0, 0)));
- }
-
- // If we get here, that means we couldn't use the original sized decode for
- // whatever reason. However, in all cases we do need an original decode to
- // either do a scale or to extract a subrect from the image. So, what we can
- // do is construct a key that would require a full sized decode, then get that
- // decode via GetDecodedImageForDrawInternal(), use it, and unref it. This
- // ensures that if the original sized decode is already available in any of
- // the caches, we reuse that. We also ensure that all the proper locking takes
- // place. If, on the other hand, the decode was not available,
- // GetDecodedImageForDrawInternal() would decode the image, and unreffing it
- // later ensures that we will store the discardable memory unlocked in the
- // cache to be used by future requests.
- gfx::Rect full_image_rect(image->width(), image->height());
- DrawImage original_size_draw_image(image, gfx::RectToSkIRect(full_image_rect),
- kNone_SkFilterQuality, SkMatrix::I());
- ImageKey original_size_key =
- ImageKey::FromDrawImage(original_size_draw_image);
- // Sanity checks.
- DCHECK(original_size_key.can_use_original_decode());
- DCHECK(full_image_rect.size() == original_size_key.target_size());
-
- auto decoded_draw_image = GetDecodedImageForDrawInternal(
- original_size_key, original_size_draw_image);
- if (!decoded_draw_image.image()) {
- DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
+ if (!image) {
return nullptr;
}
- SkPixmap decoded_pixmap;
- bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap);
- DCHECK(result);
- if (key.src_rect() != full_image_rect) {
- result = decoded_pixmap.extractSubset(&decoded_pixmap,
- gfx::RectToSkIRect(key.src_rect()));
- DCHECK(result);
- }
-
- // Now we have a decoded_pixmap which represents the src_rect at the
- // original scale. All we need to do is scale it.
- DCHECK(!key.target_size().IsEmpty());
- SkImageInfo scaled_info = CreateImageInfo(
- key.target_size().width(), key.target_size().height(), format_);
- scoped_ptr<base::DiscardableMemory> scaled_pixels;
- {
- TRACE_EVENT0(
- "disabled-by-default-cc.debug",
- "SoftwareImageDecodeController::DecodeImageInternal - allocate "
- "scaled pixels");
- scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
- ->AllocateLockedDiscardableMemory(
- scaled_info.minRowBytes() * scaled_info.height());
+ switch (key.filter_quality()) {
+ case kNone_SkFilterQuality:
+ // fall through
+ case kLow_SkFilterQuality:
+ return GetOriginalImageDecode(key, *image);
+ case kMedium_SkFilterQuality:
+ return DecodeImageMediumQuality(key, *image);
+ case kHigh_SkFilterQuality:
+ return DecodeImageHighQuality(key, *image);
+ default:
+ NOTREACHED();
+ return nullptr;
}
- SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
- scaled_info.minRowBytes());
- // TODO(vmpstr): Start handling more than just high filter quality.
- DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality());
- {
- TRACE_EVENT0(
- "disabled-by-default-cc.debug",
- "SoftwareImageDecodeController::DecodeImageInternal - scale pixels");
- bool result =
- decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality());
- DCHECK(result);
- }
-
- // Release the original sized decode. Any other intermediate result to release
- // would be the subrect memory. However, that's in a scoped_ptr and will be
- // deleted automatically when we return.
- DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
-
- return make_scoped_ptr(
- new DecodedImage(scaled_info, std::move(scaled_pixels),
- SkSize::Make(-key.src_rect().x(), -key.src_rect().y())));
}
DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw(
@@ -552,7 +484,18 @@ DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal(
// on the compositor thread. This means holding on to the lock might stall
// the compositor thread for the duration of the decode!
base::AutoUnlock unlock(lock_);
- scoped_decoded_image = DecodeImageInternal(key, draw_image);
+ const SkImage* image = draw_image.image();
+ if (key.can_use_original_decode()) {
ericrk 2016/03/24 16:06:59 If we unify the two by calling DecodeImageInternal
ericrk 2016/03/24 16:06:59 Can't we just call DecodeImageInternal here? Seems
cblume 2016/03/24 18:45:10 I began removing it and noticed GetScaleAdjustment
cblume 2016/03/24 18:45:10 Done.
cblume 2016/03/24 18:46:49 Running the tests, the low quality test and none q
+ scoped_decoded_image = GetOriginalImageDecode(key, *image);
+ } else {
+ auto decoded_image_result = DecodeImageOrUseCache(key, *image);
+ if (!decoded_image_result.decoded_pixmap_.addr()) {
+ scoped_decoded_image = nullptr;
+ } else {
+ scoped_decoded_image = ScaleImage(key, decoded_image_result);
+ }
+ }
+
decoded_image = scoped_decoded_image.get();
// Skip the image if we couldn't decode it.
@@ -593,6 +536,126 @@ DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal(
return decoded_draw_image;
}
+SoftwareImageDecodeController::DecodedImageResult::DecodedImageResult(
+ SkPixmap decoded_pixmap,
+ DrawImage original_size_draw_image,
+ DecodedDrawImage decoded_draw_image)
+ : decoded_pixmap_(decoded_pixmap),
+ original_size_draw_image_(original_size_draw_image),
+ decoded_draw_image_(decoded_draw_image) {}
+
+scoped_ptr<SoftwareImageDecodeController::DecodedImage>
+SoftwareImageDecodeController::GetOriginalImageDecode(const ImageKey& key,
+ const SkImage& image) {
+ TRACE_EVENT1("disabled-by-default-cc.debug",
+ "SoftwareImageDecodeController::GetOriginalImageDecode", "key",
+ key.ToString());
+ DCHECK(key.can_use_original_decode());
+ SkImageInfo decoded_info =
+ CreateImageInfo(image.width(), image.height(), format_);
+ scoped_ptr<base::DiscardableMemory> decoded_pixels;
+ {
+ TRACE_EVENT0("disabled-by-default-cc.debug",
+ "SoftwareImageDecodeController::GetOriginalImageDecode - "
+ "allocate decoded pixels");
+ decoded_pixels =
+ base::DiscardableMemoryAllocator::GetInstance()
+ ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() *
+ decoded_info.height());
+ }
+ {
+ TRACE_EVENT0("disabled-by-default-cc.debug",
+ "SoftwareImageDecodeController::GetOriginalImageDecode - "
+ "read pixels");
+ bool result = image.readPixels(decoded_info, decoded_pixels->data(),
+ decoded_info.minRowBytes(), 0, 0,
+ SkImage::kDisallow_CachingHint);
+
+ if (!result) {
+ decoded_pixels->Unlock();
+ return nullptr;
+ }
+ }
+
+ return make_scoped_ptr(new DecodedImage(
+ decoded_info, std::move(decoded_pixels), SkSize::Make(0, 0)));
+}
+
+SoftwareImageDecodeController::DecodedImageResult
+SoftwareImageDecodeController::DecodeImageOrUseCache(const ImageKey& key,
+ const SkImage& image) {
+ // Construct a key to use in GetDecodedImageForDrawInternal().
+ // This allows us to reuse an image in any cache if available.
+ gfx::Rect full_image_rect(image.width(), image.height());
+ DrawImage original_size_draw_image(&image,
+ gfx::RectToSkIRect(full_image_rect),
+ kNone_SkFilterQuality, SkMatrix::I());
+ ImageKey original_size_key =
+ ImageKey::FromDrawImage(original_size_draw_image);
+ // Sanity checks.
+ DCHECK(original_size_key.can_use_original_decode());
+ DCHECK(full_image_rect.size() == original_size_key.target_size());
+
+ auto decoded_draw_image = GetDecodedImageForDrawInternal(
+ original_size_key, original_size_draw_image);
+ if (!decoded_draw_image.image()) {
+ DrawWithImageFinished(original_size_draw_image, decoded_draw_image);
+ return DecodedImageResult(SkPixmap(), DrawImage(),
+ DecodedDrawImage(nullptr, kNone_SkFilterQuality));
+ }
+
+ SkPixmap decoded_pixmap;
+ bool result = decoded_draw_image.image()->peekPixels(&decoded_pixmap);
+ DCHECK(result);
+ if (key.src_rect() != full_image_rect) {
+ result = decoded_pixmap.extractSubset(&decoded_pixmap,
+ gfx::RectToSkIRect(key.src_rect()));
+ DCHECK(result);
+ }
+
+ return DecodedImageResult(decoded_pixmap, original_size_draw_image,
+ decoded_draw_image);
+}
+
+scoped_ptr<SoftwareImageDecodeController::DecodedImage>
+SoftwareImageDecodeController::ScaleImage(
+ const ImageKey& key,
+ const DecodedImageResult& decoded_image_result) {
+ DCHECK(!key.target_size().IsEmpty());
+ SkImageInfo scaled_info = CreateImageInfo(
+ key.target_size().width(), key.target_size().height(), format_);
+ scoped_ptr<base::DiscardableMemory> scaled_pixels;
+ {
+ TRACE_EVENT0(
+ "disabled-by-default-cc.debug",
+ "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels");
+ scaled_pixels = base::DiscardableMemoryAllocator::GetInstance()
+ ->AllocateLockedDiscardableMemory(
+ scaled_info.minRowBytes() * scaled_info.height());
+ }
+ SkPixmap scaled_pixmap(scaled_info, scaled_pixels->data(),
+ scaled_info.minRowBytes());
+ // TODO(vmpstr): Start handling more than just high filter quality.
+ DCHECK_EQ(kHigh_SkFilterQuality, key.filter_quality());
+ {
+ TRACE_EVENT0("disabled-by-default-cc.debug",
+ "SoftwareImageDecodeController::ScaleImage - scale pixels");
+ bool result = decoded_image_result.decoded_pixmap_.scalePixels(
+ scaled_pixmap, key.filter_quality());
+ DCHECK(result);
+ }
+
+ // Release the original sized decode. Any other intermediate result to release
+ // would be the subrect memory. However, that's in a scoped_ptr and will be
+ // deleted automatically when we return.
+ DrawWithImageFinished(decoded_image_result.original_size_draw_image_,
+ decoded_image_result.decoded_draw_image_);
+
+ return make_scoped_ptr(
+ new DecodedImage(scaled_info, std::move(scaled_pixels),
+ SkSize::Make(-key.src_rect().x(), -key.src_rect().y())));
+}
+
void SoftwareImageDecodeController::DrawWithImageFinished(
const DrawImage& image,
const DecodedDrawImage& decoded_image) {
« cc/tiles/software_image_decode_controller.h ('K') | « cc/tiles/software_image_decode_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698