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