• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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