1 /* 2 * Copyright 2016 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 "SkData.h" 11 #include "SkImage.h" 12 #include "SkPDFBitmap.h" 13 #include "SkPixmap.h" 14 15 namespace { 16 struct NullWStream : public SkWStream { NullWStream__anona0cac82e0111::NullWStream17 NullWStream() : fN(0) {} write__anona0cac82e0111::NullWStream18 bool write(const void*, size_t n) override { fN += n; return true; } bytesWritten__anona0cac82e0111::NullWStream19 size_t bytesWritten() const override { return fN; } 20 size_t fN; 21 }; 22 test_pdf_object_serialization(SkPDFObject * object)23 static void test_pdf_object_serialization(SkPDFObject* object) { 24 // SkDebugWStream wStream; 25 NullWStream wStream; 26 SkPDFSubstituteMap substitutes; 27 SkPDFObjNumMap objNumMap; 28 objNumMap.addObjectRecursively(object, substitutes); 29 for (int i = 0; i < objNumMap.objects().count(); ++i) { 30 SkPDFObject* object = objNumMap.objects()[i]; 31 wStream.writeDecAsText(i + 1); 32 wStream.writeText(" 0 obj\n"); 33 object->emitObject(&wStream, objNumMap, substitutes); 34 wStream.writeText("\nendobj\n"); 35 } 36 } 37 38 class PDFImageBench : public Benchmark { 39 public: PDFImageBench()40 PDFImageBench() {} ~PDFImageBench()41 virtual ~PDFImageBench() {} 42 43 protected: onGetName()44 const char* onGetName() override { return "PDFImage"; } isSuitableFor(Backend backend)45 bool isSuitableFor(Backend backend) override { 46 return backend == kNonRendering_Backend; 47 } onDelayedSetup()48 void onDelayedSetup() override { 49 SkAutoTUnref<SkImage> img(GetResourceAsImage("color_wheel.png")); 50 if (img) { 51 // force decoding, throw away reference to encoded data. 52 SkAutoPixmapStorage pixmap; 53 pixmap.alloc(SkImageInfo::MakeN32Premul(img->dimensions())); 54 if (img->readPixels(pixmap, 0, 0)) { 55 fImage.reset(SkImage::NewRasterCopy( 56 pixmap.info(), pixmap.addr(), 57 pixmap.rowBytes(), pixmap.ctable())); 58 } 59 } 60 } onDraw(int loops,SkCanvas *)61 void onDraw(int loops, SkCanvas*) override { 62 if (!fImage) { 63 return; 64 } 65 while (loops-- > 0) { 66 SkAutoTUnref<SkPDFObject> object( 67 SkPDFCreateBitmapObject(fImage, nullptr)); 68 SkASSERT(object); 69 if (!object) { 70 return; 71 } 72 test_pdf_object_serialization(object); 73 } 74 } 75 76 private: 77 SkAutoTUnref<SkImage> fImage; 78 }; 79 80 class PDFJpegImageBench : public Benchmark { 81 public: PDFJpegImageBench()82 PDFJpegImageBench() {} ~PDFJpegImageBench()83 virtual ~PDFJpegImageBench() {} 84 85 protected: onGetName()86 const char* onGetName() override { return "PDFJpegImage"; } isSuitableFor(Backend backend)87 bool isSuitableFor(Backend backend) override { 88 return backend == kNonRendering_Backend; 89 } onDelayedSetup()90 void onDelayedSetup() override { 91 SkAutoTUnref<SkImage> img( 92 GetResourceAsImage("mandrill_512_q075.jpg")); 93 if (!img) { return; } 94 SkAutoTUnref<SkData> encoded(img->refEncoded()); 95 SkASSERT(encoded); 96 if (!encoded) { return; } 97 fImage.reset(img.release()); 98 } onDraw(int loops,SkCanvas *)99 void onDraw(int loops, SkCanvas*) override { 100 if (!fImage) { 101 SkDEBUGFAIL(""); 102 return; 103 } 104 while (loops-- > 0) { 105 SkAutoTUnref<SkPDFObject> object( 106 SkPDFCreateBitmapObject(fImage, nullptr)); 107 SkASSERT(object); 108 if (!object) { 109 return; 110 } 111 test_pdf_object_serialization(object); 112 } 113 } 114 115 private: 116 SkAutoTUnref<SkImage> fImage; 117 }; 118 119 /** Test calling DEFLATE on a 78k PDF command stream. Used for measuring 120 alternate zlib settings, usage, and library versions. */ 121 class PDFCompressionBench : public Benchmark { 122 public: PDFCompressionBench()123 PDFCompressionBench() {} ~PDFCompressionBench()124 virtual ~PDFCompressionBench() {} 125 126 protected: onGetName()127 const char* onGetName() override { return "PDFCompression"; } isSuitableFor(Backend backend)128 bool isSuitableFor(Backend backend) override { 129 return backend == kNonRendering_Backend; 130 } onDelayedSetup()131 void onDelayedSetup() override { 132 fAsset.reset(GetResourceAsStream("pdf_command_stream.txt")); 133 } onDraw(int loops,SkCanvas *)134 void onDraw(int loops, SkCanvas*) override { 135 SkASSERT(fAsset); 136 if (!fAsset) { return; } 137 while (loops-- > 0) { 138 SkAutoTUnref<SkPDFObject> object( 139 new SkPDFSharedStream(fAsset->duplicate())); 140 test_pdf_object_serialization(object); 141 } 142 } 143 144 private: 145 SkAutoTDelete<SkStreamAsset> fAsset; 146 }; 147 148 } // namespace 149 DEF_BENCH(return new PDFImageBench;) 150 DEF_BENCH(return new PDFJpegImageBench;) 151 DEF_BENCH(return new PDFCompressionBench;) 152