1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "Benchmark.h"
93a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkCanvas.h"
10d6638e644e430a721ea2dc2372e1880e16a3ff5dreed@android.com#include "SkFontHost.h"
113a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkPaint.h"
123a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkRandom.h"
133a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkString.h"
143a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkTemplates.h"
153a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com
16095186a466f92b871c8ef8385246405426a67adbreed@google.comenum FontQuality {
17095186a466f92b871c8ef8385246405426a67adbreed@google.com    kBW,
18095186a466f92b871c8ef8385246405426a67adbreed@google.com    kAA,
19095186a466f92b871c8ef8385246405426a67adbreed@google.com    kLCD
20095186a466f92b871c8ef8385246405426a67adbreed@google.com};
21095186a466f92b871c8ef8385246405426a67adbreed@google.com
22095186a466f92b871c8ef8385246405426a67adbreed@google.comstatic const char* fontQualityName(const SkPaint& paint) {
23095186a466f92b871c8ef8385246405426a67adbreed@google.com    if (!paint.isAntiAlias()) {
24095186a466f92b871c8ef8385246405426a67adbreed@google.com        return "BW";
25095186a466f92b871c8ef8385246405426a67adbreed@google.com    }
26095186a466f92b871c8ef8385246405426a67adbreed@google.com    if (paint.isLCDRenderText()) {
27095186a466f92b871c8ef8385246405426a67adbreed@google.com        return "LCD";
28095186a466f92b871c8ef8385246405426a67adbreed@google.com    }
29095186a466f92b871c8ef8385246405426a67adbreed@google.com    return "AA";
30095186a466f92b871c8ef8385246405426a67adbreed@google.com}
31095186a466f92b871c8ef8385246405426a67adbreed@google.com
323a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com/*  Some considerations for performance:
333a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        short -vs- long strings (measuring overhead)
343a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        tiny -vs- large pointsize (measure blit -vs- overhead)
353a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        1 -vs- many point sizes (measure cache lookup)
363a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        normal -vs- subpixel -vs- lineartext (minor)
373a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        force purge after each draw to measure scaler
383a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        textencoding?
393a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        text -vs- postext - pathtext
403a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com */
41f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass TextBench : public Benchmark {
423a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkPaint     fPaint;
433a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkString    fText;
443a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkString    fName;
45095186a466f92b871c8ef8385246405426a67adbreed@google.com    FontQuality fFQ;
46055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com    bool        fDoPos;
47055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com    SkPoint*    fPos;
483a859a00342ed078af683fd1901fd26c93dd40f0reed@android.compublic:
49410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    TextBench(const char text[], int ps,
50410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com              SkColor color, FontQuality fq, bool doPos = false)  {
517fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com        fPos = NULL;
52095186a466f92b871c8ef8385246405426a67adbreed@google.com        fFQ = fq;
53055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com        fDoPos = doPos;
543a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        fText.set(text);
553a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com
56095186a466f92b871c8ef8385246405426a67adbreed@google.com        fPaint.setAntiAlias(kBW != fq);
57095186a466f92b871c8ef8385246405426a67adbreed@google.com        fPaint.setLCDRenderText(kLCD == fq);
583a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        fPaint.setTextSize(SkIntToScalar(ps));
59b9d84f3bed7255004b7df18fb2c2fcc0ffac78bcreed@google.com        fPaint.setColor(color);
60055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com
61055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com        if (doPos) {
62055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            size_t len = strlen(text);
63055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            SkScalar* adv = new SkScalar[len];
64055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            fPaint.getTextWidths(text, len, adv);
65055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            fPos = new SkPoint[len];
66055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            SkScalar x = 0;
67055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            for (size_t i = 0; i < len; ++i) {
68055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com                fPos[i].set(x, SkIntToScalar(50));
69055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com                x += adv[i];
70055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            }
71055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            delete[] adv;
72055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com        }
73055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com    }
74055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com
75055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com    virtual ~TextBench() {
76055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com        delete[] fPos;
773a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    }
783a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com
793a859a00342ed078af683fd1901fd26c93dd40f0reed@android.comprotected:
803a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    virtual const char* onGetName() {
813a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        fName.printf("text_%g", SkScalarToFloat(fPaint.getTextSize()));
82055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com        if (fDoPos) {
83b9682d38c1daa597c4acffd93cbd5ba72735a613vandebo@chromium.org            fName.append("_pos");
84055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com        }
85095186a466f92b871c8ef8385246405426a67adbreed@google.com        fName.appendf("_%s", fontQualityName(fPaint));
86b9d84f3bed7255004b7df18fb2c2fcc0ffac78bcreed@google.com        if (SK_ColorBLACK != fPaint.getColor()) {
87b9d84f3bed7255004b7df18fb2c2fcc0ffac78bcreed@google.com            fName.appendf("_%02X", fPaint.getAlpha());
88095186a466f92b871c8ef8385246405426a67adbreed@google.com        } else {
89b9682d38c1daa597c4acffd93cbd5ba72735a613vandebo@chromium.org            fName.append("_BK");
90b9d84f3bed7255004b7df18fb2c2fcc0ffac78bcreed@google.com        }
913a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        return fName.c_str();
923a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    }
933a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com
943361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org    virtual void onDraw(const int loops, SkCanvas* canvas) {
953a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        const SkIPoint dim = this->getSize();
96e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom rand;
973a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com
983a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        SkPaint paint(fPaint);
993a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        this->setupPaint(&paint);
100095186a466f92b871c8ef8385246405426a67adbreed@google.com        // explicitly need these
101095186a466f92b871c8ef8385246405426a67adbreed@google.com        paint.setColor(fPaint.getColor());
102095186a466f92b871c8ef8385246405426a67adbreed@google.com        paint.setAntiAlias(kBW != fFQ);
103095186a466f92b871c8ef8385246405426a67adbreed@google.com        paint.setLCDRenderText(kLCD == fFQ);
1043a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com
1053a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        const SkScalar x0 = SkIntToScalar(-10);
1063a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        const SkScalar y0 = SkIntToScalar(-10);
107b9d84f3bed7255004b7df18fb2c2fcc0ffac78bcreed@google.com
108055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com        if (fDoPos) {
109055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            // realistically, the matrix is often at least translated, so we
110055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            // do that since it exercises different code in drawPosText.
111055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            canvas->translate(SK_Scalar1, SK_Scalar1);
112055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com        }
113055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com
1143361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; i++) {
115055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            if (fDoPos) {
116055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com                canvas->drawPosText(fText.c_str(), fText.size(), fPos, paint);
117055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            } else {
118055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com                SkScalar x = x0 + rand.nextUScalar1() * dim.fX;
119055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com                SkScalar y = y0 + rand.nextUScalar1() * dim.fY;
120055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com                canvas->drawText(fText.c_str(), fText.size(), x, y, paint);
121055af884c8f1a0a2e5b4ded400ea7af27295dfc1reed@google.com            }
1223a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com        }
1233a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    }
1243a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com
1253a859a00342ed078af683fd1901fd26c93dd40f0reed@android.comprivate:
126f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
1273a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com};
1283a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com
1293a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com///////////////////////////////////////////////////////////////////////////////
1303a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com
1313a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#define STR     "Hamburgefons"
132eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com
133410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kBW); )
134410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kBW); )
135410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kBW); )
136b9d84f3bed7255004b7df18fb2c2fcc0ffac78bcreed@google.com
137410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kAA); )
138410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kAA); )
139410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kAA); )
140b9d84f3bed7255004b7df18fb2c2fcc0ffac78bcreed@google.com
141410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kLCD); )
142410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kLCD); )
143410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kLCD); )
1443a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com
145410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kAA, true); )
146