11119c870651ccd34c0acb8fb2cdfad2c07d3116creed/*
21119c870651ccd34c0acb8fb2cdfad2c07d3116creed * Copyright 2014 Google Inc.
31119c870651ccd34c0acb8fb2cdfad2c07d3116creed *
41119c870651ccd34c0acb8fb2cdfad2c07d3116creed * Use of this source code is governed by a BSD-style license that can be
51119c870651ccd34c0acb8fb2cdfad2c07d3116creed * found in the LICENSE file.
61119c870651ccd34c0acb8fb2cdfad2c07d3116creed */
71119c870651ccd34c0acb8fb2cdfad2c07d3116creed
81119c870651ccd34c0acb8fb2cdfad2c07d3116creed#include "Benchmark.h"
91119c870651ccd34c0acb8fb2cdfad2c07d3116creed#include "SkGeometry.h"
101119c870651ccd34c0acb8fb2cdfad2c07d3116creed#include "SkRandom.h"
111119c870651ccd34c0acb8fb2cdfad2c07d3116creed#include "SkRect.h"
121119c870651ccd34c0acb8fb2cdfad2c07d3116creed
131119c870651ccd34c0acb8fb2cdfad2c07d3116creedclass GeometryBench : public Benchmark {
141119c870651ccd34c0acb8fb2cdfad2c07d3116creedpublic:
151119c870651ccd34c0acb8fb2cdfad2c07d3116creed    GeometryBench(const char suffix[]) : fVolatileInt(0) {
161119c870651ccd34c0acb8fb2cdfad2c07d3116creed        fName.printf("geo_%s", suffix);
171119c870651ccd34c0acb8fb2cdfad2c07d3116creed    }
181119c870651ccd34c0acb8fb2cdfad2c07d3116creed
1936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* onGetName() override {
201119c870651ccd34c0acb8fb2cdfad2c07d3116creed        return fName.c_str();
211119c870651ccd34c0acb8fb2cdfad2c07d3116creed    }
221119c870651ccd34c0acb8fb2cdfad2c07d3116creed
2336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool isSuitableFor(Backend backend) override {
241119c870651ccd34c0acb8fb2cdfad2c07d3116creed        return kNonRendering_Backend == backend;
251119c870651ccd34c0acb8fb2cdfad2c07d3116creed    }
261119c870651ccd34c0acb8fb2cdfad2c07d3116creed
271119c870651ccd34c0acb8fb2cdfad2c07d3116creedprotected:
281119c870651ccd34c0acb8fb2cdfad2c07d3116creed    volatile int fVolatileInt;
291119c870651ccd34c0acb8fb2cdfad2c07d3116creed
301119c870651ccd34c0acb8fb2cdfad2c07d3116creed    /**
311119c870651ccd34c0acb8fb2cdfad2c07d3116creed     *  Subclasses can call this to try to defeat the optimizer (with some result of their
321119c870651ccd34c0acb8fb2cdfad2c07d3116creed     *  inner loop), since it will fool the compiler into assuming that "n" is actually
331119c870651ccd34c0acb8fb2cdfad2c07d3116creed     *  needed somewhere, and since this method is not const, the member fields cannot
341119c870651ccd34c0acb8fb2cdfad2c07d3116creed     *  be assumed to be const before and after the call.
351119c870651ccd34c0acb8fb2cdfad2c07d3116creed     */
361119c870651ccd34c0acb8fb2cdfad2c07d3116creed    virtual void virtualCallToFoilOptimizers(int n) { fVolatileInt += n; }
371119c870651ccd34c0acb8fb2cdfad2c07d3116creed
381119c870651ccd34c0acb8fb2cdfad2c07d3116creedprivate:
391119c870651ccd34c0acb8fb2cdfad2c07d3116creed    SkString fName;
401119c870651ccd34c0acb8fb2cdfad2c07d3116creed};
411119c870651ccd34c0acb8fb2cdfad2c07d3116creed
421119c870651ccd34c0acb8fb2cdfad2c07d3116creedclass GeoRectBench : public GeometryBench {
431119c870651ccd34c0acb8fb2cdfad2c07d3116creedpublic:
441119c870651ccd34c0acb8fb2cdfad2c07d3116creed    GeoRectBench(const char suffix[]) : GeometryBench(suffix) {}
451119c870651ccd34c0acb8fb2cdfad2c07d3116creed
461119c870651ccd34c0acb8fb2cdfad2c07d3116creedprotected:
471119c870651ccd34c0acb8fb2cdfad2c07d3116creed    SkRect fRects[2048];
481119c870651ccd34c0acb8fb2cdfad2c07d3116creed
498a6697af95b340aad6dee7e6228048fa305c1e59joshualitt    virtual void onDelayedSetup() {
501119c870651ccd34c0acb8fb2cdfad2c07d3116creed        const SkScalar min = -100;
511119c870651ccd34c0acb8fb2cdfad2c07d3116creed        const SkScalar max = 100;
521119c870651ccd34c0acb8fb2cdfad2c07d3116creed        SkRandom rand;
531119c870651ccd34c0acb8fb2cdfad2c07d3116creed        for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
541119c870651ccd34c0acb8fb2cdfad2c07d3116creed            SkScalar x = rand.nextRangeScalar(min, max);
551119c870651ccd34c0acb8fb2cdfad2c07d3116creed            SkScalar y = rand.nextRangeScalar(min, max);
561119c870651ccd34c0acb8fb2cdfad2c07d3116creed            SkScalar w = rand.nextRangeScalar(min, max);
571119c870651ccd34c0acb8fb2cdfad2c07d3116creed            SkScalar h = rand.nextRangeScalar(min, max);
581119c870651ccd34c0acb8fb2cdfad2c07d3116creed            fRects[i].setXYWH(x, y, w, h);
591119c870651ccd34c0acb8fb2cdfad2c07d3116creed        }
601119c870651ccd34c0acb8fb2cdfad2c07d3116creed    }
611119c870651ccd34c0acb8fb2cdfad2c07d3116creed};
621119c870651ccd34c0acb8fb2cdfad2c07d3116creed
631119c870651ccd34c0acb8fb2cdfad2c07d3116creedclass GeoRectBench_intersect : public GeoRectBench {
641119c870651ccd34c0acb8fb2cdfad2c07d3116creedpublic:
651119c870651ccd34c0acb8fb2cdfad2c07d3116creed    GeoRectBench_intersect() : GeoRectBench("rect_intersect") {}
661119c870651ccd34c0acb8fb2cdfad2c07d3116creed
671119c870651ccd34c0acb8fb2cdfad2c07d3116creedprotected:
68a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
691119c870651ccd34c0acb8fb2cdfad2c07d3116creed        for (int outer = 0; outer < loops; ++outer) {
701119c870651ccd34c0acb8fb2cdfad2c07d3116creed            int count = 0;
711119c870651ccd34c0acb8fb2cdfad2c07d3116creed            for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
721119c870651ccd34c0acb8fb2cdfad2c07d3116creed                SkRect r = fRects[0];
731119c870651ccd34c0acb8fb2cdfad2c07d3116creed                count += r.intersect(fRects[i]);
741119c870651ccd34c0acb8fb2cdfad2c07d3116creed            }
751119c870651ccd34c0acb8fb2cdfad2c07d3116creed            this->virtualCallToFoilOptimizers(count);
761119c870651ccd34c0acb8fb2cdfad2c07d3116creed        }
771119c870651ccd34c0acb8fb2cdfad2c07d3116creed    }
781119c870651ccd34c0acb8fb2cdfad2c07d3116creed};
791119c870651ccd34c0acb8fb2cdfad2c07d3116creed
801119c870651ccd34c0acb8fb2cdfad2c07d3116creedclass GeoRectBench_intersect_rect : public GeoRectBench {
811119c870651ccd34c0acb8fb2cdfad2c07d3116creedpublic:
821119c870651ccd34c0acb8fb2cdfad2c07d3116creed    GeoRectBench_intersect_rect() : GeoRectBench("rect_intersect_rect") {}
831119c870651ccd34c0acb8fb2cdfad2c07d3116creed
841119c870651ccd34c0acb8fb2cdfad2c07d3116creedprotected:
85a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
861119c870651ccd34c0acb8fb2cdfad2c07d3116creed        for (int outer = 0; outer < loops; ++outer) {
871119c870651ccd34c0acb8fb2cdfad2c07d3116creed            int count = 0;
881119c870651ccd34c0acb8fb2cdfad2c07d3116creed            SkRect r;
891119c870651ccd34c0acb8fb2cdfad2c07d3116creed            for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
901119c870651ccd34c0acb8fb2cdfad2c07d3116creed                count += r.intersect(fRects[0], fRects[i]);
911119c870651ccd34c0acb8fb2cdfad2c07d3116creed            }
921119c870651ccd34c0acb8fb2cdfad2c07d3116creed            this->virtualCallToFoilOptimizers(count);
931119c870651ccd34c0acb8fb2cdfad2c07d3116creed        }
941119c870651ccd34c0acb8fb2cdfad2c07d3116creed    }
951119c870651ccd34c0acb8fb2cdfad2c07d3116creed};
961119c870651ccd34c0acb8fb2cdfad2c07d3116creed
971119c870651ccd34c0acb8fb2cdfad2c07d3116creedclass GeoRectBench_Intersects : public GeoRectBench {
981119c870651ccd34c0acb8fb2cdfad2c07d3116creedpublic:
991119c870651ccd34c0acb8fb2cdfad2c07d3116creed    GeoRectBench_Intersects() : GeoRectBench("rect_Intersects") {}
1009d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
1011119c870651ccd34c0acb8fb2cdfad2c07d3116creedprotected:
102a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
1031119c870651ccd34c0acb8fb2cdfad2c07d3116creed        for (int outer = 0; outer < loops; ++outer) {
1041119c870651ccd34c0acb8fb2cdfad2c07d3116creed            int count = 0;
1051119c870651ccd34c0acb8fb2cdfad2c07d3116creed            for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
1061119c870651ccd34c0acb8fb2cdfad2c07d3116creed                count += SkRect::Intersects(fRects[0], fRects[i]);
1071119c870651ccd34c0acb8fb2cdfad2c07d3116creed            }
1081119c870651ccd34c0acb8fb2cdfad2c07d3116creed            this->virtualCallToFoilOptimizers(count);
1091119c870651ccd34c0acb8fb2cdfad2c07d3116creed        }
1101119c870651ccd34c0acb8fb2cdfad2c07d3116creed    }
1111119c870651ccd34c0acb8fb2cdfad2c07d3116creed};
1121119c870651ccd34c0acb8fb2cdfad2c07d3116creed
11340636a53037eadd957b8e43f0961f640aaa93e84reedclass GeoRectBench_sort : public GeoRectBench {
11440636a53037eadd957b8e43f0961f640aaa93e84reedpublic:
11540636a53037eadd957b8e43f0961f640aaa93e84reed    GeoRectBench_sort() : GeoRectBench("rect_sort") {}
1169d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
11740636a53037eadd957b8e43f0961f640aaa93e84reedprotected:
118a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
11940636a53037eadd957b8e43f0961f640aaa93e84reed        for (int outer = 0; outer < loops; ++outer) {
12040636a53037eadd957b8e43f0961f640aaa93e84reed            for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
12140636a53037eadd957b8e43f0961f640aaa93e84reed                fRects[i].sort();
12240636a53037eadd957b8e43f0961f640aaa93e84reed            }
12340636a53037eadd957b8e43f0961f640aaa93e84reed        }
12440636a53037eadd957b8e43f0961f640aaa93e84reed    }
12540636a53037eadd957b8e43f0961f640aaa93e84reed};
12640636a53037eadd957b8e43f0961f640aaa93e84reed
1271119c870651ccd34c0acb8fb2cdfad2c07d3116creedDEF_BENCH( return new GeoRectBench_intersect; )
1281119c870651ccd34c0acb8fb2cdfad2c07d3116creedDEF_BENCH( return new GeoRectBench_intersect_rect; )
1291119c870651ccd34c0acb8fb2cdfad2c07d3116creedDEF_BENCH( return new GeoRectBench_Intersects; )
13040636a53037eadd957b8e43f0961f640aaa93e84reed
13140636a53037eadd957b8e43f0961f640aaa93e84reedDEF_BENCH( return new GeoRectBench_sort; )
13265cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed
13365cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed///////////////////////////////////////////////////////////////////////////////////////////////////
13465cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed
13540b7dd57ef1f4e91af72512d8ca57459b99d71bdreedclass QuadBenchBase : public GeometryBench {
13640b7dd57ef1f4e91af72512d8ca57459b99d71bdreedprotected:
1376b9ef90c029c7c783f156ffd6fb1ba047bec63e0reed    SkPoint fPts[4];
13865cb2cd2f7ad4146f055810b8bd77bff03a4e76ereedpublic:
13940b7dd57ef1f4e91af72512d8ca57459b99d71bdreed    QuadBenchBase(const char name[]) : GeometryBench(name) {
14065cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed        SkRandom rand;
1416b9ef90c029c7c783f156ffd6fb1ba047bec63e0reed        for (int i = 0; i < 4; ++i) {
14265cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed            fPts[i].set(rand.nextUScalar1(), rand.nextUScalar1());
14365cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed        }
14465cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed    }
14540b7dd57ef1f4e91af72512d8ca57459b99d71bdreed};
14640b7dd57ef1f4e91af72512d8ca57459b99d71bdreed
14740b7dd57ef1f4e91af72512d8ca57459b99d71bdreedclass EvalQuadAt0 : public QuadBenchBase {
14840b7dd57ef1f4e91af72512d8ca57459b99d71bdreedpublic:
14940b7dd57ef1f4e91af72512d8ca57459b99d71bdreed    EvalQuadAt0() : QuadBenchBase("evalquadat0") {}
15065cb2cd2f7ad4146f055810b8bd77bff03a4e76ereedprotected:
151a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
15265cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed        SkPoint result;
15365cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed        for (int outer = 0; outer < loops; ++outer) {
15440b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            SkEvalQuadAt(fPts, 0.5f, &result);
15540b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            SkEvalQuadAt(fPts, 0.5f, &result);
15640b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            SkEvalQuadAt(fPts, 0.5f, &result);
15740b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            SkEvalQuadAt(fPts, 0.5f, &result);
15865cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed        }
15965cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed    }
16065cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed};
16165cb2cd2f7ad4146f055810b8bd77bff03a4e76ereedDEF_BENCH( return new EvalQuadAt0; )
16265cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed
16340b7dd57ef1f4e91af72512d8ca57459b99d71bdreedclass EvalQuadAt1 : public QuadBenchBase {
16465cb2cd2f7ad4146f055810b8bd77bff03a4e76ereedpublic:
16540b7dd57ef1f4e91af72512d8ca57459b99d71bdreed    EvalQuadAt1() : QuadBenchBase("evalquadat1") {}
16640b7dd57ef1f4e91af72512d8ca57459b99d71bdreedprotected:
167a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
16840b7dd57ef1f4e91af72512d8ca57459b99d71bdreed        SkPoint result;
16940b7dd57ef1f4e91af72512d8ca57459b99d71bdreed        for (int outer = 0; outer < loops; ++outer) {
17040b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            result = SkEvalQuadAt(fPts, 0.5f);
17140b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            result = SkEvalQuadAt(fPts, 0.5f);
17240b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            result = SkEvalQuadAt(fPts, 0.5f);
17340b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            result = SkEvalQuadAt(fPts, 0.5f);
17465cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed        }
17565cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed    }
17640b7dd57ef1f4e91af72512d8ca57459b99d71bdreed};
17740b7dd57ef1f4e91af72512d8ca57459b99d71bdreedDEF_BENCH( return new EvalQuadAt1; )
17840b7dd57ef1f4e91af72512d8ca57459b99d71bdreed
17940b7dd57ef1f4e91af72512d8ca57459b99d71bdreed////////
18040b7dd57ef1f4e91af72512d8ca57459b99d71bdreed
18140b7dd57ef1f4e91af72512d8ca57459b99d71bdreedclass EvalQuadTangentAt0 : public QuadBenchBase {
18240b7dd57ef1f4e91af72512d8ca57459b99d71bdreedpublic:
18340b7dd57ef1f4e91af72512d8ca57459b99d71bdreed    EvalQuadTangentAt0() : QuadBenchBase("evalquadtangentat0") {}
18465cb2cd2f7ad4146f055810b8bd77bff03a4e76ereedprotected:
185a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
18640b7dd57ef1f4e91af72512d8ca57459b99d71bdreed        SkPoint result;
18765cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed        for (int outer = 0; outer < loops; ++outer) {
18896fcdcc219d2a0d3579719b84b28bede76efba64halcanary            SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
18996fcdcc219d2a0d3579719b84b28bede76efba64halcanary            SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
19096fcdcc219d2a0d3579719b84b28bede76efba64halcanary            SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
19196fcdcc219d2a0d3579719b84b28bede76efba64halcanary            SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
19265cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed        }
19365cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed    }
19465cb2cd2f7ad4146f055810b8bd77bff03a4e76ereed};
19540b7dd57ef1f4e91af72512d8ca57459b99d71bdreedDEF_BENCH( return new EvalQuadTangentAt0; )
19640b7dd57ef1f4e91af72512d8ca57459b99d71bdreed
19740b7dd57ef1f4e91af72512d8ca57459b99d71bdreedclass EvalQuadTangentAt1 : public QuadBenchBase {
19840b7dd57ef1f4e91af72512d8ca57459b99d71bdreedpublic:
19940b7dd57ef1f4e91af72512d8ca57459b99d71bdreed    EvalQuadTangentAt1() : QuadBenchBase("evalquadtangentat1") {}
20040b7dd57ef1f4e91af72512d8ca57459b99d71bdreedprotected:
201a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
20240b7dd57ef1f4e91af72512d8ca57459b99d71bdreed        SkPoint result;
20340b7dd57ef1f4e91af72512d8ca57459b99d71bdreed        for (int outer = 0; outer < loops; ++outer) {
20440b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            result = SkEvalQuadTangentAt(fPts, 0.5f);
20540b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            result = SkEvalQuadTangentAt(fPts, 0.5f);
20640b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            result = SkEvalQuadTangentAt(fPts, 0.5f);
20740b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            result = SkEvalQuadTangentAt(fPts, 0.5f);
20840b7dd57ef1f4e91af72512d8ca57459b99d71bdreed        }
20940b7dd57ef1f4e91af72512d8ca57459b99d71bdreed    }
21040b7dd57ef1f4e91af72512d8ca57459b99d71bdreed};
21140b7dd57ef1f4e91af72512d8ca57459b99d71bdreedDEF_BENCH( return new EvalQuadTangentAt1; )
21240b7dd57ef1f4e91af72512d8ca57459b99d71bdreed
21340b7dd57ef1f4e91af72512d8ca57459b99d71bdreed////////
21440b7dd57ef1f4e91af72512d8ca57459b99d71bdreed
215c08330f1601aeca7f10aeb2194118decbfbf83e1reedclass ChopQuadAt : public QuadBenchBase {
21640b7dd57ef1f4e91af72512d8ca57459b99d71bdreedpublic:
217c08330f1601aeca7f10aeb2194118decbfbf83e1reed    ChopQuadAt() : QuadBenchBase("chopquadat") {}
21840b7dd57ef1f4e91af72512d8ca57459b99d71bdreedprotected:
219a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
22040b7dd57ef1f4e91af72512d8ca57459b99d71bdreed        SkPoint dst[5];
22140b7dd57ef1f4e91af72512d8ca57459b99d71bdreed        for (int outer = 0; outer < loops; ++outer) {
22240b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            SkChopQuadAt(fPts, dst, 0.5f);
22340b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            SkChopQuadAt(fPts, dst, 0.5f);
22440b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            SkChopQuadAt(fPts, dst, 0.5f);
22540b7dd57ef1f4e91af72512d8ca57459b99d71bdreed            SkChopQuadAt(fPts, dst, 0.5f);
22640b7dd57ef1f4e91af72512d8ca57459b99d71bdreed        }
22740b7dd57ef1f4e91af72512d8ca57459b99d71bdreed    }
22840b7dd57ef1f4e91af72512d8ca57459b99d71bdreed};
229c08330f1601aeca7f10aeb2194118decbfbf83e1reedDEF_BENCH( return new ChopQuadAt; )
23040b7dd57ef1f4e91af72512d8ca57459b99d71bdreed
231c08330f1601aeca7f10aeb2194118decbfbf83e1reedclass ChopCubicAt : public QuadBenchBase {
23240b7dd57ef1f4e91af72512d8ca57459b99d71bdreedpublic:
233c08330f1601aeca7f10aeb2194118decbfbf83e1reed    ChopCubicAt() : QuadBenchBase("chopcubicat0") {}
2346b9ef90c029c7c783f156ffd6fb1ba047bec63e0reedprotected:
235a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
2366b9ef90c029c7c783f156ffd6fb1ba047bec63e0reed        SkPoint dst[7];
2376b9ef90c029c7c783f156ffd6fb1ba047bec63e0reed        for (int outer = 0; outer < loops; ++outer) {
2386b9ef90c029c7c783f156ffd6fb1ba047bec63e0reed            SkChopCubicAt(fPts, dst, 0.5f);
2396b9ef90c029c7c783f156ffd6fb1ba047bec63e0reed            SkChopCubicAt(fPts, dst, 0.5f);
2406b9ef90c029c7c783f156ffd6fb1ba047bec63e0reed            SkChopCubicAt(fPts, dst, 0.5f);
2416b9ef90c029c7c783f156ffd6fb1ba047bec63e0reed            SkChopCubicAt(fPts, dst, 0.5f);
2426b9ef90c029c7c783f156ffd6fb1ba047bec63e0reed        }
2436b9ef90c029c7c783f156ffd6fb1ba047bec63e0reed    }
2446b9ef90c029c7c783f156ffd6fb1ba047bec63e0reed};
245c08330f1601aeca7f10aeb2194118decbfbf83e1reedDEF_BENCH( return new ChopCubicAt; )
246