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