1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkBenchmark.h" 9 #include "SkBitmap.h" 10 #include "SkData.h" 11 #include "SkForceLinking.h" 12 #include "SkImageDecoder.h" 13 #include "SkOSFile.h" 14 #include "SkStream.h" 15 #include "SkString.h" 16 17 __SK_FORCE_IMAGE_DECODER_LINKING; 18 19 class SkCanvas; 20 21 class SkipZeroesBench : public SkBenchmark { 22 public: 23 SkipZeroesBench(const char* filename, bool skipZeroes) 24 : fName("SkipZeroes_") 25 , fDecoder(NULL) 26 , fFilename(filename) 27 , fStream() 28 , fSkipZeroes(skipZeroes) 29 , fValid(false) { 30 fName.append(filename); 31 if (skipZeroes) { 32 fName.append("_skip_zeroes"); 33 } else { 34 fName.append("_write_zeroes"); 35 } 36 } 37 38 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { 39 return backend == kNonRendering_Backend; 40 } 41 42 protected: 43 virtual const char* onGetName() SK_OVERRIDE { 44 return fName.c_str(); 45 } 46 47 virtual void onPreDraw() SK_OVERRIDE { 48 const char* resPath = GetResourcePath().c_str(); 49 if (NULL == resPath) { 50 fValid = false; 51 return; 52 } 53 54 SkString fullPath = SkOSPath::SkPathJoin(resPath, fFilename.c_str()); 55 SkFILEStream fileStream(fullPath.c_str()); 56 fValid = fileStream.isValid() && fileStream.getLength() > 0; 57 if (fValid) { 58 const size_t size = fileStream.getLength(); 59 void* data = sk_malloc_throw(size); 60 if (fileStream.read(data, size) < size) { 61 fValid = false; 62 } else { 63 SkAutoTUnref<SkData> skdata(SkData::NewFromMalloc(data, size)); 64 fStream.setData(skdata.get()); 65 fDecoder.reset(SkImageDecoder::Factory(&fStream)); 66 if (fDecoder.get()) { 67 fDecoder->setSkipWritingZeroes(fSkipZeroes); 68 } else { 69 fValid = false; 70 } 71 } 72 } 73 } 74 75 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { 76 if (!fValid) { 77 #ifdef SK_DEBUG 78 SkDebugf("stream was invalid: %s\n", fFilename.c_str()); 79 #endif 80 return; 81 } 82 // Decode a bunch of times 83 SkBitmap bm; 84 for (int i = 0; i < loops; ++i) { 85 SkDEBUGCODE(bool success =) fDecoder->decode(&fStream, &bm, 86 SkImageDecoder::kDecodePixels_Mode); 87 #ifdef SK_DEBUG 88 if (!success) { 89 SkDebugf("failed to decode %s\n", fFilename.c_str()); 90 return; 91 } 92 #endif 93 SkDEBUGCODE(success =) fStream.rewind(); 94 #ifdef SK_DEBUG 95 if (!success) { 96 SkDebugf("failed to rewind %s\n", fFilename.c_str()); 97 return; 98 } 99 #endif 100 } 101 } 102 103 private: 104 SkString fName; 105 SkAutoTDelete<SkImageDecoder> fDecoder; 106 const SkString fFilename; 107 SkMemoryStream fStream; 108 bool fSkipZeroes; 109 bool fValid; 110 111 typedef SkBenchmark INHERITED; 112 }; 113 114 // Enable the true version once the feature is checked in. 115 DEF_BENCH( return SkNEW_ARGS(SkipZeroesBench, ("arrow.png", true))); 116 DEF_BENCH( return SkNEW_ARGS(SkipZeroesBench, ("arrow.png", false))); 117