1/*
2* Copyright 2014 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
8#include "Benchmark.h"
9#include "SkRandom.h"
10#include "SkSize.h"
11#include "SkTDArray.h"
12
13#if SK_SUPPORT_GPU
14
15#include "GrRectanizer_pow2.h"
16#include "GrRectanizer_skyline.h"
17
18/**
19 * This bench exercises Ganesh' GrRectanizer classes. It exercises the following
20 * rectanizers:
21 *      Pow2 Rectanizer
22 *      Skyline Rectanizer
23 * in the following cases:
24 *      random rects (e.g., pull-save-layers forward use case)
25 *      random power of two rects
26 *      small constant sized power of 2 rects (e.g., glyph cache use case)
27 */
28class RectanizerBench : public Benchmark {
29public:
30    static const int kWidth = 1024;
31    static const int kHeight = 1024;
32
33    enum RectanizerType {
34        kPow2_RectanizerType,
35        kSkyline_RectanizerType,
36    };
37
38    enum RectType {
39        kRand_RectType,
40        kRandPow2_RectType,
41        kSmallPow2_RectType
42    };
43
44    RectanizerBench(RectanizerType rectanizerType, RectType rectType)
45        : fName("rectanizer_")
46        , fRectanizerType(rectanizerType)
47        , fRectType(rectType) {
48
49        if (kPow2_RectanizerType == fRectanizerType) {
50            fName.append("pow2_");
51        } else {
52            SkASSERT(kSkyline_RectanizerType == fRectanizerType);
53            fName.append("skyline_");
54        }
55
56        if (kRand_RectType == fRectType) {
57            fName.append("rand");
58        } else if (kRandPow2_RectType == fRectType) {
59            fName.append("rand2");
60        } else {
61            SkASSERT(kSmallPow2_RectType == fRectType);
62            fName.append("sm2");
63        }
64    }
65
66protected:
67    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
68        return kNonRendering_Backend == backend;
69    }
70
71    virtual const char* onGetName() SK_OVERRIDE {
72        return fName.c_str();
73    }
74
75    virtual void onPreDraw() SK_OVERRIDE {
76        SkASSERT(NULL == fRectanizer.get());
77
78        if (kPow2_RectanizerType == fRectanizerType) {
79            fRectanizer.reset(SkNEW_ARGS(GrRectanizerPow2, (kWidth, kHeight)));
80        } else {
81            SkASSERT(kSkyline_RectanizerType == fRectanizerType);
82            fRectanizer.reset(SkNEW_ARGS(GrRectanizerSkyline, (kWidth, kHeight)));
83        }
84    }
85
86    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
87        SkRandom rand;
88        SkIPoint16 loc;
89        SkISize size;
90
91        for (int i = 0; i < loops; ++i) {
92            if (kRand_RectType == fRectType) {
93                size = SkISize::Make(rand.nextRangeU(1, kWidth / 2),
94                                     rand.nextRangeU(1, kHeight / 2));
95            } else if (kRandPow2_RectType == fRectType) {
96                size = SkISize::Make(GrNextPow2(rand.nextRangeU(1, kWidth / 2)),
97                                     GrNextPow2(rand.nextRangeU(1, kHeight / 2)));
98            } else {
99                SkASSERT(kSmallPow2_RectType == fRectType);
100                size = SkISize::Make(128, 128);
101            }
102
103            if (!fRectanizer->addRect(size.fWidth, size.fHeight, &loc)) {
104                // insert failed so clear out the rectanizer and give the
105                // current rect another try
106                fRectanizer->reset();
107                i--;
108            }
109        }
110
111        fRectanizer->reset();
112    }
113
114private:
115    SkString                    fName;
116    RectanizerType              fRectanizerType;
117    RectType                    fRectType;
118    SkAutoTDelete<GrRectanizer> fRectanizer;
119
120    typedef Benchmark INHERITED;
121};
122
123//////////////////////////////////////////////////////////////////////////////
124
125DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
126                                     RectanizerBench::kRand_RectType);)
127DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
128                                     RectanizerBench::kRandPow2_RectType);)
129DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
130                                     RectanizerBench::kSmallPow2_RectType);)
131DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
132                                     RectanizerBench::kRand_RectType);)
133DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
134                                     RectanizerBench::kRandPow2_RectType);)
135DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
136                                     RectanizerBench::kSmallPow2_RectType);)
137
138#endif
139