OLD | NEW |
| (Empty) |
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 #if SK_SUPPORT_GPU | |
9 | |
10 #include "SkMatrix.h" | |
11 #include "SkString.h" | |
12 #include "GrTRecorder.h" | |
13 #include "Test.h" | |
14 | |
15 //////////////////////////////////////////////////////////////////////////////// | |
16 | |
17 static int activeRecorderItems = 0; | |
18 | |
19 class IntWrapper { | |
20 public: | |
21 IntWrapper() {} | |
22 IntWrapper(int value) : fValue(value) {} | |
23 operator int() { return fValue; } | |
24 private: | |
25 int fValue; | |
26 }; | |
27 | |
28 static void test_empty_back(skiatest::Reporter* reporter) { | |
29 GrTRecorder<IntWrapper, int> recorder(0); | |
30 | |
31 REPORTER_ASSERT(reporter, recorder.empty()); | |
32 | |
33 for (int i = 0; i < 100; ++i) { | |
34 REPORTER_ASSERT(reporter, i == *GrNEW_APPEND_TO_RECORDER(recorder, IntWr
apper, (i))); | |
35 REPORTER_ASSERT(reporter, !recorder.empty()); | |
36 REPORTER_ASSERT(reporter, i == recorder.back()); | |
37 } | |
38 | |
39 REPORTER_ASSERT(reporter, !recorder.empty()); | |
40 | |
41 recorder.reset(); | |
42 | |
43 REPORTER_ASSERT(reporter, recorder.empty()); | |
44 } | |
45 | |
46 struct ExtraData { | |
47 typedef GrTRecorder<ExtraData, int> Recorder; | |
48 | |
49 ExtraData(int i) : fData(i) { | |
50 int* extraData = this->extraData(); | |
51 for (int j = 0; j < i; j++) { | |
52 extraData[j] = i; | |
53 } | |
54 ++activeRecorderItems; | |
55 } | |
56 ~ExtraData() { | |
57 --activeRecorderItems; | |
58 } | |
59 int* extraData() { | |
60 return reinterpret_cast<int*>(Recorder::GetDataForItem(this)); | |
61 } | |
62 int fData; | |
63 }; | |
64 | |
65 static void test_extra_data(skiatest::Reporter* reporter) { | |
66 ExtraData::Recorder recorder(0); | |
67 for (int i = 0; i < 100; ++i) { | |
68 GrNEW_APPEND_WITH_DATA_TO_RECORDER(recorder, ExtraData, (i), i * sizeof(
int)); | |
69 } | |
70 REPORTER_ASSERT(reporter, 100 == activeRecorderItems); | |
71 | |
72 ExtraData::Recorder::Iter iter(recorder); | |
73 for (int i = 0; i < 100; ++i) { | |
74 REPORTER_ASSERT(reporter, iter.next()); | |
75 REPORTER_ASSERT(reporter, i == iter->fData); | |
76 for (int j = 0; j < i; j++) { | |
77 REPORTER_ASSERT(reporter, i == iter->extraData()[j]); | |
78 } | |
79 } | |
80 REPORTER_ASSERT(reporter, !iter.next()); | |
81 | |
82 recorder.reset(); | |
83 REPORTER_ASSERT(reporter, 0 == activeRecorderItems); | |
84 } | |
85 | |
86 enum ClassType { | |
87 kBase_ClassType, | |
88 kSubclass_ClassType, | |
89 kSubSubclass_ClassType, | |
90 kSubclassExtraData_ClassType, | |
91 kSubclassEmpty_ClassType, | |
92 | |
93 kNumClassTypes | |
94 }; | |
95 | |
96 class Base { | |
97 public: | |
98 typedef GrTRecorder<Base, void*> Recorder; | |
99 | |
100 Base() { | |
101 fMatrix.reset(); | |
102 ++activeRecorderItems; | |
103 } | |
104 | |
105 virtual ~Base() { --activeRecorderItems; } | |
106 | |
107 virtual ClassType getType() { return kBase_ClassType; } | |
108 | |
109 virtual void validate(skiatest::Reporter* reporter) const { | |
110 REPORTER_ASSERT(reporter, fMatrix.isIdentity()); | |
111 } | |
112 | |
113 private: | |
114 SkMatrix fMatrix; | |
115 }; | |
116 | |
117 class Subclass : public Base { | |
118 public: | |
119 Subclass() : fString("Lorem ipsum dolor sit amet") {} | |
120 | |
121 virtual ClassType getType() { return kSubclass_ClassType; } | |
122 | |
123 virtual void validate(skiatest::Reporter* reporter) const { | |
124 Base::validate(reporter); | |
125 REPORTER_ASSERT(reporter, !strcmp("Lorem ipsum dolor sit amet", fString.
c_str())); | |
126 } | |
127 | |
128 private: | |
129 SkString fString; | |
130 }; | |
131 | |
132 class SubSubclass : public Subclass { | |
133 public: | |
134 SubSubclass() : fInt(1234), fFloat(1.234f) {} | |
135 | |
136 virtual ClassType getType() { return kSubSubclass_ClassType; } | |
137 | |
138 virtual void validate(skiatest::Reporter* reporter) const { | |
139 Subclass::validate(reporter); | |
140 REPORTER_ASSERT(reporter, 1234 == fInt); | |
141 REPORTER_ASSERT(reporter, 1.234f == fFloat); | |
142 } | |
143 | |
144 private: | |
145 int fInt; | |
146 float fFloat; | |
147 }; | |
148 | |
149 class SubclassExtraData : public Base { | |
150 public: | |
151 SubclassExtraData(int length) : fLength(length) { | |
152 int* data = reinterpret_cast<int*>(Recorder::GetDataForItem(this)); | |
153 for (int i = 0; i < fLength; ++i) { | |
154 data[i] = ValueAt(i); | |
155 } | |
156 } | |
157 | |
158 virtual ClassType getType() { return kSubclassExtraData_ClassType; } | |
159 | |
160 virtual void validate(skiatest::Reporter* reporter) const { | |
161 Base::validate(reporter); | |
162 const int* data = reinterpret_cast<const int*>(Recorder::GetDataForItem(
this)); | |
163 for (int i = 0; i < fLength; ++i) { | |
164 REPORTER_ASSERT(reporter, ValueAt(i) == data[i]); | |
165 } | |
166 } | |
167 | |
168 private: | |
169 static int ValueAt(uint64_t i) { return static_cast<int>(123456789 + 9876543
21 * i); } | |
170 int fLength; | |
171 }; | |
172 | |
173 class SubclassEmpty : public Base { | |
174 public: | |
175 virtual ClassType getType() { return kSubclassEmpty_ClassType; } | |
176 }; | |
177 | |
178 static void test_subclasses(skiatest::Reporter* reporter) { | |
179 class Order { | |
180 public: | |
181 Order() { this->reset(); } | |
182 void reset() { fCurrent = 0; } | |
183 ClassType next() { | |
184 fCurrent = 1664525 * fCurrent + 1013904223; | |
185 return static_cast<ClassType>(fCurrent % kNumClassTypes); | |
186 } | |
187 private: | |
188 uint32_t fCurrent; | |
189 }; | |
190 | |
191 Base::Recorder recorder(1024); | |
192 | |
193 Order order; | |
194 for (int i = 0; i < 1000; i++) { | |
195 switch (order.next()) { | |
196 case kBase_ClassType: | |
197 GrNEW_APPEND_TO_RECORDER(recorder, Base, ()); | |
198 break; | |
199 | |
200 case kSubclass_ClassType: | |
201 GrNEW_APPEND_TO_RECORDER(recorder, Subclass, ()); | |
202 break; | |
203 | |
204 case kSubSubclass_ClassType: | |
205 GrNEW_APPEND_TO_RECORDER(recorder, SubSubclass, ()); | |
206 break; | |
207 | |
208 case kSubclassExtraData_ClassType: | |
209 GrNEW_APPEND_WITH_DATA_TO_RECORDER(recorder, SubclassExtraData,
(i), sizeof(int) * i); | |
210 break; | |
211 | |
212 case kSubclassEmpty_ClassType: | |
213 GrNEW_APPEND_TO_RECORDER(recorder, SubclassEmpty, ()); | |
214 break; | |
215 | |
216 default: | |
217 reporter->reportFailed(SkString("Invalid class type")); | |
218 break; | |
219 } | |
220 } | |
221 REPORTER_ASSERT(reporter, 1000 == activeRecorderItems); | |
222 | |
223 order.reset(); | |
224 Base::Recorder::Iter iter(recorder); | |
225 for (int i = 0; i < 1000; ++i) { | |
226 REPORTER_ASSERT(reporter, iter.next()); | |
227 REPORTER_ASSERT(reporter, order.next() == iter->getType()); | |
228 iter->validate(reporter); | |
229 } | |
230 REPORTER_ASSERT(reporter, !iter.next()); | |
231 | |
232 // Don't reset the recorder. It should automatically destruct all its items. | |
233 } | |
234 | |
235 DEF_GPUTEST(GrTRecorder, reporter, factory) { | |
236 test_empty_back(reporter); | |
237 | |
238 test_extra_data(reporter); | |
239 REPORTER_ASSERT(reporter, 0 == activeRecorderItems); // test_extra_data shou
ld call reset(). | |
240 | |
241 test_subclasses(reporter); | |
242 REPORTER_ASSERT(reporter, 0 == activeRecorderItems); // Ensure ~GrTRecorder
invokes dtors. | |
243 } | |
244 | |
245 #endif | |
OLD | NEW |