2a1208017d
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
118 lines
3.4 KiB
C++
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)));
|