aboutsummaryrefslogtreecommitdiffhomepage
path: root/bench/RectanizerBench.cpp
blob: a5fad063666916ada232c571852af1390dc4b37f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "Benchmark.h"
#include "SkRandom.h"
#include "SkSize.h"
#include "SkTDArray.h"

#if SK_SUPPORT_GPU

#include "GrRectanizer_pow2.h"
#include "GrRectanizer_skyline.h"

/**
 * This bench exercises Ganesh' GrRectanizer classes. It exercises the following
 * rectanizers:
 *      Pow2 Rectanizer
 *      Skyline Rectanizer
 * in the following cases:
 *      random rects (e.g., pull-save-layers forward use case)
 *      random power of two rects
 *      small constant sized power of 2 rects (e.g., glyph cache use case)
 */
class RectanizerBench : public Benchmark {
public:
    static const int kWidth = 1024;
    static const int kHeight = 1024;

    enum RectanizerType {
        kPow2_RectanizerType,
        kSkyline_RectanizerType,
    };

    enum RectType {
        kRand_RectType,
        kRandPow2_RectType,
        kSmallPow2_RectType
    };

    RectanizerBench(RectanizerType rectanizerType, RectType rectType) 
        : fName("rectanizer_")
        , fRectanizerType(rectanizerType)
        , fRectType(rectType) {

        if (kPow2_RectanizerType == fRectanizerType) {
            fName.append("pow2_");
        } else {
            SkASSERT(kSkyline_RectanizerType == fRectanizerType);
            fName.append("skyline_");
        }

        if (kRand_RectType == fRectType) {
            fName.append("rand");
        } else if (kRandPow2_RectType == fRectType) {
            fName.append("rand2");
        } else {
            SkASSERT(kSmallPow2_RectType == fRectType);
            fName.append("sm2");
        }
    }

protected:
    bool isSuitableFor(Backend backend) SK_OVERRIDE {
        return kNonRendering_Backend == backend;
    }

    const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }

    void onPreDraw() SK_OVERRIDE {
        SkASSERT(NULL == fRectanizer.get());

        if (kPow2_RectanizerType == fRectanizerType) {
            fRectanizer.reset(SkNEW_ARGS(GrRectanizerPow2, (kWidth, kHeight)));
        } else {
            SkASSERT(kSkyline_RectanizerType == fRectanizerType);
            fRectanizer.reset(SkNEW_ARGS(GrRectanizerSkyline, (kWidth, kHeight)));
        }
    }

    void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
        SkRandom rand;
        SkIPoint16 loc;
        SkISize size;

        for (int i = 0; i < loops; ++i) {
            if (kRand_RectType == fRectType) {
                size = SkISize::Make(rand.nextRangeU(1, kWidth / 2),
                                     rand.nextRangeU(1, kHeight / 2));
            } else if (kRandPow2_RectType == fRectType) {
                size = SkISize::Make(GrNextPow2(rand.nextRangeU(1, kWidth / 2)),
                                     GrNextPow2(rand.nextRangeU(1, kHeight / 2)));
            } else {
                SkASSERT(kSmallPow2_RectType == fRectType);
                size = SkISize::Make(128, 128);
            }

            if (!fRectanizer->addRect(size.fWidth, size.fHeight, &loc)) {
                // insert failed so clear out the rectanizer and give the
                // current rect another try
                fRectanizer->reset();
                i--;
            }
        }

        fRectanizer->reset();
    }

private:
    SkString                    fName;
    RectanizerType              fRectanizerType;
    RectType                    fRectType;
    SkAutoTDelete<GrRectanizer> fRectanizer;

    typedef Benchmark INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
                                     RectanizerBench::kRand_RectType);)
DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
                                     RectanizerBench::kRandPow2_RectType);)
DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType,
                                     RectanizerBench::kSmallPow2_RectType);)
DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
                                     RectanizerBench::kRand_RectType);)
DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
                                     RectanizerBench::kRandPow2_RectType);)
DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
                                     RectanizerBench::kSmallPow2_RectType);)

#endif