+++ /dev/null
-
-/*
- * Copyright 2011 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 "SkBitmap.h"
-#include "SkCommandLineFlags.h"
-#include "SkImageDecoder.h"
-#include "SkOSFile.h"
-#include "SkString.h"
-#include "sk_tool_utils.h"
-
-DEFINE_string(decodeBenchFilename, "resources/CMYK.jpeg", "Path to image for DecodeBench.");
-
-class DecodeBench : public Benchmark {
- const SkColorType fPrefColorType;
- SkString fName;
-public:
- DecodeBench(SkColorType ct) : fPrefColorType(ct) {
- SkString fname = SkOSPath::Basename(FLAGS_decodeBenchFilename[0]);
- fName.printf("decode_%s_%s", sk_tool_utils::colortype_name(ct), fname.c_str());
- }
-
- bool isSuitableFor(Backend backend) SK_OVERRIDE {
- return backend == kNonRendering_Backend;
- }
-
-protected:
- virtual const char* onGetName() {
- return fName.c_str();
- }
-
- virtual void onDraw(const int loops, SkCanvas*) {
- for (int i = 0; i < loops; i++) {
- SkBitmap bm;
- SkImageDecoder::DecodeFile(FLAGS_decodeBenchFilename[0], &bm, fPrefColorType,
- SkImageDecoder::kDecodePixels_Mode);
- }
- }
-
-private:
- typedef Benchmark INHERITED;
-};
-
-DEF_BENCH( return new DecodeBench(kN32_SkColorType); )
-DEF_BENCH( return new DecodeBench(kRGB_565_SkColorType); )
-DEF_BENCH( return new DecodeBench(kARGB_4444_SkColorType); )
--- /dev/null
+/*
+ * 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 "DecodingBench.h"
+#include "SkData.h"
+#include "SkImageDecoder.h"
+#include "SkOSFile.h"
+#include "SkStream.h"
+
+/*
+ *
+ * This benchmark is designed to test the performance of image decoding.
+ * It is invoked from the nanobench.cpp file.
+ *
+ */
+DecodingBench::DecodingBench(SkString path, SkColorType colorType)
+ : fColorType(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);
+
+ // Perform setup for the decode
+ SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str()));
+ fStream.reset(new SkMemoryStream(encoded));
+ fDecoder.reset(SkImageDecoder::Factory(fStream.get()));
+}
+
+const char* DecodingBench::onGetName() {
+ return fName.c_str();
+}
+
+bool DecodingBench::isSuitableFor(Backend backend) {
+ return kNonRendering_Backend == backend;
+}
+
+void DecodingBench::onDraw(const int n, SkCanvas* canvas) {
+ SkBitmap bitmap;
+ for (int i = 0; i < n; i++) {
+ fStream->rewind();
+ fDecoder->decode(fStream, &bitmap, fColorType,
+ SkImageDecoder::kDecodePixels_Mode);
+ }
+}
--- /dev/null
+/*
+ * 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 image decoding.
+ * It is invoked from the nanobench.cpp file.
+ *
+ */
+class DecodingBench : public Benchmark {
+public:
+ DecodingBench(SkString path, SkColorType colorType);
+
+protected:
+ const char* onGetName() SK_OVERRIDE;
+ bool isSuitableFor(Backend backend) SK_OVERRIDE;
+ void onDraw(const int n, SkCanvas* canvas) SK_OVERRIDE;
+
+private:
+ SkString fName;
+ SkColorType fColorType;
+ SkAutoTDelete<SkMemoryStream> fStream;
+ SkAutoTDelete<SkImageDecoder> fDecoder;
+ typedef Benchmark INHERITED;
+};
--- /dev/null
+/*
+ * 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 "DecodingSubsetBench.h"
+#include "SkData.h"
+#include "SkImageDecoder.h"
+#include "SkOSFile.h"
+#include "SkStream.h"
+
+/*
+ *
+ * This benchmark is designed to test the performance of image subset decoding.
+ * It is invoked from the nanobench.cpp file.
+ *
+ */
+DecodingSubsetBench::DecodingSubsetBench(SkString path, SkColorType colorType,
+ const int divisor)
+ : fColorType(colorType)
+ , fDivisor(divisor)
+{
+ // 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("DecodeSubset_%dx%d_%s_%s", fDivisor, fDivisor,
+ baseName.c_str(), colorName);
+
+ // Perform the decode setup
+ SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str()));
+ fStream.reset(new SkMemoryStream(encoded));
+ fDecoder.reset(SkImageDecoder::Factory(fStream));
+}
+
+const char* DecodingSubsetBench::onGetName() {
+ return fName.c_str();
+}
+
+bool DecodingSubsetBench::isSuitableFor(Backend backend) {
+ return kNonRendering_Backend == backend;
+}
+
+void DecodingSubsetBench::onDraw(const int n, SkCanvas* canvas) {
+ for (int i = 0; i < n; i++) {
+ int w, h;
+ fDecoder->buildTileIndex(fStream->duplicate(), &w, &h);
+ // Divide the image into subsets and decode each subset
+ const int sW = w / fDivisor;
+ const int sH = h / fDivisor;
+ for (int y = 0; y < h; y += sH) {
+ for (int x = 0; x < w; x += sW) {
+ SkBitmap bitmap;
+ SkIRect rect = SkIRect::MakeXYWH(x, y, sW, sH);
+ fDecoder->decodeSubset(&bitmap, rect, fColorType);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * 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 image subset decoding.
+ * It is invoked from the nanobench.cpp file.
+ *
+ */
+class DecodingSubsetBench : public Benchmark {
+public:
+ DecodingSubsetBench(SkString path, SkColorType colorType,
+ const int divisor);
+
+protected:
+ const char* onGetName() SK_OVERRIDE;
+ bool isSuitableFor(Backend backend) SK_OVERRIDE;
+ void onDraw(const int n, SkCanvas* canvas) SK_OVERRIDE;
+
+private:
+ SkString fName;
+ SkColorType fColorType;
+ const int fDivisor;
+ SkAutoTDelete<SkMemoryStream> fStream;
+ SkAutoTDelete<SkImageDecoder> fDecoder;
+ typedef Benchmark INHERITED;
+};
+++ /dev/null
-/*
- * Copyright 2013 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 "SkBitmap.h"
-#include "SkData.h"
-#include "SkForceLinking.h"
-#include "SkImageDecoder.h"
-#include "SkOSFile.h"
-#include "SkStream.h"
-#include "SkString.h"
-
-__SK_FORCE_IMAGE_DECODER_LINKING;
-
-class SkCanvas;
-
-class ImageDecodeBench : public Benchmark {
-public:
- ImageDecodeBench(void* p, const char* filename)
- : fName("image_decode_")
- , fFilename(filename)
- , fStream()
- , fValid(false) {
- fName.append(SkOSPath::Basename(filename));
- }
-
- bool isSuitableFor(Backend backend) SK_OVERRIDE {
- return backend == kNonRendering_Backend;
- }
-
-protected:
- const char* onGetName() SK_OVERRIDE {
- return fName.c_str();
- }
-
- void onPreDraw() SK_OVERRIDE {
- SkFILEStream fileStream(fFilename.c_str());
- fValid = fileStream.isValid() && fileStream.getLength() > 0;
- if (fValid) {
- const size_t size = fileStream.getLength();
- void* data = sk_malloc_throw(size);
- if (fileStream.read(data, size) < size) {
- fValid = false;
- } else {
- SkAutoTUnref<SkData> skdata(SkData::NewFromMalloc(data, size));
- fStream.setData(skdata.get());
- }
- }
- }
-
- void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
-#ifdef SK_DEBUG
- if (!fValid) {
- SkDebugf("stream was invalid: %s\n", fName.c_str());
- return;
- }
-#endif
- // Decode a bunch of times
- SkBitmap bm;
- for (int i = 0; i < loops; ++i) {
- SkDEBUGCODE(bool success =) SkImageDecoder::DecodeStream(&fStream, &bm);
-#ifdef SK_DEBUG
- if (!success) {
- SkDebugf("failed to decode %s\n", fName.c_str());
- return;
- }
-#endif
- SkDEBUGCODE(success =) fStream.rewind();
-#ifdef SK_DEBUG
- if (!success) {
- SkDebugf("failed to rewind %s\n", fName.c_str());
- return;
- }
-#endif
- }
- }
-
-private:
- SkString fName;
- const SkString fFilename;
- SkMemoryStream fStream;
- bool fValid;
-
- typedef Benchmark INHERITED;
-};
-
-// These are files which call decodePalette
-//DEF_BENCH( return SkNEW_ARGS(ImageDecodeBench, ("/usr/local/google/home/scroggo/Downloads/images/hal_163x90.png")); )
-//DEF_BENCH( return SkNEW_ARGS(ImageDecodeBench, ("/usr/local/google/home/scroggo/Downloads/images/box_19_top-left.png")); )
#include "Benchmark.h"
#include "CrashHandler.h"
+#include "DecodingBench.h"
+#include "DecodingSubsetBench.h"
#include "GMBench.h"
#include "ProcStats.h"
#include "ResultsWriter.h"
#include "SkBBoxHierarchy.h"
#include "SkCanvas.h"
#include "SkCommonFlags.h"
+#include "SkData.h"
#include "SkForceLinking.h"
#include "SkGraphics.h"
#include "SkOSFile.h"
, fCurrentRecording(0)
, fCurrentScale(0)
, fCurrentSKP(0)
- , fCurrentUseMPD(0) {
+ , fCurrentUseMPD(0)
+ , fCurrentImage(0)
+ , fCurrentSubsetImage(0)
+ , fCurrentColorType(0)
+ , fDivisor(2) {
for (int i = 0; i < FLAGS_skps.count(); i++) {
if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
fSKPs.push_back() = FLAGS_skps[i];
if (FLAGS_mpd) {
fUseMPDs.push_back() = true;
}
+
+ // Prepare the images for decoding
+ for (int i = 0; i < FLAGS_images.count(); i++) {
+ const char* flag = FLAGS_images[i];
+ if (sk_isdir(flag)) {
+ // If the value passed in is a directory, add all the images
+ SkOSFile::Iter it(flag);
+ SkString file;
+ while (it.next(&file)) {
+ fImages.push_back() = SkOSPath::Join(flag, file.c_str());
+ }
+ } else if (sk_exists(flag)) {
+ // Also add the value if it is a single image
+ fImages.push_back() = flag;
+ }
+ }
+
+ // Choose the candidate color types for image decoding
+ const SkColorType colorTypes[] =
+ { kN32_SkColorType, kRGB_565_SkColorType, kAlpha_8_SkColorType };
+ fColorTypes.push_back_n(SK_ARRAY_COUNT(colorTypes), colorTypes);
}
static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) {
fCurrentScale++;
}
+ // Run the DecodingBenches
+ while (fCurrentImage < fImages.count()) {
+ while (fCurrentColorType < fColorTypes.count()) {
+ const SkString& path = fImages[fCurrentImage];
+ SkColorType colorType = fColorTypes[fCurrentColorType];
+ fCurrentColorType++;
+ // Check if the image decodes before creating the benchmark
+ SkBitmap bitmap;
+ if (SkImageDecoder::DecodeFile(path.c_str(), &bitmap,
+ colorType, SkImageDecoder::kDecodePixels_Mode)) {
+ return new DecodingBench(path, colorType);
+ }
+ }
+ fCurrentColorType = 0;
+ fCurrentImage++;
+ }
+
+ // Run the DecodingSubsetBenches
+ while (fCurrentSubsetImage < fImages.count()) {
+ while (fCurrentColorType < fColorTypes.count()) {
+ const SkString& path = fImages[fCurrentSubsetImage];
+ SkColorType colorType = fColorTypes[fCurrentColorType];
+ fCurrentColorType++;
+ // Check if the image decodes before creating the benchmark
+ SkAutoTUnref<SkData> encoded(
+ SkData::NewFromFileName(path.c_str()));
+ SkAutoTDelete<SkMemoryStream> stream(
+ new SkMemoryStream(encoded));
+ SkAutoTDelete<SkImageDecoder>
+ decoder(SkImageDecoder::Factory(stream.get()));
+ if (!decoder) {
+ SkDebugf("Cannot find decoder for %s\n", path.c_str());
+ } else {
+ stream->rewind();
+ int w, h;
+ bool success;
+ if (!decoder->buildTileIndex(stream.detach(), &w, &h)
+ || w*h == 1) {
+ // This is not an error, but in this case we still
+ // do not want to run the benchmark.
+ success = false;
+ } else if (fDivisor > w || fDivisor > h) {
+ SkDebugf("Divisor %d is too big for %s %dx%d\n",
+ fDivisor, path.c_str(), w, h);
+ success = false;
+ } else {
+ const int sW = w / fDivisor;
+ const int sH = h / fDivisor;
+ SkBitmap bitmap;
+ success = true;
+ for (int y = 0; y < h; y += sH) {
+ for (int x = 0; x < w; x += sW) {
+ SkIRect rect = SkIRect::MakeXYWH(x, y, sW, sH);
+ success &= decoder->decodeSubset(&bitmap, rect,
+ colorType);
+ }
+ }
+ }
+ // Create the benchmark if successful
+ if (success) {
+ return new DecodingSubsetBench(path, colorType,
+ fDivisor);
+ }
+ }
+ }
+ fCurrentColorType = 0;
+ fCurrentSubsetImage++;
+ }
+
return NULL;
}
SkTArray<SkScalar> fScales;
SkTArray<SkString> fSKPs;
SkTArray<bool> fUseMPDs;
+ SkTArray<SkString> fImages;
+ SkTArray<SkColorType> fColorTypes;
double fSKPBytes, fSKPOps;
int fCurrentScale;
int fCurrentSKP;
int fCurrentUseMPD;
+ int fCurrentImage;
+ int fCurrentSubsetImage;
+ int fCurrentColorType;
+ const int fDivisor;
};
int nanobench_main();
#include "Test.h"
#include "Timer.h"
-DEFINE_string(images, "resources", "Images to decode.");
DEFINE_string(src, "tests gm skp image subset", "Source types to test.");
DEFINE_bool(nameByHash, false,
"If true, write to FLAGS_writePath[0]/<hash>.png instead of "
'type': 'executable',
'sources': [
'../gm/gm.cpp',
+ '../bench/DecodingBench.cpp',
+ '../bench/DecodingSubsetBench.cpp',
'../bench/GMBench.cpp',
'../bench/RecordingBench.cpp',
'../bench/SKPBench.cpp',
'../bench/ColorPrivBench.cpp',
'../bench/CoverageBench.cpp',
'../bench/DashBench.cpp',
- '../bench/DecodeBench.cpp',
'../bench/DeferredSurfaceCopyBench.cpp',
'../bench/DisplacementBench.cpp',
'../bench/ETCBitmapBench.cpp',
'../bench/GradientBench.cpp',
'../bench/HairlinePathBench.cpp',
'../bench/ImageCacheBench.cpp',
- '../bench/ImageDecodeBench.cpp',
'../bench/ImageFilterDAGBench.cpp',
'../bench/ImageFilterCollapse.cpp',
'../bench/InterpBench.cpp',
'xml.gyp:xml',
],
'sources': [
+ '../bench/DecodingBench.cpp',
+ '../bench/DecodingSubsetBench.cpp',
'../bench/GMBench.cpp',
'../bench/RecordingBench.cpp',
'../bench/SKPBench.cpp',
"Defaults to empty string, which selects the API native to the "
"system.");
+DEFINE_string(images, "resources", "Directory of images to decode.");
+
DEFINE_bool2(leaks, l, false, "show leaked ref cnt'd objects.");
DEFINE_string2(match, m, NULL,
DECLARE_bool(dryRun);
DECLARE_bool(gpu);
DECLARE_string(gpuAPI);
+DECLARE_string(images);
DECLARE_bool(leaks);
DECLARE_string(match);
DECLARE_bool(quiet);