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 "SkRefCnt.h"
10#include "SkThread.h"
11#include "SkWeakRefCnt.h"
12
13enum {
14    M = 2
15};
16
17class AtomicInc32 : public Benchmark {
18public:
19    AtomicInc32() : fX(0) {}
20
21    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
22        return backend == kNonRendering_Backend;
23    }
24
25protected:
26    virtual const char* onGetName() {
27        return "atomic_inc_32";
28    }
29
30    virtual void onDraw(const int loops, SkCanvas*) {
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 AtomicInc64 : public Benchmark {
42public:
43    AtomicInc64() : fX(0) {}
44
45    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
46        return backend == kNonRendering_Backend;
47    }
48
49protected:
50    virtual const char* onGetName() {
51        return "atomic_inc_64";
52    }
53
54    virtual void onDraw(const int loops, SkCanvas*) {
55        for (int i = 0; i < loops; ++i) {
56            sk_atomic_inc(&fX);
57        }
58    }
59
60private:
61    int64_t fX;
62    typedef Benchmark INHERITED;
63};
64
65class RefCntBench_Stack : public Benchmark {
66public:
67    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
68        return backend == kNonRendering_Backend;
69    }
70
71protected:
72    virtual const char* onGetName() {
73        return "ref_cnt_stack";
74    }
75
76    virtual void onDraw(const int loops, SkCanvas*) {
77        for (int i = 0; i < loops; ++i) {
78            SkRefCnt ref;
79            for (int j = 0; j < M; ++j) {
80                ref.ref();
81                ref.unref();
82            }
83        }
84    }
85
86private:
87    typedef Benchmark INHERITED;
88};
89
90class PlacedRefCnt : public SkRefCnt {
91public:
92    SK_DECLARE_INST_COUNT(PlacedRefCnt)
93
94    PlacedRefCnt() : SkRefCnt() { }
95    void operator delete(void*) { }
96
97private:
98    typedef SkRefCnt INHERITED;
99};
100
101class RefCntBench_Heap : public Benchmark {
102public:
103    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
104        return backend == kNonRendering_Backend;
105    }
106
107protected:
108    virtual const char* onGetName() {
109        return "ref_cnt_heap";
110    }
111
112    virtual void onDraw(const int loops, SkCanvas*) {
113        char memory[sizeof(PlacedRefCnt)];
114        for (int i = 0; i < loops; ++i) {
115            PlacedRefCnt* ref = new (memory) PlacedRefCnt();
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
128class RefCntBench_New : public Benchmark {
129public:
130    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
131        return backend == kNonRendering_Backend;
132    }
133
134protected:
135    virtual const char* onGetName() {
136        return "ref_cnt_new";
137    }
138
139    virtual void onDraw(const int loops, SkCanvas*) {
140        for (int i = 0; i < loops; ++i) {
141            SkRefCnt* ref = new SkRefCnt();
142            for (int j = 0; j < M; ++j) {
143                ref->ref();
144                ref->unref();
145            }
146            ref->unref();
147        }
148    }
149
150private:
151    typedef Benchmark INHERITED;
152};
153
154///////////////////////////////////////////////////////////////////////////////
155
156class WeakRefCntBench_Stack : public Benchmark {
157public:
158    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
159        return backend == kNonRendering_Backend;
160    }
161
162protected:
163    virtual const char* onGetName() {
164        return "ref_cnt_stack_weak";
165    }
166
167    virtual void onDraw(const int loops, SkCanvas*) {
168        for (int i = 0; i < loops; ++i) {
169            SkWeakRefCnt ref;
170            for (int j = 0; j < M; ++j) {
171                ref.ref();
172                ref.unref();
173            }
174        }
175    }
176
177private:
178    typedef Benchmark INHERITED;
179};
180
181class PlacedWeakRefCnt : public SkWeakRefCnt {
182public:
183    PlacedWeakRefCnt() : SkWeakRefCnt() { }
184    void operator delete(void*) { }
185};
186
187class WeakRefCntBench_Heap : public Benchmark {
188public:
189    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
190        return backend == kNonRendering_Backend;
191    }
192
193protected:
194    virtual const char* onGetName() {
195        return "ref_cnt_heap_weak";
196    }
197
198    virtual void onDraw(const int loops, SkCanvas*) {
199        char memory[sizeof(PlacedWeakRefCnt)];
200        for (int i = 0; i < loops; ++i) {
201            PlacedWeakRefCnt* ref = new (memory) PlacedWeakRefCnt();
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
214class WeakRefCntBench_New : public Benchmark {
215public:
216    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
217        return backend == kNonRendering_Backend;
218    }
219
220protected:
221    virtual const char* onGetName() {
222        return "ref_cnt_new_weak";
223    }
224
225    virtual void onDraw(const int loops, SkCanvas*) {
226        for (int i = 0; i < loops; ++i) {
227            SkWeakRefCnt* ref = new SkWeakRefCnt();
228            for (int j = 0; j < M; ++j) {
229                ref->ref();
230                ref->unref();
231            }
232            ref->unref();
233        }
234    }
235
236private:
237    typedef Benchmark INHERITED;
238};
239
240///////////////////////////////////////////////////////////////////////////////
241
242DEF_BENCH( return new AtomicInc32(); )
243DEF_BENCH( return new AtomicInc64(); )
244
245DEF_BENCH( return new RefCntBench_Stack(); )
246DEF_BENCH( return new RefCntBench_Heap(); )
247DEF_BENCH( return new RefCntBench_New(); )
248
249DEF_BENCH( return new WeakRefCntBench_Stack(); )
250DEF_BENCH( return new WeakRefCntBench_Heap(); )
251DEF_BENCH( return new WeakRefCntBench_New(); )
252