1/*
2 * Copyright 2012 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#include <memory>
8#include "Benchmark.h"
9#include "SkAtomics.h"
10#include "SkRefCnt.h"
11#include "SkWeakRefCnt.h"
12
13enum {
14    M = 2
15};
16
17class AtomicInc32 : public Benchmark {
18public:
19    AtomicInc32() : fX(0) {}
20
21    bool isSuitableFor(Backend backend) override {
22        return backend == kNonRendering_Backend;
23    }
24
25protected:
26    const char* onGetName() override {
27        return "atomic_inc_32";
28    }
29
30    void onDraw(int loops, SkCanvas*) override {
31        for (int i = 0; i < loops; ++i) {
32            sk_atomic_inc(&fX);
33        }
34    }
35
36private:
37    int32_t fX;
38    typedef Benchmark INHERITED;
39};
40
41class RefCntBench_Stack : public Benchmark {
42public:
43    bool isSuitableFor(Backend backend) override {
44        return backend == kNonRendering_Backend;
45    }
46
47protected:
48    const char* onGetName() override {
49        return "ref_cnt_stack";
50    }
51
52    void onDraw(int loops, SkCanvas*) override {
53        for (int i = 0; i < loops; ++i) {
54            SkRefCnt ref;
55            for (int j = 0; j < M; ++j) {
56                ref.ref();
57                ref.unref();
58            }
59        }
60    }
61
62private:
63    typedef Benchmark INHERITED;
64};
65
66class PlacedRefCnt : public SkRefCnt {
67public:
68    PlacedRefCnt() : SkRefCnt() { }
69    void operator delete(void*) { }
70
71private:
72    typedef SkRefCnt INHERITED;
73};
74
75class RefCntBench_Heap : public Benchmark {
76public:
77    bool isSuitableFor(Backend backend) override {
78        return backend == kNonRendering_Backend;
79    }
80
81protected:
82    const char* onGetName() override {
83        return "ref_cnt_heap";
84    }
85
86    void onDraw(int loops, SkCanvas*) override {
87        char memory[sizeof(PlacedRefCnt)];
88        for (int i = 0; i < loops; ++i) {
89            PlacedRefCnt* ref = new (memory) PlacedRefCnt();
90            for (int j = 0; j < M; ++j) {
91                ref->ref();
92                ref->unref();
93            }
94            ref->unref();
95        }
96    }
97
98private:
99    typedef Benchmark INHERITED;
100};
101
102class RefCntBench_New : public Benchmark {
103public:
104    bool isSuitableFor(Backend backend) override {
105        return backend == kNonRendering_Backend;
106    }
107
108protected:
109    const char* onGetName() override {
110        return "ref_cnt_new";
111    }
112
113    void onDraw(int loops, SkCanvas*) override {
114        for (int i = 0; i < loops; ++i) {
115            SkRefCnt* ref = new SkRefCnt();
116            for (int j = 0; j < M; ++j) {
117                ref->ref();
118                ref->unref();
119            }
120            ref->unref();
121        }
122    }
123
124private:
125    typedef Benchmark INHERITED;
126};
127
128///////////////////////////////////////////////////////////////////////////////
129
130class WeakRefCntBench_Stack : public Benchmark {
131public:
132    bool isSuitableFor(Backend backend) override {
133        return backend == kNonRendering_Backend;
134    }
135
136protected:
137    const char* onGetName() override {
138        return "ref_cnt_stack_weak";
139    }
140
141    void onDraw(int loops, SkCanvas*) override {
142        for (int i = 0; i < loops; ++i) {
143            SkWeakRefCnt ref;
144            for (int j = 0; j < M; ++j) {
145                ref.ref();
146                ref.unref();
147            }
148        }
149    }
150
151private:
152    typedef Benchmark INHERITED;
153};
154
155class PlacedWeakRefCnt : public SkWeakRefCnt {
156public:
157    PlacedWeakRefCnt() : SkWeakRefCnt() { }
158    void operator delete(void*) { }
159};
160
161class WeakRefCntBench_Heap : public Benchmark {
162public:
163    bool isSuitableFor(Backend backend) override {
164        return backend == kNonRendering_Backend;
165    }
166
167protected:
168    const char* onGetName() override {
169        return "ref_cnt_heap_weak";
170    }
171
172    void onDraw(int loops, SkCanvas*) override {
173        char memory[sizeof(PlacedWeakRefCnt)];
174        for (int i = 0; i < loops; ++i) {
175            PlacedWeakRefCnt* ref = new (memory) PlacedWeakRefCnt();
176            for (int j = 0; j < M; ++j) {
177                ref->ref();
178                ref->unref();
179            }
180            ref->unref();
181        }
182    }
183
184private:
185    typedef Benchmark INHERITED;
186};
187
188class WeakRefCntBench_New : public Benchmark {
189public:
190    bool isSuitableFor(Backend backend) override {
191        return backend == kNonRendering_Backend;
192    }
193
194protected:
195    const char* onGetName() override {
196        return "ref_cnt_new_weak";
197    }
198
199    void onDraw(int loops, SkCanvas*) override {
200        for (int i = 0; i < loops; ++i) {
201            SkWeakRefCnt* ref = new SkWeakRefCnt();
202            for (int j = 0; j < M; ++j) {
203                ref->ref();
204                ref->unref();
205            }
206            ref->unref();
207        }
208    }
209
210private:
211    typedef Benchmark INHERITED;
212};
213
214///////////////////////////////////////////////////////////////////////////////
215
216DEF_BENCH( return new AtomicInc32(); )
217
218DEF_BENCH( return new RefCntBench_Stack(); )
219DEF_BENCH( return new RefCntBench_Heap(); )
220DEF_BENCH( return new RefCntBench_New(); )
221
222DEF_BENCH( return new WeakRefCntBench_Stack(); )
223DEF_BENCH( return new WeakRefCntBench_Heap(); )
224DEF_BENCH( return new WeakRefCntBench_New(); )
225