1 /* 2 * Copyright 2017 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 #if SK_SUPPORT_GPU 10 11 #include "GrContextOptions.h" 12 #include "SkCanvas.h" 13 #include "SkImage.h" 14 #include "SkRandom.h" 15 #include "SkSurface.h" 16 17 class MultitextureImages : public Benchmark { 18 public: MultitextureImages(int imageSize,int dstRectSize,bool disableMultitexturing,bool aa)19 MultitextureImages(int imageSize, int dstRectSize, bool disableMultitexturing, bool aa) 20 : fImageSize(imageSize) 21 , fDstRectSize(dstRectSize) 22 , fDisableMultitexturing(disableMultitexturing) 23 , fAA(aa) { 24 fName.appendf("multitexture_images_%dx%d_image_%dx%d_rect", imageSize, imageSize, 25 dstRectSize, dstRectSize); 26 if (aa) { 27 fName.append("_aa"); 28 } 29 if (disableMultitexturing) { 30 fName.append("_disable_multitexturing"); 31 } 32 } 33 isSuitableFor(Backend backend)34 bool isSuitableFor(Backend backend) override { return kGPU_Backend == backend; } 35 36 protected: onGetName()37 const char* onGetName() override { return fName.c_str(); } 38 onPerCanvasPreDraw(SkCanvas * canvas)39 void onPerCanvasPreDraw(SkCanvas* canvas) override { 40 auto ii = SkImageInfo::Make(fImageSize, fImageSize, kRGBA_8888_SkColorType, 41 kPremul_SkAlphaType, nullptr); 42 SkRandom random; 43 for (int i = 0; i < kNumImages; ++i) { 44 auto surf = canvas->makeSurface(ii); 45 SkColor color = random.nextU(); 46 surf->getCanvas()->clear(color); 47 SkPaint paint; 48 paint.setColor(~color); 49 paint.setBlendMode(SkBlendMode::kSrc); 50 surf->getCanvas()->drawRect(SkRect::MakeLTRB(3, 3, fImageSize - 3, fImageSize - 3), 51 paint); 52 fImages[i] = surf->makeImageSnapshot(); 53 } 54 } 55 onPerCanvasPostDraw(SkCanvas *)56 void onPerCanvasPostDraw(SkCanvas*) override { 57 for (int i = 0; i < kNumImages; ++i) { 58 fImages[i].reset(); 59 } 60 } 61 onDraw(int loops,SkCanvas * canvas)62 void onDraw(int loops, SkCanvas* canvas) override { 63 SkRect rect = SkRect::MakeWH(fDstRectSize, fDstRectSize); 64 SkPaint paint; 65 paint.setAlpha(0x40); 66 paint.setFilterQuality(kLow_SkFilterQuality); 67 paint.setAntiAlias(fAA); 68 for (int i = 0; i < loops; i++) { 69 for (int j = 0; j < kNumImages; ++j) { 70 SkVector translate = this->translation(i * kNumImages + j); 71 canvas->drawImageRect(fImages[j].get(), rect.makeOffset(translate.fX, translate.fY), 72 &paint); 73 } 74 // Prevent any batching except without multitexturing since we're trying to measure 75 // drawing distinct images and just repeating images here to increase the workload for 76 // timing reasons. 77 canvas->flush(); 78 } 79 } 80 modifyGrContextOptions(GrContextOptions * options)81 void modifyGrContextOptions(GrContextOptions* options) override { 82 options->fDisableImageMultitexturing = fDisableMultitexturing; 83 } 84 85 private: onGetSize()86 SkIPoint onGetSize() override { 87 // The rows and columns are spaced by kTranslate, but the images may overlap if they are 88 // larger than kTranslate and extend beyond the last row/column. 89 return SkIPoint::Make(kTranslate * (kNumColumns - 1) + fDstRectSize, 90 kTranslate * (kNumRows - 1) + fDstRectSize); 91 } 92 translation(int i) const93 SkVector translation(int i) const { 94 SkVector offset; 95 // Fractional offsets to ensure we can't ignore antialiasing. 96 offset.fX = i % kNumColumns * kTranslate + 0.1f; 97 offset.fY = (i / kNumColumns) % kNumRows * kTranslate + 0.1f; 98 return offset; 99 } 100 101 static const int kTranslate = 200; 102 static const int kNumColumns = 5; 103 static const int kNumRows = 5; 104 static const int kNumImages = 8; 105 106 sk_sp<SkImage> fImages[kNumImages]; 107 SkString fName; 108 int fImageSize; 109 int fDstRectSize; 110 bool fDisableMultitexturing; 111 bool fAA; 112 113 typedef Benchmark INHERITED; 114 }; 115 116 // Non-AA 117 DEF_BENCH(return new MultitextureImages(128, 32, false, false)); 118 DEF_BENCH(return new MultitextureImages(128, 32, true, false)); 119 DEF_BENCH(return new MultitextureImages(128, 128, false, false)); 120 DEF_BENCH(return new MultitextureImages(128, 128, true, false)); 121 DEF_BENCH(return new MultitextureImages(128, 256, false, false)); 122 DEF_BENCH(return new MultitextureImages(128, 256, true, false)); 123 124 DEF_BENCH(return new MultitextureImages(512, 32, false, false)); 125 DEF_BENCH(return new MultitextureImages(512, 32, true, false)); 126 DEF_BENCH(return new MultitextureImages(512, 128, false, false)); 127 DEF_BENCH(return new MultitextureImages(512, 128, true, false)); 128 DEF_BENCH(return new MultitextureImages(512, 256, false, false)); 129 DEF_BENCH(return new MultitextureImages(512, 256, true, false)); 130 DEF_BENCH(return new MultitextureImages(512, 512, false, false)); 131 DEF_BENCH(return new MultitextureImages(512, 512, true, false)); 132 133 // AA 134 DEF_BENCH(return new MultitextureImages(512, 512, true, true)); 135 DEF_BENCH(return new MultitextureImages(512, 512, false, true)); 136 DEF_BENCH(return new MultitextureImages(128, 32, true, true)); 137 DEF_BENCH(return new MultitextureImages(128, 32, false, true)); 138 139 #endif 140