skia2/bench/SkipZeroesBench.cpp
scroggo 2a1208017d Qualify the return value of SkImageDecoder::decode
Add a new enum to differentiate between a complete decode and a
partial decode (with the third value being failure). Return this
value from SkImageDecoder::onDecode (in all subclasses, plus
SkImageDecoder_empty) and ::decode.

For convenience, if the enum is treated as a boolean, success and
partial success are both considered true.

Note that the static helper functions (DecodeFile etc) still return
true and false (for one thing, this allows us to continue to use
SkImageDecoder::DecodeMemory as an SkPicture::InstallPixelRefProc in
SkPicture::CreateFromStream).

Also correctly report failure in SkASTCImageDecoder::onDecode when
SkTextureCompressor::DecompressBufferFromFormat fails.

BUG=skia:3037
BUG:b/17419670

Review URL: https://codereview.chromium.org/647023006
2014-10-22 12:07:00 -07:00

118 lines
3.4 KiB
C++

/*
* 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 "Resources.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 SkipZeroesBench : public Benchmark {
public:
SkipZeroesBench(const char* filename, bool skipZeroes)
: fName("SkipZeroes_")
, fDecoder(NULL)
, fFilename(filename)
, fStream()
, fSkipZeroes(skipZeroes)
, fValid(false) {
fName.append(filename);
if (skipZeroes) {
fName.append("_skip_zeroes");
} else {
fName.append("_write_zeroes");
}
}
virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
return backend == kNonRendering_Backend;
}
protected:
virtual const char* onGetName() SK_OVERRIDE {
return fName.c_str();
}
virtual void onPreDraw() SK_OVERRIDE {
SkString resourcePath = GetResourcePath();
if (resourcePath.isEmpty()) {
fValid = false;
return;
}
SkString fullPath = SkOSPath::Join(resourcePath.c_str(), fFilename.c_str());
SkFILEStream fileStream(fullPath.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());
fDecoder.reset(SkImageDecoder::Factory(&fStream));
if (fDecoder.get()) {
fDecoder->setSkipWritingZeroes(fSkipZeroes);
} else {
fValid = false;
}
}
}
}
virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
if (!fValid) {
#ifdef SK_DEBUG
SkDebugf("stream was invalid: %s\n", fFilename.c_str());
#endif
return;
}
// Decode a bunch of times
SkBitmap bm;
for (int i = 0; i < loops; ++i) {
SkDEBUGCODE(SkImageDecoder::Result result =) fDecoder->decode(&fStream, &bm,
SkImageDecoder::kDecodePixels_Mode);
#ifdef SK_DEBUG
if (SkImageDecoder::kFailure == result) {
SkDebugf("failed to decode %s\n", fFilename.c_str());
return;
}
#endif
SkDEBUGCODE(bool success =) fStream.rewind();
#ifdef SK_DEBUG
if (!success) {
SkDebugf("failed to rewind %s\n", fFilename.c_str());
return;
}
#endif
}
}
private:
SkString fName;
SkAutoTDelete<SkImageDecoder> fDecoder;
const SkString fFilename;
SkMemoryStream fStream;
bool fSkipZeroes;
bool fValid;
typedef Benchmark INHERITED;
};
// Enable the true version once the feature is checked in.
DEF_BENCH( return SkNEW_ARGS(SkipZeroesBench, ("arrow.png", true)));
DEF_BENCH( return SkNEW_ARGS(SkipZeroesBench, ("arrow.png", false)));