1dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com/*
2dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com * Copyright 2012 Google Inc.
3dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com *
4dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com * Use of this source code is governed by a BSD-style license that can be
5dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com * found in the LICENSE file.
6dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com */
7f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "Benchmark.h"
8dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com#include "SkCanvas.h"
9dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com#include "SkColor.h"
10dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com#include "SkPaint.h"
11dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com#include "SkPicture.h"
12770963f23f4fc313db0fa3bac18b1b8aafb55f17robertphillips@google.com#include "SkPictureRecorder.h"
13dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com#include "SkPoint.h"
147fe6409ecbff281edd6251c128eff38a7c206524reed@google.com#include "SkRandom.h"
15dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com#include "SkRect.h"
16dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com#include "SkString.h"
17dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
18f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass PictureRecordBench : public Benchmark {
19dde718c558b118e2a918d14046770a8c37d75040djsollen@google.compublic:
20410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    PictureRecordBench(const char name[])  {
21dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com        fName.printf("picture_record_%s", name);
22644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org    }
23644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org
24644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
25644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org        return backend == kNonRendering_Backend;
26dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com    }
27dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
28dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com    enum {
29dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com        PICTURE_WIDTH = 1000,
30dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com        PICTURE_HEIGHT = 4000,
31dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com    };
32dde718c558b118e2a918d14046770a8c37d75040djsollen@google.comprotected:
3393d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.com    virtual const char* onGetName() SK_OVERRIDE {
34dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com        return fName.c_str();
35dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com    }
36dde718c558b118e2a918d14046770a8c37d75040djsollen@google.comprivate:
3793d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.com    SkString fName;
38f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
39dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com};
40dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
4193d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.com
4293d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.comstatic const int kMaxLoopsPerCanvas = 10000;
4393d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.com
44dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com/*
45dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com *  An SkPicture has internal dictionaries to store bitmaps, matrices, paints,
46dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com *  and regions.  This bench populates those dictionaries to test the speed of
47dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com *  reading and writing to those particular dictionary data structures.
48dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com */
49dde718c558b118e2a918d14046770a8c37d75040djsollen@google.comclass DictionaryRecordBench : public PictureRecordBench {
50dde718c558b118e2a918d14046770a8c37d75040djsollen@google.compublic:
5193d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.com    DictionaryRecordBench() : INHERITED("dictionaries") {}
52dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
53dde718c558b118e2a918d14046770a8c37d75040djsollen@google.comprotected:
543361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
5584b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com        SkPictureRecorder recorder;
5693d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.com        SkCanvas* canvas = NULL;
57dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
583361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        const SkPoint translateDelta = getTranslateDelta(loops);
59dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
603361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; i++) {
6193d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.com            if (0 == i % kMaxLoopsPerCanvas) {
6284b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                SkAutoTUnref<SkPicture> picture(recorder.endRecording());
635fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org                canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
6493d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.com            }
65dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
66dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            SkColor color = SK_ColorYELLOW + (i % 255);
67c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            SkIRect rect = SkIRect::MakeWH(i % PICTURE_WIDTH, i % PICTURE_HEIGHT);
68dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
69dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            canvas->save();
70dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
71dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            // set the clip to the given region
72dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            SkRegion region;
73dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            region.setRect(rect);
74dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            canvas->clipRegion(region);
75dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
76dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            // fill the clip with a color
77dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            SkPaint paint;
78dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            paint.setColor(color);
79dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            canvas->drawPaint(paint);
80dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
81dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            // set a matrix on the canvas
82dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            SkMatrix matrix;
83dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            matrix.setRotate(SkIntToScalar(i % 360));
84dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            canvas->setMatrix(matrix);
85dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
86dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            // create a simple bitmap
87dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            SkBitmap bitmap;
886c22573edb234ad14df947278cfed010669a39a7reed            bitmap.allocPixels(SkImageInfo::Make(10, 10,
896c22573edb234ad14df947278cfed010669a39a7reed                                                 kRGB_565_SkColorType, kOpaque_SkAlphaType));
90dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
91dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            // draw a single color into the bitmap
92dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            SkCanvas bitmapCanvas(bitmap);
93dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            bitmapCanvas.drawColor(SkColorSetA(color, i % 255));
94dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
95dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            // draw the bitmap onto the canvas
96dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            canvas->drawBitmapMatrix(bitmap, matrix);
97dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
98dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            canvas->restore();
99dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com            canvas->translate(translateDelta.fX, translateDelta.fY);
100dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com        }
101dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com    }
102dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
103c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkPoint getTranslateDelta(int M) {
104dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com        SkIPoint canvasSize = onGetSize();
105dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com        return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/M),
106dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com                             SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/M));
107dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com    }
108dde718c558b118e2a918d14046770a8c37d75040djsollen@google.comprivate:
109dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com    typedef PictureRecordBench INHERITED;
110dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com};
111dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
112ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org/*
113ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org *  Populates the SkPaint dictionary with a large number of unique paint
114ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org *  objects that differ only by color
115ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org */
116ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.orgclass UniquePaintDictionaryRecordBench : public PictureRecordBench {
117ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.orgpublic:
11893d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.com    UniquePaintDictionaryRecordBench() : INHERITED("unique_paint_dictionary") { }
119ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org
120ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.orgprotected:
1213361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
122e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom rand;
1235e5239ed35dcac2a42c4780baa7846b751111895mtklein@google.com        SkPaint paint;
12484b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com        SkPictureRecorder recorder;
1255e5239ed35dcac2a42c4780baa7846b751111895mtklein@google.com        SkCanvas* canvas = NULL;
1263361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; i++) {
12793d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.com            if (0 == i % kMaxLoopsPerCanvas) {
12884b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                SkAutoTUnref<SkPicture> picture(recorder.endRecording());
1295fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org                canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
1305e5239ed35dcac2a42c4780baa7846b751111895mtklein@google.com            }
1317fe6409ecbff281edd6251c128eff38a7c206524reed@google.com            paint.setColor(rand.nextU());
132ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org            canvas->drawPaint(paint);
133ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org        }
134ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org    }
135ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org
136ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.orgprivate:
137ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org    typedef PictureRecordBench INHERITED;
138ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org};
139ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org
140ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org/*
141ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org *  Populates the SkPaint dictionary with a number of unique paint
1420c4e21da9598a2eb5324e90ac8648048a1a34636commit-bot@chromium.org *  objects that get reused repeatedly.
1430c4e21da9598a2eb5324e90ac8648048a1a34636commit-bot@chromium.org *
1440c4e21da9598a2eb5324e90ac8648048a1a34636commit-bot@chromium.org *  Re-creating the paint objects in the inner loop slows the benchmark down 10%.
1450c4e21da9598a2eb5324e90ac8648048a1a34636commit-bot@chromium.org *  Using setColor(i % objCount) instead of a random color creates a very high rate
1460c4e21da9598a2eb5324e90ac8648048a1a34636commit-bot@chromium.org *  of hash conflicts, slowing us down 12%.
147ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org */
148ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.orgclass RecurringPaintDictionaryRecordBench : public PictureRecordBench {
149ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.orgpublic:
15093d2f559b88b7eb59929451000a0e307f17c996fmtklein@google.com    RecurringPaintDictionaryRecordBench() : INHERITED("recurring_paint_dictionary") {
151e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom rand;
1520c4e21da9598a2eb5324e90ac8648048a1a34636commit-bot@chromium.org        for (int i = 0; i < ObjCount; i++) {
1530c4e21da9598a2eb5324e90ac8648048a1a34636commit-bot@chromium.org            fPaint[i].setColor(rand.nextU());
1540c4e21da9598a2eb5324e90ac8648048a1a34636commit-bot@chromium.org        }
1550c4e21da9598a2eb5324e90ac8648048a1a34636commit-bot@chromium.org    }
156ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org
157ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org    enum {
158c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        ObjCount = 100,  // number of unique paint objects
159ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org    };
160ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.orgprotected:
1613361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
16284b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com        SkPictureRecorder recorder;
1635fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org        SkCanvas* canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
1643361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; i++) {
1650c4e21da9598a2eb5324e90ac8648048a1a34636commit-bot@chromium.org            canvas->drawPaint(fPaint[i % ObjCount]);
166ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org        }
167ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org    }
168ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org
169ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.orgprivate:
1700c4e21da9598a2eb5324e90ac8648048a1a34636commit-bot@chromium.org    SkPaint fPaint [ObjCount];
171ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org    typedef PictureRecordBench INHERITED;
172ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org};
173ef76060cbf36032a5bef9cd8d18138704349c3aejunov@chromium.org
174dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com///////////////////////////////////////////////////////////////////////////////
175dde718c558b118e2a918d14046770a8c37d75040djsollen@google.com
176410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new DictionaryRecordBench(); )
177410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new UniquePaintDictionaryRecordBench(); )
178410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new RecurringPaintDictionaryRecordBench(); )
179