DashBench.cpp revision 4ad22753504828342e47627b12210c2c47e7290a
14aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
24aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com/*
34aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com * Copyright 2011 Google Inc.
44aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com *
54aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com * Use of this source code is governed by a BSD-style license that can be
64aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com * found in the LICENSE file.
74aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com */
84aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com#include "SkBenchmark.h"
94aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com#include "SkBitmap.h"
104aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com#include "SkCanvas.h"
114aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com#include "SkDashPathEffect.h"
124aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com#include "SkPaint.h"
134aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com#include "SkPath.h"
144aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com#include "SkRandom.h"
154aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com#include "SkString.h"
164aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com#include "SkTDArray.h"
174aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
18ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com
194aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com/*
204aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com *  Cases to consider:
214aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com *
224aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com *  1. antialiasing on/off (esp. width <= 1)
234aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com *  2. strokewidth == 0, 1, 2
244aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com *  3. hline, vline, diagonal, rect, oval
254aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com *  4. dots [1,1] ([N,N] where N=strokeWidth?) or arbitrary (e.g. [2,1] or [1,2,3,2])
264aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com */
274aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.comstatic void path_hline(SkPath* path) {
284aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    path->moveTo(SkIntToScalar(10), SkIntToScalar(10));
294aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    path->lineTo(SkIntToScalar(600), SkIntToScalar(10));
304aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com}
314aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
324aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.comclass DashBench : public SkBenchmark {
33ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.comprotected:
3499a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.org    SkString            fName;
354aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    SkTDArray<SkScalar> fIntervals;
3699a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.org    int                 fWidth;
374ad22753504828342e47627b12210c2c47e7290areed@google.com    bool fDoClip;
384aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
394aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    enum {
404aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        N = SkBENCHLOOP(100)
414aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    };
424aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.compublic:
434ad22753504828342e47627b12210c2c47e7290areed@google.com    DashBench(void* param, const SkScalar intervals[], int count, int width,
444ad22753504828342e47627b12210c2c47e7290areed@google.com              bool doClip = false) : INHERITED(param) {
454aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        fIntervals.append(count, intervals);
4699a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.org        for (int i = 0; i < count; ++i) {
4799a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.org            fIntervals[i] *= width;
4899a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.org        }
4999a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.org        fWidth = width;
504ad22753504828342e47627b12210c2c47e7290areed@google.com        fName.printf("dash_%d_%s", width, doClip ? "clipped" : "noclip");
514ad22753504828342e47627b12210c2c47e7290areed@google.com        fDoClip = doClip;
524aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    }
534aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
544aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    virtual void makePath(SkPath* path) {
554aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        path_hline(path);
564aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    }
574aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
584aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.comprotected:
594aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    virtual const char* onGetName() SK_OVERRIDE {
6099a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.org        return fName.c_str();
614aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    }
624aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
634aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
644aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        SkPaint paint;
654aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        this->setupPaint(&paint);
664aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        paint.setStyle(SkPaint::kStroke_Style);
6799a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.org        paint.setStrokeWidth(SkIntToScalar(fWidth));
684aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        paint.setAntiAlias(false);
694aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
704aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        SkPath path;
714aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        this->makePath(&path);
724aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
734aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        paint.setPathEffect(new SkDashPathEffect(fIntervals.begin(),
744aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com                                                 fIntervals.count(), 0))->unref();
754ad22753504828342e47627b12210c2c47e7290areed@google.com
764ad22753504828342e47627b12210c2c47e7290areed@google.com        if (fDoClip) {
774ad22753504828342e47627b12210c2c47e7290areed@google.com            SkRect r = path.getBounds();
784ad22753504828342e47627b12210c2c47e7290areed@google.com            r.inset(-SkIntToScalar(20), -SkIntToScalar(20));
794ad22753504828342e47627b12210c2c47e7290areed@google.com            // now move it so we don't intersect
804ad22753504828342e47627b12210c2c47e7290areed@google.com            r.offset(0, r.height() * 3 / 2);
814ad22753504828342e47627b12210c2c47e7290areed@google.com            canvas->clipRect(r);
824ad22753504828342e47627b12210c2c47e7290areed@google.com        }
834ad22753504828342e47627b12210c2c47e7290areed@google.com
84ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com        this->handlePath(canvas, path, paint, N);
85ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com    }
86ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com
87ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com    virtual void handlePath(SkCanvas* canvas, const SkPath& path,
88ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com                            const SkPaint& paint, int N) {
894aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        for (int i = 0; i < N; ++i) {
904aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com            canvas->drawPath(path, paint);
914aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com        }
924aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    }
934aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
944aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.comprivate:
954aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com    typedef SkBenchmark INHERITED;
964aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com};
974aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
98ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.comclass RectDashBench : public DashBench {
99ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.compublic:
1004ad22753504828342e47627b12210c2c47e7290areed@google.com    RectDashBench(void* param, const SkScalar intervals[], int count, int width, bool doClip = false)
101ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com    : INHERITED(param, intervals, count, width) {
102ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com        fName.append("_rect");
103ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com    }
104ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com
105ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.comprotected:
106ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com    virtual void handlePath(SkCanvas* canvas, const SkPath& path,
107ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com                            const SkPaint& paint, int N) SK_OVERRIDE {
108ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com        SkPoint pts[2];
109ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com        if (!path.isLine(pts) || pts[0].fY != pts[1].fY) {
110ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            this->INHERITED::handlePath(canvas, path, paint, N);
111ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com        } else {
112ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            SkRect rect;
113ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            rect.fLeft = pts[0].fX;
114ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            rect.fTop = pts[0].fY - paint.getStrokeWidth() / 2;
115ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            rect.fRight = rect.fLeft + SkIntToScalar(fWidth);
116ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            rect.fBottom = rect.fTop + paint.getStrokeWidth();
117ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com
118ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            SkPaint p(paint);
119ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            p.setStyle(SkPaint::kFill_Style);
120ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            p.setPathEffect(NULL);
121ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com
122ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            int count = SkScalarRoundToInt((pts[1].fX - pts[0].fX) / (2*fWidth));
123ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            SkScalar dx = SkIntToScalar(2 * fWidth);
124ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com
125ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            for (int i = 0; i < N*10; ++i) {
126ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com                SkRect r = rect;
127ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com                for (int j = 0; j < count; ++j) {
128ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com                    canvas->drawRect(r, p);
129ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com                    r.offset(dx, 0);
130ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com                }
131ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com            }
132ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com        }
133ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com    }
134ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com
135ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.comprivate:
136ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com    typedef DashBench INHERITED;
137ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com};
138ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.com
1394aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com///////////////////////////////////////////////////////////////////////////////
1404aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
1414aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.comstatic const SkScalar gDots[] = { SK_Scalar1, SK_Scalar1 };
1424aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
1434aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com#define PARAM(array)    array, SK_ARRAY_COUNT(array)
1444aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
14599a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.orgstatic SkBenchmark* gF0(void* p) { return new DashBench(p, PARAM(gDots), 0); }
14699a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.orgstatic SkBenchmark* gF1(void* p) { return new DashBench(p, PARAM(gDots), 1); }
1474ad22753504828342e47627b12210c2c47e7290areed@google.comstatic SkBenchmark* gF2(void* p) { return new DashBench(p, PARAM(gDots), 1, true); }
1484ad22753504828342e47627b12210c2c47e7290areed@google.comstatic SkBenchmark* gF3(void* p) { return new DashBench(p, PARAM(gDots), 4); }
1494ad22753504828342e47627b12210c2c47e7290areed@google.comstatic SkBenchmark* gF4(void* p) { return new RectDashBench(p, PARAM(gDots), 4); }
1504aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.com
1514aa1a70ab74e841def84367d771ac2b2202f41d2reed@google.comstatic BenchRegistry gR0(gF0);
15299a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.orgstatic BenchRegistry gR1(gF1);
15399a6ef48e396901b6cfb007b49d592ffac2bc597mike@reedtribe.orgstatic BenchRegistry gR2(gF2);
154ef85e3c52c551a66e537cc8bdcbad77bdc87ef19reed@google.comstatic BenchRegistry gR3(gF3);
1554ad22753504828342e47627b12210c2c47e7290areed@google.comstatic BenchRegistry gR4(gF4);
156