13342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon/*
23342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon * Copyright 2014 Google Inc.
33342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon *
43342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon * Use of this source code is governed by a BSD-style license that can be
53342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon * found in the LICENSE file.
63342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon */
73342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
83342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon#include "Benchmark.h"
93342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon#include "SkCanvas.h"
103342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon#include "SkPaint.h"
113342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
126563562cb6b03ad11e33b50b84acf43742b4477ebsalomon#include <ctype.h>
136563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
143342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon/** This benchmark tests rendering rotated rectangles. It can optionally apply AA and/or change the
156563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    paint color between each rect in different ways using the ColorType enum. The xfermode used can
166563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    be specified as well.
176563562cb6b03ad11e33b50b84acf43742b4477ebsalomon  */
186563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
196563562cb6b03ad11e33b50b84acf43742b4477ebsalomonenum ColorType {
206563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    kConstantOpaque_ColorType,
216563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    kConstantTransparent_ColorType,
226563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    kChangingOpaque_ColorType,
236563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    kChangingTransparent_ColorType,
246563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    kAlternatingOpaqueAndTransparent_ColorType,
256563562cb6b03ad11e33b50b84acf43742b4477ebsalomon};
266563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
276563562cb6b03ad11e33b50b84acf43742b4477ebsalomonstatic inline SkColor start_color(ColorType ct) {
286563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    switch (ct) {
296563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        case kConstantOpaque_ColorType:
306563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        case kChangingOpaque_ColorType:
316563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        case kAlternatingOpaqueAndTransparent_ColorType:
326563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            return 0xFFA07040;
336563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        case kConstantTransparent_ColorType:
346563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        case kChangingTransparent_ColorType:
356563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            return 0x80A07040;
366563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    }
376563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    SkFAIL("Shouldn't reach here.");
386563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    return 0;
396563562cb6b03ad11e33b50b84acf43742b4477ebsalomon}
406563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
416563562cb6b03ad11e33b50b84acf43742b4477ebsalomonstatic inline SkColor advance_color(SkColor old, ColorType ct, int step) {
426563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    if (kAlternatingOpaqueAndTransparent_ColorType == ct) {
436563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        ct = (step & 0x1) ? kChangingOpaque_ColorType : kChangingTransparent_ColorType ;
446563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    }
456563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    switch (ct) {
466563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        case kConstantOpaque_ColorType:
476563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        case kConstantTransparent_ColorType:
486563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            return old;
496563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        case kChangingOpaque_ColorType:
506563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            return 0xFF000000 | (old + 0x00010307);
516563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        case kChangingTransparent_ColorType:
526563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            return (0x00FFFFFF & (old + 0x00010307)) | 0x80000000;
536563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        case kAlternatingOpaqueAndTransparent_ColorType:
546563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            SkFAIL("Can't get here");
556563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    }
566563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    SkFAIL("Shouldn't reach here.");
576563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    return 0;
586563562cb6b03ad11e33b50b84acf43742b4477ebsalomon}
596563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
606563562cb6b03ad11e33b50b84acf43742b4477ebsalomonstatic SkString to_lower(const char* str) {
616563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    SkString lower(str);
626563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    for (size_t i = 0; i < lower.size(); i++) {
636563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        lower[i] = tolower(lower[i]);
646563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    }
656563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    return lower;
666563562cb6b03ad11e33b50b84acf43742b4477ebsalomon}
676563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
683342ed55e1e0b2f9f4847250927013ae74e125e3bsalomonclass RotRectBench: public Benchmark {
693342ed55e1e0b2f9f4847250927013ae74e125e3bsalomonpublic:
706563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    RotRectBench(bool aa, ColorType ct, SkXfermode::Mode mode)
713342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        : fAA(aa)
726563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        , fColorType(ct)
736563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        , fMode(mode) {
743342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        this->makeName();
753342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon    }
763342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
773342ed55e1e0b2f9f4847250927013ae74e125e3bsalomonprotected:
783342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon    virtual const char* onGetName() SK_OVERRIDE { return fName.c_str(); }
793342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
803342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
813342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        SkPaint paint;
823342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        paint.setAntiAlias(fAA);
836563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        paint.setXfermodeMode(fMode);
846563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        SkColor color = start_color(fColorType);
853342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
863342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        int w = canvas->getBaseLayerSize().width();
873342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        int h = canvas->getBaseLayerSize().height();
883342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
893342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        static const SkScalar kRectW = 25.1f;
903342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        static const SkScalar kRectH = 25.9f;
913342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
923342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        SkMatrix rotate;
933342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        // This value was chosen so that we frequently hit the axis-aligned case.
943342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        rotate.setRotate(30.f, kRectW / 2, kRectH / 2);
953342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        SkMatrix m = rotate;
963342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
973342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        SkScalar tx = 0, ty = 0;
983342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
993342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        for (int i = 0; i < loops; ++i) {
1003342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            canvas->save();
1013342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            canvas->translate(tx, ty);
1023342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            canvas->concat(m);
1033342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            paint.setColor(color);
1046563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            color = advance_color(color, fColorType, i);
1056563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
1063342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            canvas->drawRect(SkRect::MakeWH(kRectW, kRectH), paint);
1073342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            canvas->restore();
1083342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
1093342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            tx += kRectW + 2;
1103342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            if (tx > w) {
1113342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon                tx = 0;
1123342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon                ty += kRectH + 2;
1133342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon                if (ty > h) {
1143342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon                    ty = 0;
1153342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon                }
1163342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            }
1173342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
1183342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            m.postConcat(rotate);
1193342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        }
1203342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon    }
1213342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
1223342ed55e1e0b2f9f4847250927013ae74e125e3bsalomonprivate:
1233342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon    void makeName() {
1243342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        fName = "rotated_rects";
1253342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        if (fAA) {
1263342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            fName.append("_aa");
1273342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        } else {
1283342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon            fName.append("_bw");
1293342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        }
1306563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        switch (fColorType) {
1316563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            case kConstantOpaque_ColorType:
1326563562cb6b03ad11e33b50b84acf43742b4477ebsalomon                fName.append("_same_opaque");
1336563562cb6b03ad11e33b50b84acf43742b4477ebsalomon                break;
1346563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            case kConstantTransparent_ColorType:
1356563562cb6b03ad11e33b50b84acf43742b4477ebsalomon                fName.append("_same_transparent");
1366563562cb6b03ad11e33b50b84acf43742b4477ebsalomon                break;
1376563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            case kChangingOpaque_ColorType:
1386563562cb6b03ad11e33b50b84acf43742b4477ebsalomon                fName.append("_changing_opaque");
1396563562cb6b03ad11e33b50b84acf43742b4477ebsalomon                break;
1406563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            case kChangingTransparent_ColorType:
1416563562cb6b03ad11e33b50b84acf43742b4477ebsalomon                fName.append("_changing_transparent");
1426563562cb6b03ad11e33b50b84acf43742b4477ebsalomon                break;
1436563562cb6b03ad11e33b50b84acf43742b4477ebsalomon            case kAlternatingOpaqueAndTransparent_ColorType:
1446563562cb6b03ad11e33b50b84acf43742b4477ebsalomon                fName.append("_alternating_transparent_and_opaque");
1456563562cb6b03ad11e33b50b84acf43742b4477ebsalomon                break;
1463342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon        }
1476563562cb6b03ad11e33b50b84acf43742b4477ebsalomon        fName.appendf("_%s", to_lower(SkXfermode::ModeName(fMode)).c_str());
1483342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon    }
1493342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
1506563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    bool             fAA;
1516563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    ColorType        fColorType;
1526563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    SkXfermode::Mode fMode;
1536563562cb6b03ad11e33b50b84acf43742b4477ebsalomon    SkString         fName;
1543342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
1553342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon    typedef Benchmark INHERITED;
1563342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon};
1573342ed55e1e0b2f9f4847250927013ae74e125e3bsalomon
1586563562cb6b03ad11e33b50b84acf43742b4477ebsalomon// Choose kSrcOver because it always allows coverage and alpha to be conflated. kSrc only allows
1596563562cb6b03ad11e33b50b84acf43742b4477ebsalomon// conflation when opaque, and kDarken because it isn't possilbe with standard GL blending.
1606563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
1616563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
1626563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
1636563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
1646563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
1656563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
1666563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
1676563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
1686563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kSrcOver_Mode);)
1696563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kSrcOver_Mode);)
1706563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrcOver_Mode);)
1716563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
1726563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
1736563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kSrc_Mode);)
1746563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
1756563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kSrc_Mode);)
1766563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrc_Mode);)
1776563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
1786563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
1796563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kSrc_Mode);)
1806563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kSrc_Mode);)
1816563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kSrc_Mode);)
1826563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kSrc_Mode);)
1836563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
1846563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kConstantOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
1856563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kConstantTransparent_ColorType,             SkXfermode::kDarken_Mode);)
1866563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kChangingOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
1876563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kChangingTransparent_ColorType,             SkXfermode::kDarken_Mode);)
1886563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(true,  kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kDarken_Mode);)
1896563562cb6b03ad11e33b50b84acf43742b4477ebsalomon
1906563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kConstantOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
1916563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kConstantTransparent_ColorType,             SkXfermode::kDarken_Mode);)
1926563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kChangingOpaque_ColorType,                  SkXfermode::kDarken_Mode);)
1936563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kChangingTransparent_ColorType,             SkXfermode::kDarken_Mode);)
1946563562cb6b03ad11e33b50b84acf43742b4477ebsalomonDEF_BENCH(return new RotRectBench(false, kAlternatingOpaqueAndTransparent_ColorType, SkXfermode::kDarken_Mode);)
195