Home | History | Annotate | Download | only in bench
      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 <memory>
      9 #include "SkColor.h"
     10 #include "SkLinearBitmapPipeline.h"
     11 #include "SkPM4f.h"
     12 #include "Benchmark.h"
     13 #include "SkShader.h"
     14 #include "SkImage.h"
     15 
     16 struct CommonBitmapFPBenchmark : public Benchmark {
     17     CommonBitmapFPBenchmark(
     18         SkISize srcSize,
     19         SkColorProfileType colorProfile,
     20         SkMatrix m,
     21         bool useBilerp,
     22         SkShader::TileMode xTile,
     23         SkShader::TileMode yTile)
     24         : fColorProfile(colorProfile)
     25         , fM{m}
     26         , fUseBilerp{useBilerp}
     27         , fXTile{xTile}
     28         , fYTile{yTile} {
     29         fSrcSize = srcSize;
     30     }
     31 
     32     static SkString tileName(const char* pre, SkShader::TileMode mode) {
     33         SkString name{pre};
     34         switch (mode) {
     35             case SkShader::kClamp_TileMode:
     36                 name.append("Clamp");
     37                 return name;
     38             case SkShader::kRepeat_TileMode:
     39                 name.append("Repeat");
     40                 return name;
     41             case SkShader::kMirror_TileMode:
     42                 name.append("Mirror");
     43                 return name;
     44             default:
     45                 name.append("Unknown");
     46                 return name;
     47         }
     48     }
     49 
     50     const char* onGetName() override {
     51         fName.set("SkBitmapFP");
     52         if (fM.getType() & SkMatrix::kPerspective_Mask) {
     53             fName.append("Perspective");
     54         } else if (fM.getType() & SkMatrix::kAffine_Mask) {
     55             fName.append("Affine");
     56         } else if (fM.getType() & SkMatrix::kScale_Mask) {
     57             fName.append("Scale");
     58         } else if (fM.getType() & SkMatrix::kTranslate_Mask) {
     59             fName.append("Translate");
     60         } else {
     61             fName.append("Identity");
     62         }
     63 
     64         fName.append(tileName("X", fXTile));
     65         fName.append(tileName("Y", fYTile));
     66 
     67         if (fUseBilerp) {
     68             fName.append("Filter");
     69         } else {
     70             fName.append("Nearest");
     71         }
     72 
     73         fName.appendf("%s", BaseName().c_str());
     74 
     75         return fName.c_str();
     76     }
     77 
     78     void onPreDraw(SkCanvas*) override {
     79         int width = fSrcSize.fWidth;
     80         int height = fSrcSize.fHeight;
     81         fBitmap.reset(new uint32_t[width * height]);
     82         for (int y = 0; y < height; y++) {
     83             for (int x = 0; x < width; x++) {
     84                 fBitmap[y * width + x] = (y << 8) + x + (128<<24);
     85             }
     86         }
     87 
     88         bool trash = fM.invert(&fInvert);
     89         sk_ignore_unused_variable(trash);
     90 
     91         fInfo = SkImageInfo::MakeN32Premul(width, height, fColorProfile);
     92     }
     93 
     94     bool isSuitableFor(Backend backend) override {
     95         return backend == kNonRendering_Backend;
     96     }
     97 
     98     virtual SkString BaseName() = 0;
     99 
    100     SkString fName;
    101     SkISize fSrcSize;
    102     SkColorProfileType fColorProfile;
    103     SkMatrix fM;
    104     SkMatrix fInvert;
    105     bool fUseBilerp;
    106     SkShader::TileMode fXTile;
    107     SkShader::TileMode fYTile;
    108     SkImageInfo fInfo;
    109     std::unique_ptr<uint32_t[]> fBitmap;
    110 };
    111 
    112 struct SkBitmapFPGeneral final : public CommonBitmapFPBenchmark {
    113     SkBitmapFPGeneral(
    114         SkISize srcSize,
    115         SkColorProfileType colorProfile,
    116         SkMatrix m,
    117         bool useBilerp,
    118         SkShader::TileMode xTile,
    119         SkShader::TileMode yTile)
    120             : CommonBitmapFPBenchmark(srcSize, colorProfile, m, useBilerp, xTile, yTile) { }
    121 
    122     SkString BaseName() override {
    123         SkString name;
    124         if (fInfo.isSRGB()) {
    125             name.set("sRGB");
    126         } else {
    127             name.set("Linr");
    128         }
    129         return name;
    130     }
    131 
    132     void onDraw(int loops, SkCanvas*) override {
    133         int width = fSrcSize.fWidth;
    134         int height = fSrcSize.fHeight;
    135 
    136         SkAutoTMalloc<SkPM4f> FPbuffer(width*height);
    137 
    138         SkFilterQuality filterQuality;
    139         if (fUseBilerp) {
    140             filterQuality = SkFilterQuality::kLow_SkFilterQuality;
    141         } else {
    142             filterQuality = SkFilterQuality::kNone_SkFilterQuality;
    143         }
    144 
    145         SkPixmap srcPixmap{fInfo, fBitmap.get(), static_cast<size_t>(4 * width)};
    146 
    147         SkLinearBitmapPipeline pipeline{
    148             fInvert, filterQuality, fXTile, fYTile, srcPixmap};
    149 
    150         int count = 100;
    151 
    152         for (int n = 0; n < 1000*loops; n++) {
    153             pipeline.shadeSpan4f(3, 6, FPbuffer, count);
    154         }
    155     }
    156 };
    157 
    158 struct SkBitmapFPOrigShader : public CommonBitmapFPBenchmark {
    159     SkBitmapFPOrigShader(
    160         SkISize srcSize,
    161         SkColorProfileType colorProfile,
    162         SkMatrix m,
    163         bool useBilerp,
    164         SkShader::TileMode xTile,
    165         SkShader::TileMode yTile)
    166             : CommonBitmapFPBenchmark(srcSize, colorProfile, m, useBilerp, xTile, yTile) { }
    167 
    168     SkString BaseName() override {
    169         SkString name{"Orig"};
    170         return name;
    171     }
    172 
    173     void onPreDraw(SkCanvas* c) override {
    174         CommonBitmapFPBenchmark::onPreDraw(c);
    175 
    176         SkImage* image = SkImage::NewRasterCopy(
    177             fInfo, fBitmap.get(), sizeof(SkPMColor) * fSrcSize.fWidth);
    178         fImage.reset(image);
    179         SkShader* shader = fImage->newShader(fXTile, fYTile);
    180         if (fUseBilerp) {
    181             fPaint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);
    182         } else {
    183             fPaint.setFilterQuality(SkFilterQuality::kNone_SkFilterQuality);
    184         }
    185         fPaint.setShader(shader)->unref();
    186     }
    187 
    188     void onPostDraw(SkCanvas*) override {
    189 
    190     }
    191 
    192     void onDraw(int loops, SkCanvas*) override {
    193         int width = fSrcSize.fWidth;
    194         int height = fSrcSize.fHeight;
    195 
    196         SkAutoTMalloc<SkPMColor> buffer4b(width*height);
    197 
    198         uint32_t storage[200];
    199         const SkShader::ContextRec rec(fPaint, fM, nullptr,
    200                                        SkShader::ContextRec::kPMColor_DstType);
    201         SkASSERT(fPaint.getShader()->contextSize(rec) <= sizeof(storage));
    202         SkShader::Context* ctx = fPaint.getShader()->createContext(rec, storage);
    203 
    204         int count = 100;
    205 
    206         for (int n = 0; n < 1000*loops; n++) {
    207             ctx->shadeSpan(3, 6, buffer4b, count);
    208         }
    209 
    210         ctx->~Context();
    211     }
    212     SkPaint fPaint;
    213     SkAutoTUnref<SkImage> fImage;
    214 };
    215 
    216 static SkISize srcSize = SkISize::Make(120, 100);
    217 static SkMatrix mI = SkMatrix::I();
    218 DEF_BENCH(return new SkBitmapFPGeneral(
    219     srcSize, kSRGB_SkColorProfileType, mI, false,
    220     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    221 
    222 DEF_BENCH(return new SkBitmapFPGeneral(
    223     srcSize, kLinear_SkColorProfileType, mI, false,
    224     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    225 
    226 DEF_BENCH(return new SkBitmapFPOrigShader(
    227     srcSize, kLinear_SkColorProfileType, mI, false,
    228     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    229 
    230 DEF_BENCH(return new SkBitmapFPGeneral(
    231     srcSize, kSRGB_SkColorProfileType, mI, true,
    232     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    233 
    234 DEF_BENCH(return new SkBitmapFPGeneral(
    235     srcSize, kLinear_SkColorProfileType, mI, true,
    236     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    237 
    238 DEF_BENCH(return new SkBitmapFPOrigShader(
    239     srcSize, kLinear_SkColorProfileType, mI, true,
    240     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    241 
    242 static SkMatrix mS = SkMatrix::MakeScale(2.7f, 2.7f);
    243 DEF_BENCH(return new SkBitmapFPGeneral(
    244     srcSize, kSRGB_SkColorProfileType, mS, false,
    245     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    246 
    247 DEF_BENCH(return new SkBitmapFPGeneral(
    248     srcSize, kLinear_SkColorProfileType, mS, false,
    249     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    250 
    251 DEF_BENCH(return new SkBitmapFPOrigShader(
    252     srcSize, kLinear_SkColorProfileType, mS, false,
    253     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    254 
    255 DEF_BENCH(return new SkBitmapFPGeneral(
    256     srcSize, kSRGB_SkColorProfileType, mS, true,
    257     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    258 
    259 DEF_BENCH(return new SkBitmapFPGeneral(
    260     srcSize, kLinear_SkColorProfileType, mS, true,
    261     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    262 
    263 DEF_BENCH(return new SkBitmapFPOrigShader(
    264     srcSize, kLinear_SkColorProfileType, mS, true,
    265     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    266 
    267 static SkMatrix rotate(SkScalar r) {
    268     SkMatrix m;
    269     m.setRotate(30);
    270     return m;
    271 }
    272 
    273 static SkMatrix mR = rotate(30);
    274 DEF_BENCH(return new SkBitmapFPGeneral(
    275     srcSize, kSRGB_SkColorProfileType, mR, false,
    276     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    277 
    278 DEF_BENCH(return new SkBitmapFPGeneral(
    279     srcSize, kLinear_SkColorProfileType, mR, false,
    280     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    281 
    282 DEF_BENCH(return new SkBitmapFPOrigShader(
    283     srcSize, kLinear_SkColorProfileType, mR, false,
    284     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    285 
    286 DEF_BENCH(return new SkBitmapFPGeneral(
    287     srcSize, kSRGB_SkColorProfileType, mR, true,
    288     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    289 
    290 DEF_BENCH(return new SkBitmapFPGeneral(
    291     srcSize, kLinear_SkColorProfileType, mR, true,
    292     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    293 
    294 DEF_BENCH(return new SkBitmapFPOrigShader(
    295     srcSize, kLinear_SkColorProfileType, mR, true,
    296     SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
    297 
    298