180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBenchmark.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkCanvas.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFontHost.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPaint.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRandom.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkString.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTemplates.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruenum FontQuality {
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    kBW,
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    kAA,
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    kLCD
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const char* fontQualityName(const SkPaint& paint) {
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!paint.isAntiAlias()) {
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return "BW";
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (paint.isLCDRenderText()) {
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return "LCD";
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return "AA";
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*  Some considerations for performance:
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        short -vs- long strings (measuring overhead)
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        tiny -vs- large pointsize (measure blit -vs- overhead)
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        1 -vs- many point sizes (measure cache lookup)
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        normal -vs- subpixel -vs- lineartext (minor)
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        force purge after each draw to measure scaler
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        textencoding?
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        text -vs- postext - pathtext
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass TextBench : public SkBenchmark {
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint     fPaint;
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString    fText;
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString    fName;
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    FontQuality fFQ;
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool        fDoPos;
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPoint*    fPos;
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum { N = SkBENCHLOOP(800) };
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    TextBench(void* param, const char text[], int ps,
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru              SkColor color, FontQuality fq, bool doPos = false) : INHERITED(param) {
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPos = NULL;
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fFQ = fq;
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fDoPos = doPos;
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fText.set(text);
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaint.setAntiAlias(kBW != fq);
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaint.setLCDRenderText(kLCD == fq);
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaint.setTextSize(SkIntToScalar(ps));
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPaint.setColor(color);
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (doPos) {
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            size_t len = strlen(text);
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkScalar* adv = new SkScalar[len];
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fPaint.getTextWidths(text, len, adv);
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fPos = new SkPoint[len];
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkScalar x = 0;
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (size_t i = 0; i < len; ++i) {
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fPos[i].set(x, SkIntToScalar(50));
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                x += adv[i];
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            delete[] adv;
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual ~TextBench() {
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        delete[] fPos;
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected:
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual const char* onGetName() {
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fName.printf("text_%g", SkScalarToFloat(fPaint.getTextSize()));
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fDoPos) {
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fName.append("_pos");
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fName.appendf("_%s", fontQualityName(fPaint));
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (SK_ColorBLACK != fPaint.getColor()) {
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fName.appendf("_%02X", fPaint.getAlpha());
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fName.append("_BK");
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return fName.c_str();
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void onDraw(SkCanvas* canvas) {
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const SkIPoint dim = this->getSize();
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkRandom rand;
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkPaint paint(fPaint);
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->setupPaint(&paint);
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // explicitly need these
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        paint.setColor(fPaint.getColor());
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        paint.setAntiAlias(kBW != fFQ);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        paint.setLCDRenderText(kLCD == fFQ);
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const SkScalar x0 = SkIntToScalar(-10);
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const SkScalar y0 = SkIntToScalar(-10);
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fDoPos) {
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // realistically, the matrix is often at least translated, so we
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // do that since it exercises different code in drawPosText.
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            canvas->translate(SK_Scalar1, SK_Scalar1);
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int i = 0; i < N; i++) {
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (fDoPos) {
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas->drawPosText(fText.c_str(), fText.size(), fPos, paint);
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else {
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar x = x0 + rand.nextUScalar1() * dim.fX;
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar y = y0 + rand.nextUScalar1() * dim.fY;
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas->drawText(fText.c_str(), fText.size(), x, y, paint);
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef SkBenchmark INHERITED;
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define STR     "Hamburgefons"
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBenchmark* Fact01(void* p) { return new TextBench(p, STR, 16, 0xFF000000, kBW); }
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBenchmark* Fact02(void* p) { return new TextBench(p, STR, 16, 0xFFFF0000, kBW); }
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBenchmark* Fact03(void* p) { return new TextBench(p, STR, 16, 0x88FF0000, kBW); }
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBenchmark* Fact11(void* p) { return new TextBench(p, STR, 16, 0xFF000000, kAA); }
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBenchmark* Fact12(void* p) { return new TextBench(p, STR, 16, 0xFFFF0000, kAA); }
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBenchmark* Fact13(void* p) { return new TextBench(p, STR, 16, 0x88FF0000, kAA); }
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBenchmark* Fact21(void* p) { return new TextBench(p, STR, 16, 0xFF000000, kLCD); }
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBenchmark* Fact22(void* p) { return new TextBench(p, STR, 16, 0xFFFF0000, kLCD); }
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBenchmark* Fact23(void* p) { return new TextBench(p, STR, 16, 0x88FF0000, kLCD); }
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkBenchmark* Fact111(void* p) { return new TextBench(p, STR, 16, 0xFF000000, kAA, true); }
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic BenchRegistry gReg01(Fact01);
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic BenchRegistry gReg02(Fact02);
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic BenchRegistry gReg03(Fact03);
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic BenchRegistry gReg11(Fact11);
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic BenchRegistry gReg12(Fact12);
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic BenchRegistry gReg13(Fact13);
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic BenchRegistry gReg21(Fact21);
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic BenchRegistry gReg22(Fact22);
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic BenchRegistry gReg23(Fact23);
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic BenchRegistry gReg111(Fact111);
161