| /* | |
| * 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(bool success =) fDecoder->decode(&fStream, &bm, | |
| SkImageDecoder::kDecodePixels_Mode); | |
| #ifdef SK_DEBUG | |
| if (!success) { | |
| SkDebugf("failed to decode %s\n", fFilename.c_str()); | |
| return; | |
| } | |
| #endif | |
| SkDEBUGCODE(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))); |