diff options
Diffstat (limited to 'bench/subset')
-rw-r--r-- | bench/subset/SubsetBenchPriv.h | 35 | ||||
-rw-r--r-- | bench/subset/SubsetDivisorBench.cpp | 129 | ||||
-rw-r--r-- | bench/subset/SubsetDivisorBench.h | 40 | ||||
-rw-r--r-- | bench/subset/SubsetSingleBench.cpp | 94 | ||||
-rw-r--r-- | bench/subset/SubsetSingleBench.h | 46 | ||||
-rw-r--r-- | bench/subset/SubsetTranslateBench.cpp | 124 | ||||
-rw-r--r-- | bench/subset/SubsetTranslateBench.h | 42 | ||||
-rw-r--r-- | bench/subset/SubsetZoomBench.cpp | 117 | ||||
-rw-r--r-- | bench/subset/SubsetZoomBench.h | 42 |
9 files changed, 669 insertions, 0 deletions
diff --git a/bench/subset/SubsetBenchPriv.h b/bench/subset/SubsetBenchPriv.h new file mode 100644 index 0000000000..e0eb2ff826 --- /dev/null +++ b/bench/subset/SubsetBenchPriv.h @@ -0,0 +1,35 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SubsetBenchPriv_DEFINED +#define SubsetBenchPriv_DEFINED + +#include "SkCodec.h" +#include "SkData.h" +#include "SkImageGenerator.h" + +/* + * Convert the color type to a string + */ +static const char* get_color_name(SkColorType colorType) { + switch(colorType) { + case kN32_SkColorType: + return "N32"; + case kRGB_565_SkColorType: + return "565"; + case kGray_8_SkColorType: + return "Gray8"; + case kIndex_8_SkColorType: + return "Index8"; + case kAlpha_8_SkColorType: + return "Alpha8"; + default: + return "Unknown"; + } +} + +#endif // SubsetBenchPriv_DEFINED diff --git a/bench/subset/SubsetDivisorBench.cpp b/bench/subset/SubsetDivisorBench.cpp new file mode 100644 index 0000000000..0ec2579b6d --- /dev/null +++ b/bench/subset/SubsetDivisorBench.cpp @@ -0,0 +1,129 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SubsetDivisorBench.h" +#include "SubsetBenchPriv.h" +#include "SkData.h" +#include "SkCodec.h" +#include "SkImageDecoder.h" +#include "SkOSFile.h" +#include "SkStream.h" + +/* + * + * This benchmark is designed to test the performance of subset decoding. + * It uses a divisor to decode the entire image in a grid of divisor x divisor blocks. + * + */ + +SubsetDivisorBench::SubsetDivisorBench(const SkString& path, + SkColorType colorType, + uint32_t divisor, + bool useCodec) + : fColorType(colorType) + , fDivisor(divisor) + , fUseCodec(useCodec) +{ + // Parse the filename + SkString baseName = SkOSPath::Basename(path.c_str()); + + // Choose an informative color name + const char* colorName = get_color_name(fColorType); + + fName.printf("%sSubsetDivisor_%dx%d_%s_%s", fUseCodec ? "Codec" : "Image", fDivisor, fDivisor, + baseName.c_str(), colorName); + + // Perform the decode setup + SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); + fStream.reset(new SkMemoryStream(encoded)); +} + +const char* SubsetDivisorBench::onGetName() { + return fName.c_str(); +} + +bool SubsetDivisorBench::isSuitableFor(Backend backend) { + return kNonRendering_Backend == backend; +} + +void SubsetDivisorBench::onDraw(const int n, SkCanvas* canvas) { + // When the color type is kIndex8, we will need to store the color table. If it is + // used, it will be initialized by the codec. + int colorCount; + SkPMColor colors[256]; + if (fUseCodec) { + for (int count = 0; count < n; count++) { + SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream->duplicate())); + const SkImageInfo info = codec->getInfo().makeColorType(fColorType); + SkAutoTDeleteArray<uint8_t> row(SkNEW_ARRAY(uint8_t, info.minRowBytes())); + SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder( + info, NULL, colors, &colorCount); + + const uint32_t subsetWidth = info.width() / fDivisor; + const uint32_t subsetHeight = info.height() / fDivisor; + const uint32_t maxSubsetWidth = subsetWidth + info.width() % fDivisor; + const uint32_t maxSubsetHeight = subsetHeight + info.height() % fDivisor; + SkBitmap bitmap; + // Note that we use the same bitmap for all of the subsets. + // It might be slightly larger than necessary for some of the subsets. + bitmap.allocPixels(info.makeWH(maxSubsetWidth, maxSubsetHeight)); + + for (uint32_t blockX = 0; blockX < fDivisor; blockX++) { + for (uint32_t blockY = 0; blockY < fDivisor; blockY++) { + scanlineDecoder->skipScanlines(blockY * subsetHeight); + const uint32_t currSubsetWidth = + (blockX == fDivisor - 1) ? maxSubsetWidth : subsetWidth; + const uint32_t currSubsetHeight = + (blockY == fDivisor - 1) ? maxSubsetHeight : subsetHeight; + const uint32_t bpp = info.bytesPerPixel(); + for (uint32_t y = 0; y < currSubsetHeight; y++) { + scanlineDecoder->getScanlines(row.get(), 1, 0); + memcpy(bitmap.getAddr(0, y), row.get() + blockX * subsetWidth * bpp, + currSubsetWidth * bpp); + } + } + } + } + } else { + // We create a color table here to satisfy allocPixels() when the output + // type is kIndex8. It's okay that this is uninitialized since we never + // use it. + SkColorTable* colorTable = SkNEW_ARGS(SkColorTable, (colors, 0)); + for (int count = 0; count < n; count++) { + int width, height; + SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); + decoder->buildTileIndex(fStream->duplicate(), &width, &height); + + const uint32_t subsetWidth = width / fDivisor; + const uint32_t subsetHeight = height / fDivisor; + const uint32_t maxSubsetWidth = subsetWidth + width % fDivisor; + const uint32_t maxSubsetHeight = subsetHeight + height % fDivisor; + SkBitmap bitmap; + // Note that we use the same bitmap for all of the subsets. + // It might be slightly larger than necessary for some of the subsets. + // If we do not include this step, decodeSubset() would allocate space + // for the pixels automatically, but this would not allow us to reuse the + // same bitmap as the other subsets. We want to reuse the same bitmap + // because it gives a more fair comparison with SkCodec and is a common + // use case of BitmapRegionDecoder. + bitmap.allocPixels(SkImageInfo::Make(maxSubsetWidth, maxSubsetHeight, + fColorType, kOpaque_SkAlphaType), NULL, colorTable); + + for (uint32_t blockX = 0; blockX < fDivisor; blockX++) { + for (uint32_t blockY = 0; blockY < fDivisor; blockY++) { + const uint32_t currSubsetWidth = + (blockX == fDivisor - 1) ? maxSubsetWidth : subsetWidth; + const uint32_t currSubsetHeight = + (blockY == fDivisor - 1) ? maxSubsetHeight : subsetHeight; + SkIRect rect = SkIRect::MakeXYWH(blockX * subsetWidth, + blockY * subsetHeight, currSubsetWidth, currSubsetHeight); + decoder->decodeSubset(&bitmap, rect, fColorType); + } + } + } + } +} diff --git a/bench/subset/SubsetDivisorBench.h b/bench/subset/SubsetDivisorBench.h new file mode 100644 index 0000000000..e5ea71ff51 --- /dev/null +++ b/bench/subset/SubsetDivisorBench.h @@ -0,0 +1,40 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Benchmark.h" +#include "SkImageDecoder.h" +#include "SkImageInfo.h" +#include "SkStream.h" +#include "SkString.h" + +/* + * + * This benchmark is designed to test the performance of subset decoding. + * It uses a divisor to decode the entire image in a grid of divisor x divisor blocks. + * + */ +class SubsetDivisorBench : public Benchmark { +public: + + SubsetDivisorBench(const SkString& path, + SkColorType colorType, + uint32_t divisor, + bool useCodec); + +protected: + const char* onGetName() override; + bool isSuitableFor(Backend backend) override; + void onDraw(const int n, SkCanvas* canvas) override; + +private: + SkString fName; + SkColorType fColorType; + const uint32_t fDivisor; + const bool fUseCodec; + SkAutoTDelete<SkMemoryStream> fStream; + typedef Benchmark INHERITED; +}; diff --git a/bench/subset/SubsetSingleBench.cpp b/bench/subset/SubsetSingleBench.cpp new file mode 100644 index 0000000000..68c94cd246 --- /dev/null +++ b/bench/subset/SubsetSingleBench.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SubsetSingleBench.h" +#include "SubsetBenchPriv.h" +#include "SkData.h" +#include "SkCodec.h" +#include "SkImageDecoder.h" +#include "SkOSFile.h" +#include "SkStream.h" + +/* + * + * This benchmark is designed to test the performance of subset decoding. + * It uses an input width, height, left, and top to decode a single subset. + * + */ + +SubsetSingleBench::SubsetSingleBench(const SkString& path, + SkColorType colorType, + uint32_t subsetWidth, + uint32_t subsetHeight, + uint32_t offsetLeft, + uint32_t offsetTop, + bool useCodec) + : fColorType(colorType) + , fSubsetWidth(subsetWidth) + , fSubsetHeight(subsetHeight) + , fOffsetLeft(offsetLeft) + , fOffsetTop(offsetTop) + , fUseCodec(useCodec) +{ + // Parse the filename + SkString baseName = SkOSPath::Basename(path.c_str()); + + // Choose an informative color name + const char* colorName = get_color_name(fColorType); + + fName.printf("%sSubsetSingle_%dx%d +%d_+%d_%s_%s", fUseCodec ? "Codec" : "Image", fSubsetWidth, + fSubsetHeight, fOffsetLeft, fOffsetTop, baseName.c_str(), colorName); + + // Perform the decode setup + SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); + fStream.reset(new SkMemoryStream(encoded)); +} + +const char* SubsetSingleBench::onGetName() { + return fName.c_str(); +} + +bool SubsetSingleBench::isSuitableFor(Backend backend) { + return kNonRendering_Backend == backend; +} + +void SubsetSingleBench::onDraw(const int n, SkCanvas* canvas) { + // When the color type is kIndex8, we will need to store the color table. If it is + // used, it will be initialized by the codec. + int colorCount; + SkPMColor colors[256]; + if (fUseCodec) { + for (int count = 0; count < n; count++) { + SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream->duplicate())); + const SkImageInfo info = codec->getInfo().makeColorType(fColorType); + SkAutoTDeleteArray<uint8_t> row(SkNEW_ARRAY(uint8_t, info.minRowBytes())); + SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder( + info, NULL, colors, &colorCount); + + SkBitmap bitmap; + bitmap.allocPixels(info.makeWH(fSubsetWidth, fSubsetHeight)); + + scanlineDecoder->skipScanlines(fOffsetTop); + uint32_t bpp = info.bytesPerPixel(); + for (uint32_t y = 0; y < fSubsetHeight; y++) { + scanlineDecoder->getScanlines(row.get(), 1, 0); + memcpy(bitmap.getAddr(0, y), row.get() + fOffsetLeft * bpp, + fSubsetWidth * bpp); + } + } + } else { + for (int count = 0; count < n; count++) { + SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); + int width, height; + decoder->buildTileIndex(fStream->duplicate(), &width, &height); + SkBitmap bitmap; + SkIRect rect = SkIRect::MakeXYWH(fOffsetLeft, fOffsetTop, fSubsetWidth, + fSubsetHeight); + decoder->decodeSubset(&bitmap, rect, fColorType); + } + } +} diff --git a/bench/subset/SubsetSingleBench.h b/bench/subset/SubsetSingleBench.h new file mode 100644 index 0000000000..1484a51258 --- /dev/null +++ b/bench/subset/SubsetSingleBench.h @@ -0,0 +1,46 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Benchmark.h" +#include "SkImageDecoder.h" +#include "SkImageInfo.h" +#include "SkStream.h" +#include "SkString.h" + +/* + * + * This benchmark is designed to test the performance of subset decoding. + * It uses an input width, height, left, and top to decode a single subset. + * + */ +class SubsetSingleBench : public Benchmark { +public: + + SubsetSingleBench(const SkString& path, + SkColorType colorType, + uint32_t subsetWidth, + uint32_t subsetHeight, + uint32_t offsetLeft, + uint32_t offsetTop, + bool useCodec); + +protected: + const char* onGetName() override; + bool isSuitableFor(Backend backend) override; + void onDraw(const int n, SkCanvas* canvas) override; + +private: + SkString fName; + SkColorType fColorType; + const uint32_t fSubsetWidth; + const uint32_t fSubsetHeight; + const uint32_t fOffsetLeft; + const uint32_t fOffsetTop; + const bool fUseCodec; + SkAutoTDelete<SkMemoryStream> fStream; + typedef Benchmark INHERITED; +}; diff --git a/bench/subset/SubsetTranslateBench.cpp b/bench/subset/SubsetTranslateBench.cpp new file mode 100644 index 0000000000..620b6f4903 --- /dev/null +++ b/bench/subset/SubsetTranslateBench.cpp @@ -0,0 +1,124 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SubsetTranslateBench.h" +#include "SubsetBenchPriv.h" +#include "SkData.h" +#include "SkCodec.h" +#include "SkImageDecoder.h" +#include "SkOSFile.h" +#include "SkStream.h" + +/* + * + * This benchmark is designed to test the performance of subset decoding. + * It uses input dimensions to decode the entire image where each block is susbetW x subsetH. + * + */ + +SubsetTranslateBench::SubsetTranslateBench(const SkString& path, + SkColorType colorType, + uint32_t subsetWidth, + uint32_t subsetHeight, + bool useCodec) + : fColorType(colorType) + , fSubsetWidth(subsetWidth) + , fSubsetHeight(subsetHeight) + , fUseCodec(useCodec) +{ + // Parse the filename + SkString baseName = SkOSPath::Basename(path.c_str()); + + // Choose an informative color name + const char* colorName = get_color_name(fColorType); + + fName.printf("%sSubsetTranslate_%dx%d_%s_%s", fUseCodec ? "Codec" : "Image", fSubsetWidth, + fSubsetHeight, baseName.c_str(), colorName); + + // Perform the decode setup + SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); + fStream.reset(new SkMemoryStream(encoded)); +} + +const char* SubsetTranslateBench::onGetName() { + return fName.c_str(); +} + +bool SubsetTranslateBench::isSuitableFor(Backend backend) { + return kNonRendering_Backend == backend; +} + +void SubsetTranslateBench::onDraw(const int n, SkCanvas* canvas) { + // When the color type is kIndex8, we will need to store the color table. If it is + // used, it will be initialized by the codec. + int colorCount; + SkPMColor colors[256]; + if (fUseCodec) { + for (int count = 0; count < n; count++) { + SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream->duplicate())); + const SkImageInfo info = codec->getInfo().makeColorType(fColorType); + SkAutoTDeleteArray<uint8_t> row(SkNEW_ARRAY(uint8_t, info.minRowBytes())); + SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder( + info, NULL, colors, &colorCount); + + SkBitmap bitmap; + // Note that we use the same bitmap for all of the subsets. + // It might be larger than necessary for the end subsets. + bitmap.allocPixels(info.makeWH(fSubsetWidth, fSubsetHeight)); + + for (int x = 0; x < info.width(); x += fSubsetWidth) { + for (int y = 0; y < info.height(); y += fSubsetHeight) { + scanlineDecoder->skipScanlines(y); + const uint32_t currSubsetWidth = + x + (int) fSubsetWidth > info.width() ? + info.width() - x : fSubsetWidth; + const uint32_t currSubsetHeight = + y + (int) fSubsetHeight > info.height() ? + info.height() - y : fSubsetHeight; + const uint32_t bpp = info.bytesPerPixel(); + for (uint32_t y = 0; y < currSubsetHeight; y++) { + scanlineDecoder->getScanlines(row.get(), 1, 0); + memcpy(bitmap.getAddr(0, y), row.get() + x * bpp, + currSubsetWidth * bpp); + } + } + } + } + } else { + // We create a color table here to satisfy allocPixels() when the output + // type is kIndex8. It's okay that this is uninitialized since we never + // use it. + SkColorTable* colorTable = SkNEW_ARGS(SkColorTable, (colors, 0)); + for (int count = 0; count < n; count++) { + int width, height; + SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); + decoder->buildTileIndex(fStream->duplicate(), &width, &height); + SkBitmap bitmap; + // Note that we use the same bitmap for all of the subsets. + // It might be larger than necessary for the end subsets. + // If we do not include this step, decodeSubset() would allocate space + // for the pixels automatically, but this would not allow us to reuse the + // same bitmap as the other subsets. We want to reuse the same bitmap + // because it gives a more fair comparison with SkCodec and is a common + // use case of BitmapRegionDecoder. + bitmap.allocPixels(SkImageInfo::Make(fSubsetWidth, fSubsetHeight, + fColorType, kOpaque_SkAlphaType), NULL, colorTable); + + for (int x = 0; x < width; x += fSubsetWidth) { + for (int y = 0; y < height; y += fSubsetHeight) { + const uint32_t currSubsetWidth = x + (int) fSubsetWidth > width ? + width - x : fSubsetWidth; + const uint32_t currSubsetHeight = y + (int) fSubsetHeight > height ? + height - y : fSubsetHeight; + SkIRect rect = SkIRect::MakeXYWH(x, y, currSubsetWidth, + currSubsetHeight); + decoder->decodeSubset(&bitmap, rect, fColorType); + } + } + } + } +} diff --git a/bench/subset/SubsetTranslateBench.h b/bench/subset/SubsetTranslateBench.h new file mode 100644 index 0000000000..c7c6febbcb --- /dev/null +++ b/bench/subset/SubsetTranslateBench.h @@ -0,0 +1,42 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Benchmark.h" +#include "SkImageDecoder.h" +#include "SkImageInfo.h" +#include "SkStream.h" +#include "SkString.h" + +/* + * + * This benchmark is designed to test the performance of subset decoding. + * It uses input dimensions to decode the entire image where each block is susbetW x subsetH. + * + */ +class SubsetTranslateBench : public Benchmark { +public: + + SubsetTranslateBench(const SkString& path, + SkColorType colorType, + uint32_t subsetWidth, + uint32_t subsetHeight, + bool useCodec); + +protected: + const char* onGetName() override; + bool isSuitableFor(Backend backend) override; + void onDraw(const int n, SkCanvas* canvas) override; + +private: + SkString fName; + SkColorType fColorType; + const uint32_t fSubsetWidth; + const uint32_t fSubsetHeight; + const bool fUseCodec; + SkAutoTDelete<SkMemoryStream> fStream; + typedef Benchmark INHERITED; +}; diff --git a/bench/subset/SubsetZoomBench.cpp b/bench/subset/SubsetZoomBench.cpp new file mode 100644 index 0000000000..3ce193b6ea --- /dev/null +++ b/bench/subset/SubsetZoomBench.cpp @@ -0,0 +1,117 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SubsetZoomBench.h" +#include "SubsetBenchPriv.h" +#include "SkData.h" +#include "SkCodec.h" +#include "SkImageDecoder.h" +#include "SkOSFile.h" +#include "SkStream.h" + +/* + * + * This benchmark is designed to test the performance of subset decoding. + * Choose subsets to mimic a user zooming in or out on a photo. + * + */ + +SubsetZoomBench::SubsetZoomBench(const SkString& path, + SkColorType colorType, + uint32_t subsetWidth, + uint32_t subsetHeight, + bool useCodec) + : fColorType(colorType) + , fSubsetWidth(subsetWidth) + , fSubsetHeight(subsetHeight) + , fUseCodec(useCodec) +{ + // Parse the filename + SkString baseName = SkOSPath::Basename(path.c_str()); + + // Choose an informative color name + const char* colorName = get_color_name(fColorType); + + fName.printf("%sSubsetZoom_%dx%d_%s_%s", fUseCodec ? "Codec" : "Image", fSubsetWidth, + fSubsetHeight, baseName.c_str(), colorName); + + // Perform the decode setup + SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); + fStream.reset(new SkMemoryStream(encoded)); +} + +const char* SubsetZoomBench::onGetName() { + return fName.c_str(); +} + +bool SubsetZoomBench::isSuitableFor(Backend backend) { + return kNonRendering_Backend == backend; +} + +void SubsetZoomBench::onDraw(const int n, SkCanvas* canvas) { + // When the color type is kIndex8, we will need to store the color table. If it is + // used, it will be initialized by the codec. + int colorCount; + SkPMColor colors[256]; + if (fUseCodec) { + for (int count = 0; count < n; count++) { + SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream->duplicate())); + const SkImageInfo info = codec->getInfo().makeColorType(fColorType); + SkAutoTDeleteArray<uint8_t> row(SkNEW_ARRAY(uint8_t, info.minRowBytes())); + SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder( + info, NULL, colors, &colorCount); + + const int centerX = info.width() / 2; + const int centerY = info.height() / 2; + int w = fSubsetWidth; + int h = fSubsetHeight; + do { + const int subsetStartX = SkTMax(0, centerX - w / 2); + const int subsetStartY = SkTMax(0, centerY - h / 2); + const int subsetWidth = SkTMin(w, info.width() - subsetStartX); + const int subsetHeight = SkTMin(h, info.height() - subsetStartY); + // Note that if we subsetted and scaled in a single step, we could use the + // same bitmap - as is often done in actual use cases. + SkBitmap bitmap; + bitmap.allocPixels(info.makeWH(subsetWidth, subsetHeight)); + + uint32_t bpp = info.bytesPerPixel(); + scanlineDecoder->skipScanlines(subsetStartY); + for (int y = 0; y < subsetHeight; y++) { + scanlineDecoder->getScanlines(row.get(), 1, 0); + memcpy(bitmap.getAddr(0, y), row.get() + subsetStartX * bpp, + subsetWidth * bpp); + } + w <<= 1; + h <<= 1; + } while (w < 2 * info.width() || h < 2 * info.height()); + } + } else { + for (int count = 0; count < n; count++) { + int width, height; + SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); + decoder->buildTileIndex(fStream->duplicate(), &width, &height); + + const int centerX = width / 2; + const int centerY = height / 2; + int w = fSubsetWidth; + int h = fSubsetHeight; + do { + const int subsetStartX = SkTMax(0, centerX - w / 2); + const int subsetStartY = SkTMax(0, centerY - h / 2); + const int subsetWidth = SkTMin(w, width - subsetStartX); + const int subsetHeight = SkTMin(h, height - subsetStartY); + SkBitmap bitmap; + SkIRect rect = SkIRect::MakeXYWH(subsetStartX, subsetStartY, subsetWidth, + subsetHeight); + decoder->decodeSubset(&bitmap, rect, fColorType); + w <<= 1; + h <<= 1; + } while (w < 2 * width || h < 2 * height); + } + } +} diff --git a/bench/subset/SubsetZoomBench.h b/bench/subset/SubsetZoomBench.h new file mode 100644 index 0000000000..6a8f62de46 --- /dev/null +++ b/bench/subset/SubsetZoomBench.h @@ -0,0 +1,42 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Benchmark.h" +#include "SkImageDecoder.h" +#include "SkImageInfo.h" +#include "SkStream.h" +#include "SkString.h" + +/* + * + * This benchmark is designed to test the performance of subset decoding. + * Choose subsets to mimic a user zooming in or out on a photo. + * + */ +class SubsetZoomBench : public Benchmark { +public: + + SubsetZoomBench(const SkString& path, + SkColorType colorType, + uint32_t subsetWidth, + uint32_t subsetHeight, + bool useCodec); + +protected: + const char* onGetName() override; + bool isSuitableFor(Backend backend) override; + void onDraw(const int n, SkCanvas* canvas) override; + +private: + SkString fName; + SkColorType fColorType; + const uint32_t fSubsetWidth; + const uint32_t fSubsetHeight; + const bool fUseCodec; + SkAutoTDelete<SkMemoryStream> fStream; + typedef Benchmark INHERITED; +}; |