From: msarett Date: Thu, 11 Jun 2015 21:27:27 +0000 (-0700) Subject: DM testing for skipping and scaling X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~2114 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0a24297be4737f5fe23b3b918b193260e64ab32d;p=platform%2Fupstream%2FlibSkiaSharp.git DM testing for skipping and scaling BUG=skia: Review URL: https://codereview.chromium.org/1175993005 --- diff --git a/dm/DM.cpp b/dm/DM.cpp index 0174b73..684ae80 100644 --- a/dm/DM.cpp +++ b/dm/DM.cpp @@ -205,38 +205,54 @@ static void push_codec_srcs(Path path) { return; } - // Build additional test cases for images that decode natively to non-canvas types - switch(codec->getInfo().colorType()) { - case kGray_8_SkColorType: - push_src("image", "codec_kGray8", new CodecSrc(path, CodecSrc::kNormal_Mode, - CodecSrc::kGrayscale_Always_DstColorType)); - push_src("image", "scanline_kGray8", new CodecSrc(path, CodecSrc::kScanline_Mode, - CodecSrc::kGrayscale_Always_DstColorType)); - push_src("image", "scanline_subset_kGray8", new CodecSrc(path, - CodecSrc::kScanline_Subset_Mode, CodecSrc::kGrayscale_Always_DstColorType)); - // Intentional fall through - // FIXME: Is this a long term solution for testing wbmps decodes to kIndex8? - // Further discussion on this topic is at skbug.com/3683 - case kIndex_8_SkColorType: - push_src("image", "codec_kIndex8", new CodecSrc(path, CodecSrc::kNormal_Mode, - CodecSrc::kIndex8_Always_DstColorType)); - push_src("image", "scanline_kIndex8", new CodecSrc(path, CodecSrc::kScanline_Mode, - CodecSrc::kIndex8_Always_DstColorType)); - push_src("image", "scanline_subset_kIndex8", new CodecSrc(path, - CodecSrc::kScanline_Subset_Mode, CodecSrc::kIndex8_Always_DstColorType)); - break; - default: - // Do nothing - break; - } - - // Decode all images to the canvas color type - push_src("image", "codec", new CodecSrc(path, CodecSrc::kNormal_Mode, - CodecSrc::kGetFromCanvas_DstColorType)); - push_src("image", "scanline", new CodecSrc(path, CodecSrc::kScanline_Mode, - CodecSrc::kGetFromCanvas_DstColorType)); - push_src("image", "scanline_subset", new CodecSrc(path, CodecSrc::kScanline_Subset_Mode, - CodecSrc::kGetFromCanvas_DstColorType)); + // Choose scales for scaling tests. + // TODO (msarett): Add more scaling tests as we implement more flexible scaling. + // TODO (msarett): Implement scaling tests for SkImageDecoder in order to compare with these + // tests. SkImageDecoder supports downscales by integer factors. + const float scales[] = { 0.125f, 0.25f, 0.5f, 1.0f }; + + for (float scale : scales) { + // Build additional test cases for images that decode natively to non-canvas types + switch(codec->getInfo().colorType()) { + case kGray_8_SkColorType: + push_src("image", "codec_kGray8", new CodecSrc(path, CodecSrc::kNormal_Mode, + CodecSrc::kGrayscale_Always_DstColorType, scale)); + push_src("image", "scanline_kGray8", new CodecSrc(path, CodecSrc::kScanline_Mode, + CodecSrc::kGrayscale_Always_DstColorType, scale)); + push_src("image", "scanline_subset_kGray8", new CodecSrc(path, + CodecSrc::kScanline_Subset_Mode, CodecSrc::kGrayscale_Always_DstColorType, + scale)); + push_src("image", "stripe_kGray8", new CodecSrc(path, CodecSrc::kStripe_Mode, + CodecSrc::kGrayscale_Always_DstColorType, scale)); + // Intentional fall through + // FIXME: Is this a long term solution for testing wbmps decodes to kIndex8? + // Further discussion on this topic is at skbug.com/3683 + case kIndex_8_SkColorType: + push_src("image", "codec_kIndex8", new CodecSrc(path, CodecSrc::kNormal_Mode, + CodecSrc::kIndex8_Always_DstColorType, scale)); + push_src("image", "scanline_kIndex8", new CodecSrc(path, CodecSrc::kScanline_Mode, + CodecSrc::kIndex8_Always_DstColorType, scale)); + push_src("image", "scanline_subset_kIndex8", new CodecSrc(path, + CodecSrc::kScanline_Subset_Mode, CodecSrc::kIndex8_Always_DstColorType, + scale)); + push_src("image", "stripe_kIndex8", new CodecSrc(path, CodecSrc::kStripe_Mode, + CodecSrc::kIndex8_Always_DstColorType, scale)); + break; + default: + // Do nothing + break; + } + + // Decode all images to the canvas color type + push_src("image", "codec", new CodecSrc(path, CodecSrc::kNormal_Mode, + CodecSrc::kGetFromCanvas_DstColorType, scale)); + push_src("image", "scanline", new CodecSrc(path, CodecSrc::kScanline_Mode, + CodecSrc::kGetFromCanvas_DstColorType, scale)); + push_src("image", "scanline_subset", new CodecSrc(path, CodecSrc::kScanline_Subset_Mode, + CodecSrc::kGetFromCanvas_DstColorType, scale)); + push_src("image", "stripe", new CodecSrc(path, CodecSrc::kStripe_Mode, + CodecSrc::kGetFromCanvas_DstColorType, scale)); + } } static bool codec_supported(const char* ext) { diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 0a90e03..c89ffd1 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -64,10 +64,11 @@ void GMSrc::modifyGrContextOptions(GrContextOptions* options) const { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ -CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType) +CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType, float scale) : fPath(path) , fMode(mode) , fDstColorType(dstColorType) + , fScale(scale) {} Error CodecSrc::draw(SkCanvas* canvas) const { @@ -108,6 +109,13 @@ Error CodecSrc::draw(SkCanvas* canvas) const { break; } + // Try to scale the image if it is desired + SkISize size = codec->getScaledDimensions(fScale); + if (size == decodeInfo.dimensions() && 1.0f != fScale) { + return Error::Nonfatal("Test without scaling is uninteresting."); + } + decodeInfo = decodeInfo.makeWH(size.width(), size.height()); + // Construct a color table for the decode if necessary SkAutoTUnref colorTable(NULL); SkPMColor* colorPtr = NULL; @@ -195,7 +203,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { * subsetBm's size is determined based on the current subset and may be larger for end * subsets. */ - SkImageInfo largestSubsetDecodeInfo = + SkImageInfo largestSubsetDecodeInfo = decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extraY); SkBitmap largestSubsetBm; if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, colorTable.get())) { @@ -226,7 +234,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { } } //skip to first line of subset - const SkImageGenerator::Result skipResult = + const SkImageGenerator::Result skipResult = subsetScanlineDecoder->skipScanlines(y); switch (skipResult) { case SkImageGenerator::kSuccess: @@ -262,6 +270,80 @@ Error CodecSrc::draw(SkCanvas* canvas) const { } break; } + case kStripe_Mode: { + const int height = decodeInfo.height(); + // This value is chosen arbitrarily. We exercise more cases by choosing a value that + // does not align with image blocks. + const int stripeHeight = 37; + const int numStripes = (height + stripeHeight - 1) / stripeHeight; + + // Decode odd stripes + SkScanlineDecoder* decoder = codec->getScanlineDecoder(decodeInfo, NULL, colorPtr, + colorCountPtr); + if (NULL == decoder) { + return Error::Nonfatal("Cannot use scanline decoder for all images"); + } + for (int i = 0; i < numStripes; i += 2) { + // Skip a stripe + const int linesToSkip = SkTMin(stripeHeight, height - i * stripeHeight); + SkImageGenerator::Result result = decoder->skipScanlines(linesToSkip); + switch (result) { + case SkImageGenerator::kSuccess: + case SkImageGenerator::kIncompleteInput: + break; + default: + return SkStringPrintf("Cannot skip scanlines for %s.", fPath.c_str()); + } + + // Read a stripe + const int startY = (i + 1) * stripeHeight; + const int linesToRead = SkTMin(stripeHeight, height - startY); + if (linesToRead > 0) { + result = decoder->getScanlines(bitmap.getAddr(0, startY), + linesToRead, bitmap.rowBytes()); + switch (result) { + case SkImageGenerator::kSuccess: + case SkImageGenerator::kIncompleteInput: + break; + default: + return SkStringPrintf("Cannot get scanlines for %s.", fPath.c_str()); + } + } + } + + // Decode even stripes + decoder = codec->getScanlineDecoder(decodeInfo, NULL, colorPtr, colorCountPtr); + if (NULL == decoder) { + return "Failed to create second scanline decoder."; + } + for (int i = 0; i < numStripes; i += 2) { + // Read a stripe + const int startY = i * stripeHeight; + const int linesToRead = SkTMin(stripeHeight, height - startY); + SkImageGenerator::Result result = decoder->getScanlines(bitmap.getAddr(0, startY), + linesToRead, bitmap.rowBytes()); + switch (result) { + case SkImageGenerator::kSuccess: + case SkImageGenerator::kIncompleteInput: + break; + default: + return SkStringPrintf("Cannot get scanlines for %s.", fPath.c_str()); + } + + // Skip a stripe + const int linesToSkip = SkTMax(0, SkTMin(stripeHeight, + height - (i + 1) * stripeHeight)); + result = decoder->skipScanlines(linesToSkip); + switch (result) { + case SkImageGenerator::kSuccess: + case SkImageGenerator::kIncompleteInput: + break; + default: + return SkStringPrintf("Cannot skip scanlines for %s.", fPath.c_str()); + } + } + canvas->drawBitmap(bitmap, 0, 0); + } } return ""; } @@ -270,14 +352,19 @@ SkISize CodecSrc::size() const { SkAutoTUnref encoded(SkData::NewFromFileName(fPath.c_str())); SkAutoTDelete codec(SkCodec::NewFromData(encoded)); if (NULL != codec) { - return codec->getInfo().dimensions(); + SkISize size = codec->getScaledDimensions(fScale); + return size; } else { return SkISize::Make(0, 0); } } Name CodecSrc::name() const { - return SkOSPath::Basename(fPath.c_str()); + if (1.0f == fScale) { + return SkOSPath::Basename(fPath.c_str()); + } else { + return SkStringPrintf("%s_%.3f", SkOSPath::Basename(fPath.c_str()).c_str(), fScale); + } } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index bd8c41e..b7c28ed 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -98,13 +98,14 @@ public: kNormal_Mode, kScanline_Mode, kScanline_Subset_Mode, + kStripe_Mode, // Tests the skipping of scanlines }; enum DstColorType { kGetFromCanvas_DstColorType, kIndex8_Always_DstColorType, kGrayscale_Always_DstColorType, }; - CodecSrc(Path, Mode, DstColorType); + CodecSrc(Path, Mode, DstColorType, float); Error draw(SkCanvas*) const override; SkISize size() const override; @@ -113,6 +114,7 @@ private: Path fPath; Mode fMode; DstColorType fDstColorType; + float fScale; };