aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bench/BitmapRegionDecoderBench.cpp68
-rw-r--r--bench/BitmapRegionDecoderBench.h49
-rw-r--r--bench/CodecBench.cpp17
-rw-r--r--bench/CodecBenchPriv.h30
-rw-r--r--bench/DecodingBench.cpp17
-rw-r--r--bench/nanobench.cpp140
-rw-r--r--bench/subset/SubsetBenchPriv.h20
-rw-r--r--bench/subset/SubsetSingleBench.cpp3
-rw-r--r--bench/subset/SubsetTranslateBench.cpp3
-rw-r--r--bench/subset/SubsetZoomBench.cpp3
-rw-r--r--dm/DM.cpp3
-rw-r--r--dm/DMSrcSink.cpp3
-rw-r--r--dm/DMSrcSink.h2
-rw-r--r--gyp/bench.gypi1
-rw-r--r--gyp/visualbench.gyp1
-rw-r--r--tools/SkCodecTools.h15
16 files changed, 314 insertions, 61 deletions
diff --git a/bench/BitmapRegionDecoderBench.cpp b/bench/BitmapRegionDecoderBench.cpp
new file mode 100644
index 0000000000..77d342331d
--- /dev/null
+++ b/bench/BitmapRegionDecoderBench.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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 "BitmapRegionDecoderBench.h"
+#include "CodecBenchPriv.h"
+#include "SkBitmap.h"
+#include "SkCodecTools.h"
+#include "SkOSFile.h"
+
+BitmapRegionDecoderBench::BitmapRegionDecoderBench(const char* baseName, SkData* encoded,
+ SkBitmapRegionDecoderInterface::Strategy strategy, SkColorType colorType,
+ uint32_t sampleSize, const SkIRect& subset)
+ : fBRD(nullptr)
+ , fData(SkRef(encoded))
+ , fStrategy(strategy)
+ , fColorType(colorType)
+ , fSampleSize(sampleSize)
+ , fSubset(subset)
+{
+ // Choose a useful name for the region decoding strategy
+ const char* strategyName;
+ switch (strategy) {
+ case SkBitmapRegionDecoderInterface::kOriginal_Strategy:
+ strategyName = "Original";
+ break;
+ case SkBitmapRegionDecoderInterface::kCanvas_Strategy:
+ strategyName = "Canvas";
+ break;
+ default:
+ SkASSERT(false);
+ strategyName = "";
+ break;
+ }
+
+ // Choose a useful name for the color type
+ const char* colorName = color_type_to_str(colorType);
+
+ fName.printf("BRD_%s_%s_%s", baseName, strategyName, colorName);
+ if (1 != sampleSize) {
+ fName.appendf("_%.3f", get_scale_from_sample_size(sampleSize));
+ }
+}
+
+const char* BitmapRegionDecoderBench::onGetName() {
+ return fName.c_str();
+}
+
+bool BitmapRegionDecoderBench::isSuitableFor(Backend backend) {
+ return kNonRendering_Backend == backend;
+}
+
+void BitmapRegionDecoderBench::onPreDraw() {
+ SkStreamRewindable* stream = new SkMemoryStream(fData);
+ fBRD.reset(SkBitmapRegionDecoderInterface::CreateBitmapRegionDecoder(stream, fStrategy));
+}
+
+void BitmapRegionDecoderBench::onDraw(const int n, SkCanvas* canvas) {
+ SkAutoTDelete<SkBitmap> bitmap;
+ for (int i = 0; i < n; i++) {
+ bitmap.reset(fBRD->decodeRegion(fSubset.left(), fSubset.top(), fSubset.width(),
+ fSubset.height(), fSampleSize, fColorType));
+ SkASSERT(nullptr != bitmap.get());
+ }
+}
diff --git a/bench/BitmapRegionDecoderBench.h b/bench/BitmapRegionDecoderBench.h
new file mode 100644
index 0000000000..7be770f472
--- /dev/null
+++ b/bench/BitmapRegionDecoderBench.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef BitmapRegionDecoderBench_DEFINED
+#define BitmapRegionDecoderBench_DEFINED
+
+#include "Benchmark.h"
+#include "SkBitmapRegionDecoderInterface.h"
+#include "SkData.h"
+#include "SkImageInfo.h"
+#include "SkRefCnt.h"
+#include "SkString.h"
+
+/**
+ * Benchmark Android's BitmapRegionDecoder for a particular colorType, sampleSize, and subset.
+ *
+ * fStrategy determines which of various implementations is to be used.
+ *
+ * nanobench.cpp handles creating benchmarks for interesting scaled subsets. We strive to test
+ * on real use cases.
+ */
+class BitmapRegionDecoderBench : public Benchmark {
+public:
+ // Calls encoded->ref()
+ BitmapRegionDecoderBench(const char* basename, SkData* encoded,
+ SkBitmapRegionDecoderInterface::Strategy strategy, SkColorType colorType,
+ uint32_t sampleSize, const SkIRect& subset);
+
+protected:
+ const char* onGetName() override;
+ bool isSuitableFor(Backend backend) override;
+ void onDraw(const int n, SkCanvas* canvas) override;
+ void onPreDraw() override;
+
+private:
+ SkString fName;
+ SkAutoTDelete<SkBitmapRegionDecoderInterface> fBRD;
+ SkAutoTUnref<SkData> fData;
+ const SkBitmapRegionDecoderInterface::Strategy fStrategy;
+ const SkColorType fColorType;
+ const uint32_t fSampleSize;
+ const SkIRect fSubset;
+ typedef Benchmark INHERITED;
+};
+#endif // BitmapRegionDecoderBench_DEFINED
diff --git a/bench/CodecBench.cpp b/bench/CodecBench.cpp
index 1e6b5207bf..a21aae1f0b 100644
--- a/bench/CodecBench.cpp
+++ b/bench/CodecBench.cpp
@@ -6,6 +6,7 @@
*/
#include "CodecBench.h"
+#include "CodecBenchPriv.h"
#include "SkBitmap.h"
#include "SkCodec.h"
#include "SkOSFile.h"
@@ -15,21 +16,7 @@ CodecBench::CodecBench(SkString baseName, SkData* encoded, SkColorType colorType
, fData(SkRef(encoded))
{
// Parse filename and the color type to give the benchmark a useful name
- const char* colorName;
- switch(colorType) {
- case kN32_SkColorType:
- colorName = "N32";
- break;
- case kRGB_565_SkColorType:
- colorName = "565";
- break;
- case kAlpha_8_SkColorType:
- colorName = "Alpha8";
- break;
- default:
- colorName = "Unknown";
- }
- fName.printf("Codec_%s_%s", baseName.c_str(), colorName);
+ fName.printf("Codec_%s_%s", baseName.c_str(), color_type_to_str(colorType));
#ifdef SK_DEBUG
// Ensure that we can create an SkCodec from this data.
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(fData));
diff --git a/bench/CodecBenchPriv.h b/bench/CodecBenchPriv.h
new file mode 100644
index 0000000000..d8585b6006
--- /dev/null
+++ b/bench/CodecBenchPriv.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef CodecBenchPriv_DEFINED
+#define CodecBenchPriv_DEFINED
+
+#include "SkImageInfo.h"
+
+inline const char* color_type_to_str(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 // CodecBenchPriv_DEFINED
diff --git a/bench/DecodingBench.cpp b/bench/DecodingBench.cpp
index 421cabe34a..7b6ad2bb0a 100644
--- a/bench/DecodingBench.cpp
+++ b/bench/DecodingBench.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+#include "CodecBenchPriv.h"
#include "DecodingBench.h"
#include "SkBitmap.h"
#include "SkData.h"
@@ -25,21 +26,7 @@ DecodingBench::DecodingBench(SkString path, SkColorType colorType)
{
// Parse filename and the color type to give the benchmark a useful name
SkString baseName = SkOSPath::Basename(path.c_str());
- const char* colorName;
- switch(colorType) {
- case kN32_SkColorType:
- colorName = "N32";
- break;
- case kRGB_565_SkColorType:
- colorName = "565";
- break;
- case kAlpha_8_SkColorType:
- colorName = "Alpha8";
- break;
- default:
- colorName = "Unknown";
- }
- fName.printf("Decode_%s_%s", baseName.c_str(), colorName);
+ fName.printf("Decode_%s_%s", baseName.c_str(), color_type_to_str(colorType));
#ifdef SK_DEBUG
// Ensure that we can create a decoder.
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index e7019dcb8c..a1db0acd80 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -10,7 +10,9 @@
#include "nanobench.h"
#include "Benchmark.h"
+#include "BitmapRegionDecoderBench.h"
#include "CodecBench.h"
+#include "CodecBenchPriv.h"
#include "CrashHandler.h"
#include "DecodingBench.h"
#include "GMBench.h"
@@ -19,13 +21,13 @@
#include "RecordingBench.h"
#include "SKPAnimationBench.h"
#include "SKPBench.h"
-#include "SubsetBenchPriv.h"
#include "SubsetSingleBench.h"
#include "SubsetTranslateBench.h"
#include "SubsetZoomBench.h"
#include "Stats.h"
#include "Timer.h"
+#include "SkBitmapRegionDecoderInterface.h"
#include "SkBBoxHierarchy.h"
#include "SkCanvas.h"
#include "SkCodec.h"
@@ -525,7 +527,7 @@ static bool valid_subset_bench(const SkString& path, SkColorType colorType, bool
colors, &colorCount) != SkCodec::kSuccess)
{
SkDebugf("Could not create scanline decoder for %s with color type %s. "
- "Skipping bench.\n", path.c_str(), get_color_name(colorType));
+ "Skipping bench.\n", path.c_str(), color_type_to_str(colorType));
return false;
}
*width = info.width();
@@ -539,7 +541,7 @@ static bool valid_subset_bench(const SkString& path, SkColorType colorType, bool
//FIXME: See skbug.com/3921
if (kIndex_8_SkColorType == colorType || kGray_8_SkColorType == colorType) {
SkDebugf("Cannot use image subset decoder for %s with color type %s. "
- "Skipping bench.\n", path.c_str(), get_color_name(colorType));
+ "Skipping bench.\n", path.c_str(), color_type_to_str(colorType));
return false;
}
if (!decoder->buildTileIndex(stream.detach(), width, height)) {
@@ -557,6 +559,38 @@ static bool valid_subset_bench(const SkString& path, SkColorType colorType, bool
return true;
}
+static bool valid_brd_bench(SkData* encoded, SkBitmapRegionDecoderInterface::Strategy strategy,
+ SkColorType colorType, uint32_t sampleSize, uint32_t minOutputSize, int* width,
+ int* height) {
+ SkStreamRewindable* stream = new SkMemoryStream(encoded);
+ SkAutoTDelete<SkBitmapRegionDecoderInterface> brd(
+ SkBitmapRegionDecoderInterface::CreateBitmapRegionDecoder(stream, strategy));
+ if (nullptr == brd.get()) {
+ // This is indicates that subset decoding is not supported for a particular image format.
+ return false;
+ }
+
+ SkAutoTDelete<SkBitmap> bitmap(brd->decodeRegion(0, 0, brd->width(), brd->height(), 1,
+ colorType));
+ if (nullptr == bitmap.get() || colorType != bitmap->colorType()) {
+ // This indicates that conversion to the requested color type is not supported for the
+ // particular image.
+ return false;
+ }
+
+ if (sampleSize * minOutputSize > (uint32_t) brd->width() || sampleSize * minOutputSize >
+ (uint32_t) brd->height()) {
+ // This indicates that the image is not large enough to decode a
+ // minOutputSize x minOutputSize subset at the given sampleSize.
+ return false;
+ }
+
+ // Set the image width and height. The calling code will use this to choose subsets to decode.
+ *width = brd->width();
+ *height = brd->height();
+ return true;
+}
+
static void cleanup_run(Target* target) {
delete target;
#if SK_SUPPORT_GPU
@@ -580,9 +614,12 @@ public:
, fCurrentCodec(0)
, fCurrentImage(0)
, fCurrentSubsetImage(0)
+ , fCurrentBRDImage(0)
, fCurrentColorType(0)
, fCurrentSubsetType(0)
, fUseCodec(0)
+ , fCurrentBRDStrategy(0)
+ , fCurrentBRDSampleSize(0)
, fCurrentAnimSKP(0) {
for (int i = 0; i < FLAGS_skps.count(); i++) {
if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
@@ -876,6 +913,97 @@ public:
fUseCodec++;
}
+ // Run the BRDBenches
+ // We will benchmark multiple BRD strategies.
+ const SkBitmapRegionDecoderInterface::Strategy strategies[] = {
+ SkBitmapRegionDecoderInterface::kOriginal_Strategy,
+ SkBitmapRegionDecoderInterface::kCanvas_Strategy,
+ };
+
+ // We intend to create benchmarks that model the use cases in
+ // android/libraries/social/tiledimage. In this library, an image is decoded in 512x512
+ // tiles. The image can be translated freely, so the location of a tile may be anywhere in
+ // the image. For that reason, we will benchmark decodes in five representative locations
+ // in the image. Additionally, this use case utilizes power of two scaling, so we will
+ // test on power of two sample sizes. The output tile is always 512x512, so, when a
+ // sampleSize is used, the size of the subset that is decoded is always
+ // (sampleSize*512)x(sampleSize*512).
+ // There are a few good reasons to only test on power of two sample sizes at this time:
+ // JPEG decodes using kOriginal_Strategy are broken for non-powers of two.
+ // skbug.com/4319
+ // All use cases we are aware of only scale by powers of two.
+ // PNG decodes use the indicated sampling strategy regardless of the sample size, so
+ // these tests are sufficient to provide good coverage of our scaling options.
+ const uint32_t sampleSizes[] = { 1, 2, 4, 8, 16 };
+ const uint32_t minOutputSize = 512;
+ while (fCurrentBRDImage < fImages.count()) {
+ while (fCurrentBRDStrategy < (int) SK_ARRAY_COUNT(strategies)) {
+ while (fCurrentColorType < fColorTypes.count()) {
+ while (fCurrentBRDSampleSize < (int) SK_ARRAY_COUNT(sampleSizes)) {
+ while (fCurrentSubsetType <= kLastSingle_SubsetType) {
+ const SkString& path = fImages[fCurrentBRDImage];
+ const SkBitmapRegionDecoderInterface::Strategy strategy =
+ strategies[fCurrentBRDStrategy];
+ SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str()));
+ const SkColorType colorType = fColorTypes[fCurrentColorType];
+ uint32_t sampleSize = sampleSizes[fCurrentBRDSampleSize];
+ int currentSubsetType = fCurrentSubsetType++;
+
+ int width = 0;
+ int height = 0;
+ if (!valid_brd_bench(encoded.get(), strategy, colorType, sampleSize,
+ minOutputSize, &width, &height)) {
+ break;
+ }
+
+ SkString basename = SkOSPath::Basename(path.c_str());
+ SkIRect subset;
+ const uint32_t subsetSize = sampleSize * minOutputSize;
+ switch (currentSubsetType) {
+ case kTopLeft_SubsetType:
+ basename.append("_TopLeft");
+ subset = SkIRect::MakeXYWH(0, 0, subsetSize, subsetSize);
+ break;
+ case kTopRight_SubsetType:
+ basename.append("_TopRight");
+ subset = SkIRect::MakeXYWH(width - subsetSize, 0, subsetSize,
+ subsetSize);
+ break;
+ case kMiddle_SubsetType:
+ basename.append("_Middle");
+ subset = SkIRect::MakeXYWH((width - subsetSize) / 2,
+ (height - subsetSize) / 2, subsetSize, subsetSize);
+ break;
+ case kBottomLeft_SubsetType:
+ basename.append("_BottomLeft");
+ subset = SkIRect::MakeXYWH(0, height - subsetSize, subsetSize,
+ subsetSize);
+ break;
+ case kBottomRight_SubsetType:
+ basename.append("_BottomRight");
+ subset = SkIRect::MakeXYWH(width - subsetSize,
+ height - subsetSize, subsetSize, subsetSize);
+ break;
+ default:
+ SkASSERT(false);
+ }
+
+ return new BitmapRegionDecoderBench(basename.c_str(), encoded.get(),
+ strategy, colorType, sampleSize, subset);
+ }
+ fCurrentSubsetType = 0;
+ fCurrentBRDSampleSize++;
+ }
+ fCurrentBRDSampleSize = 0;
+ fCurrentColorType++;
+ }
+ fCurrentColorType = 0;
+ fCurrentBRDStrategy++;
+ }
+ fCurrentBRDStrategy = 0;
+ fCurrentBRDImage++;
+ }
+
return nullptr;
}
@@ -907,7 +1035,8 @@ private:
kBottomRight_SubsetType = 4,
kTranslate_SubsetType = 5,
kZoom_SubsetType = 6,
- kLast_SubsetType = kZoom_SubsetType
+ kLast_SubsetType = kZoom_SubsetType,
+ kLastSingle_SubsetType = kBottomRight_SubsetType,
};
const BenchRegistry* fBenches;
@@ -932,9 +1061,12 @@ private:
int fCurrentCodec;
int fCurrentImage;
int fCurrentSubsetImage;
+ int fCurrentBRDImage;
int fCurrentColorType;
int fCurrentSubsetType;
int fUseCodec;
+ int fCurrentBRDStrategy;
+ int fCurrentBRDSampleSize;
int fCurrentAnimSKP;
};
diff --git a/bench/subset/SubsetBenchPriv.h b/bench/subset/SubsetBenchPriv.h
index 02f7040a22..7e1dfb9530 100644
--- a/bench/subset/SubsetBenchPriv.h
+++ b/bench/subset/SubsetBenchPriv.h
@@ -13,26 +13,6 @@
#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";
- }
-}
-
-/*
* If we plan to decode to kIndex8, we must create a color table and pass it to the
* bitmap when we allocate pixels. Otherwise, we simply allocate pixels using the
* decode info.
diff --git a/bench/subset/SubsetSingleBench.cpp b/bench/subset/SubsetSingleBench.cpp
index ce00f20947..2e5703f508 100644
--- a/bench/subset/SubsetSingleBench.cpp
+++ b/bench/subset/SubsetSingleBench.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+#include "CodecBenchPriv.h"
#include "SubsetSingleBench.h"
#include "SubsetBenchPriv.h"
#include "SkData.h"
@@ -39,7 +40,7 @@ SubsetSingleBench::SubsetSingleBench(const SkString& path,
SkString baseName = SkOSPath::Basename(path.c_str());
// Choose an informative color name
- const char* colorName = get_color_name(fColorType);
+ const char* colorName = color_type_to_str(fColorType);
fName.printf("%sSubsetSingle_%dx%d +%d_+%d_%s_%s", fUseCodec ? "Codec" : "Image", fSubsetWidth,
fSubsetHeight, fOffsetLeft, fOffsetTop, baseName.c_str(), colorName);
diff --git a/bench/subset/SubsetTranslateBench.cpp b/bench/subset/SubsetTranslateBench.cpp
index 8f6f2ea21b..bed3580853 100644
--- a/bench/subset/SubsetTranslateBench.cpp
+++ b/bench/subset/SubsetTranslateBench.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+#include "CodecBenchPriv.h"
#include "SubsetTranslateBench.h"
#include "SubsetBenchPriv.h"
#include "SkData.h"
@@ -35,7 +36,7 @@ SubsetTranslateBench::SubsetTranslateBench(const SkString& path,
SkString baseName = SkOSPath::Basename(path.c_str());
// Choose an informative color name
- const char* colorName = get_color_name(fColorType);
+ const char* colorName = color_type_to_str(fColorType);
fName.printf("%sSubsetTranslate_%dx%d_%s_%s", fUseCodec ? "Codec" : "Image", fSubsetWidth,
fSubsetHeight, baseName.c_str(), colorName);
diff --git a/bench/subset/SubsetZoomBench.cpp b/bench/subset/SubsetZoomBench.cpp
index bbdca75a54..655285fdf8 100644
--- a/bench/subset/SubsetZoomBench.cpp
+++ b/bench/subset/SubsetZoomBench.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+#include "CodecBenchPriv.h"
#include "SubsetZoomBench.h"
#include "SubsetBenchPriv.h"
#include "SkData.h"
@@ -35,7 +36,7 @@ SubsetZoomBench::SubsetZoomBench(const SkString& path,
SkString baseName = SkOSPath::Basename(path.c_str());
// Choose an informative color name
- const char* colorName = get_color_name(fColorType);
+ const char* colorName = color_type_to_str(fColorType);
fName.printf("%sSubsetZoom_%dx%d_%s_%s", fUseCodec ? "Codec" : "Image", fSubsetWidth,
fSubsetHeight, baseName.c_str(), colorName);
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 73dbc27e56..f70c81a943 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -14,6 +14,7 @@
#include "SkBBHFactory.h"
#include "SkChecksum.h"
#include "SkCodec.h"
+#include "SkCodecTools.h"
#include "SkCommonFlags.h"
#include "SkFontMgr.h"
#include "SkForceLinking.h"
@@ -396,7 +397,7 @@ static void push_brd_src(Path path, SkBitmapRegionDecoderInterface::Strategy str
}
if (1 != sampleSize) {
- folder.appendf("_%.3f", BRDSrc::GetScale(sampleSize));
+ folder.appendf("_%.3f", get_scale_from_sample_size(sampleSize));
}
BRDSrc* src = new BRDSrc(path, strategy, mode, dstColorType, sampleSize);
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 981e47d6c0..10cdd0965b 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -8,6 +8,7 @@
#include "DMSrcSink.h"
#include "SamplePipeControllers.h"
#include "SkCodec.h"
+#include "SkCodecTools.h"
#include "SkCommonFlags.h"
#include "SkData.h"
#include "SkDocument.h"
@@ -216,7 +217,7 @@ Name BRDSrc::name() const {
if (1 == fSampleSize) {
return SkOSPath::Basename(fPath.c_str());
}
- return get_scaled_name(fPath, BRDSrc::GetScale(fSampleSize));
+ return get_scaled_name(fPath, get_scale_from_sample_size(fSampleSize));
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h
index fe6c91dfad..9e0ef49651 100644
--- a/dm/DMSrcSink.h
+++ b/dm/DMSrcSink.h
@@ -144,8 +144,6 @@ public:
BRDSrc(Path, SkBitmapRegionDecoderInterface::Strategy, Mode, CodecSrc::DstColorType, uint32_t);
- static float GetScale(uint32_t sampleSize) { return 1.0f / (float) sampleSize; }
-
Error draw(SkCanvas*) const override;
SkISize size() const override;
Name name() const override;
diff --git a/gyp/bench.gypi b/gyp/bench.gypi
index e102a97f1b..95073b0fba 100644
--- a/gyp/bench.gypi
+++ b/gyp/bench.gypi
@@ -18,6 +18,7 @@
'dependencies': [
'etc1.gyp:libetc1',
'skia_lib.gyp:skia_lib',
+ 'tools.gyp:bitmap_region_decoder',
'tools.gyp:resources',
'tools.gyp:sk_tool_utils',
],
diff --git a/gyp/visualbench.gyp b/gyp/visualbench.gyp
index 43816ee872..8dea597ef8 100644
--- a/gyp/visualbench.gyp
+++ b/gyp/visualbench.gyp
@@ -38,6 +38,7 @@
'jsoncpp.gyp:jsoncpp',
'gputest.gyp:skgputest',
'skia_lib.gyp:skia_lib',
+ 'tools.gyp:bitmap_region_decoder',
'tools.gyp:proc_stats',
'tools.gyp:sk_tool_utils',
'tools.gyp:timer',
diff --git a/tools/SkCodecTools.h b/tools/SkCodecTools.h
new file mode 100644
index 0000000000..097915b5d7
--- /dev/null
+++ b/tools/SkCodecTools.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkCodecTools_DEFINED
+#define SkCodecTools_DEFINED
+
+inline float get_scale_from_sample_size(uint32_t sampleSize) {
+ return 1.0f / (float) sampleSize;
+}
+
+#endif // SkCodecTools_DEFINED