1/*
2 * Copyright 2011 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#include "SkBenchmark.h"
8#include "SkCanvas.h"
9#include "SkColor.h"
10#include "SkPaint.h"
11#include "SkPicture.h"
12#include "SkPoint.h"
13#include "SkRect.h"
14#include "SkString.h"
15
16// This is designed to emulate about 4 screens of textual content
17
18
19class PicturePlaybackBench : public SkBenchmark {
20public:
21    PicturePlaybackBench(void* param, const char name[]) : INHERITED(param) {
22        fName.printf("picture_playback_%s", name);
23        fPictureWidth = SkIntToScalar(PICTURE_WIDTH);
24        fPictureHeight = SkIntToScalar(PICTURE_HEIGHT);
25        fTextSize = SkIntToScalar(TEXT_SIZE);
26    }
27
28    enum {
29        N = SkBENCHLOOP(1000),   // number of times to playback the picture
30        PICTURE_WIDTH = 1000,
31        PICTURE_HEIGHT = 4000,
32        TEXT_SIZE = 10
33    };
34protected:
35    virtual const char* onGetName() {
36        return fName.c_str();
37    }
38
39    virtual void onDraw(SkCanvas* canvas) {
40
41        SkPicture picture;
42
43        SkCanvas* pCanvas = picture.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT);
44        recordCanvas(pCanvas);
45        picture.endRecording();
46
47        const SkPoint translateDelta = getTranslateDelta();
48
49        for (int i = 0; i < N; i++) {
50            picture.draw(canvas);
51            canvas->translate(translateDelta.fX, translateDelta.fY);
52        }
53    }
54
55    virtual void recordCanvas(SkCanvas* canvas) = 0;
56    virtual SkPoint getTranslateDelta() {
57        SkIPoint canvasSize = onGetSize();
58        return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/N),
59                             SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/N));
60    }
61
62    SkString fName;
63    SkScalar fPictureWidth;
64    SkScalar fPictureHeight;
65    SkScalar fTextSize;
66private:
67    typedef SkBenchmark INHERITED;
68};
69
70
71class TextPlaybackBench : public PicturePlaybackBench {
72public:
73    TextPlaybackBench(void* param) : INHERITED(param, "drawText") { }
74protected:
75    virtual void recordCanvas(SkCanvas* canvas) {
76        SkPaint paint;
77        paint.setTextSize(fTextSize);
78        paint.setColor(SK_ColorBLACK);
79
80        const char* text = "Hamburgefons";
81        size_t len = strlen(text);
82        const SkScalar textWidth = paint.measureText(text, len);
83
84        for (SkScalar x = 0; x < fPictureWidth; x += textWidth) {
85            for (SkScalar y = 0; y < fPictureHeight; y += fTextSize) {
86                canvas->drawText(text, len, x, y, paint);
87            }
88        }
89    }
90private:
91    typedef PicturePlaybackBench INHERITED;
92};
93
94class PosTextPlaybackBench : public PicturePlaybackBench {
95public:
96    PosTextPlaybackBench(void* param, bool drawPosH)
97        : INHERITED(param, drawPosH ? "drawPosTextH" : "drawPosText")
98        , fDrawPosH(drawPosH) { }
99protected:
100    virtual void recordCanvas(SkCanvas* canvas) {
101        SkPaint paint;
102        paint.setTextSize(fTextSize);
103        paint.setColor(SK_ColorBLACK);
104
105        const char* text = "Hamburgefons";
106        size_t len = strlen(text);
107        const SkScalar textWidth = paint.measureText(text, len);
108
109        SkScalar* adv = new SkScalar[len];
110        paint.getTextWidths(text, len, adv);
111
112        for (SkScalar x = 0; x < fPictureWidth; x += textWidth) {
113            for (SkScalar y = 0; y < fPictureHeight; y += fTextSize) {
114
115                SkPoint* pos = new SkPoint[len];
116                SkScalar advX = 0;
117
118                for (size_t i = 0; i < len; i++) {
119                    if (fDrawPosH)
120                        pos[i].set(x + advX, y);
121                    else
122                        pos[i].set(x + advX, y + SkIntToScalar(i));
123                    advX += adv[i];
124                }
125
126                canvas->drawPosText(text, len, pos, paint);
127                delete[] pos;
128            }
129        }
130        delete[] adv;
131    }
132private:
133    bool fDrawPosH;
134    typedef PicturePlaybackBench INHERITED;
135};
136
137
138///////////////////////////////////////////////////////////////////////////////
139
140static SkBenchmark* Fact0(void* p) { return new TextPlaybackBench(p); }
141static SkBenchmark* Fact1(void* p) { return new PosTextPlaybackBench(p, true); }
142static SkBenchmark* Fact2(void* p) { return new PosTextPlaybackBench(p, false); }
143
144static BenchRegistry gReg0(Fact0);
145static BenchRegistry gReg1(Fact1);
146static BenchRegistry gReg2(Fact2);
147
148