Use new jpeg_crop_scanlines() API to optimize jpeg subset decodes
This was adapted from:
https://codereview.chromium.org/1530933003
Subset Decode Runtime (Original / Optimized) on Nexus 6P
TopLeft 0.51x
TopRight 0.56x
Middle 0.71x
BottomLeft 0.79x
BottomRight 0.79x
BUG=skia:4256
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1719073002
Review URL: https://codereview.chromium.org/1719073002
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 7ccaf22..bd881e8 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -522,6 +522,31 @@
canvas->drawBitmap(bitmap, 0, 0);
break;
}
+ case kCroppedScanline_Mode: {
+ const int width = decodeInfo.width();
+ const int height = decodeInfo.height();
+ // This value is chosen because, as we move across the image, it will sometimes
+ // align with the jpeg block sizes and it will sometimes not. This allows us
+ // to test interestingly different code paths in the implementation.
+ const int tileSize = 36;
+
+ SkCodec::Options opts;
+ SkIRect subset;
+ for (int x = 0; x < width; x += tileSize) {
+ subset = SkIRect::MakeXYWH(x, 0, SkTMin(tileSize, width - x), height);
+ opts.fSubset = ⊂
+ if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &opts,
+ colorPtr, colorCountPtr)) {
+ return "Could not start scanline decoder.";
+ }
+
+ codec->getScanlines(bitmap.getAddr(x, 0), height, bitmap.rowBytes());
+ }
+
+ premultiply_if_necessary(bitmap);
+ canvas->drawBitmap(bitmap, 0, 0);
+ break;
+ }
case kSubset_Mode: {
// Arbitrarily choose a divisor.
int divisor = 2;