OLD | NEW |
| (Empty) |
1 /* libs/graphics/sgl/SkGraphics.cpp | |
2 ** | |
3 ** Copyright 2006, The Android Open Source Project | |
4 ** | |
5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
6 ** you may not use this file except in compliance with the License. | |
7 ** You may obtain a copy of the License at | |
8 ** | |
9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
10 ** | |
11 ** Unless required by applicable law or agreed to in writing, software | |
12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 ** See the License for the specific language governing permissions and | |
15 ** limitations under the License. | |
16 */ | |
17 | |
18 #include "SkGraphics.h" | |
19 | |
20 #include "Sk64.h" | |
21 #include "SkBlitter.h" | |
22 #include "SkCanvas.h" | |
23 #include "SkDOM.h" | |
24 #include "SkFloat.h" | |
25 #include "SkGeometry.h" | |
26 #include "SkGlobals.h" | |
27 #include "SkMath.h" | |
28 #include "SkMatrix.h" | |
29 #include "SkPath.h" | |
30 #include "SkPathEffect.h" | |
31 #include "SkPathMeasure.h" | |
32 #include "SkRandom.h" | |
33 #include "SkRefCnt.h" | |
34 #include "SkScalerContext.h" | |
35 #include "SkShader.h" | |
36 #include "SkStream.h" | |
37 #include "SkTSearch.h" | |
38 #include "SkTime.h" | |
39 #include "SkUtils.h" | |
40 #include "SkXfermode.h" | |
41 | |
42 #if 0 | |
43 | |
44 #define SK_SORT_TEMPLATE_TYPE int | |
45 #define SK_SORT_TEMPLATE_NAME sort_int | |
46 #define SK_SORT_TEMPLATE_CMP(a, b) ((a) - (b)) | |
47 #include "SkSortTemplate.h" | |
48 | |
49 #define SK_SORT_TEMPLATE_TYPE int* | |
50 #define SK_SORT_TEMPLATE_NAME sort_intptr | |
51 #define SK_SORT_TEMPLATE_CMP(a, b) (*(a) - *(b)) | |
52 #include "SkSortTemplate.h" | |
53 | |
54 static void test_sort() | |
55 { | |
56 int array[] = { 4, 3, 7, 5, 2, 5, 1, 2, 9, 6, 7, 4, 5, 3, 1, 0 }; | |
57 int* ptr[SK_ARRAY_COUNT(array)]; | |
58 int i, N = SK_ARRAY_COUNT(array) - 1; | |
59 | |
60 for (i = 0; i < N; i++) | |
61 printf(" %d", array[i]); | |
62 printf("\n"); | |
63 | |
64 for (i = 0; i < N; i++) | |
65 ptr[i] = &array[i]; | |
66 sort_intptr(ptr, N); | |
67 for (i = 0; i < N; i++) | |
68 printf(" %d", *ptr[i]); | |
69 printf("\n"); | |
70 | |
71 sort_int(array, N); | |
72 for (i = 0; i < N; i++) | |
73 printf(" %d", array[i]); | |
74 printf("\n"); | |
75 | |
76 } | |
77 #endif | |
78 | |
79 #define SPEED_TESTx | |
80 | |
81 #define typesizeline(type) { #type , sizeof(type) } | |
82 #define unittestline(type) { #type , type::UnitTest } | |
83 | |
84 | |
85 #ifdef BUILD_EMBOSS_TABLE | |
86 extern void SkEmbossMask_BuildTable(); | |
87 #endif | |
88 | |
89 #ifdef BUILD_RADIALGRADIENT_TABLE | |
90 extern void SkRadialGradient_BuildTable(); | |
91 #endif | |
92 | |
93 #define BIG_LOOP_COUNT 1000000 | |
94 #define TEXT_LOOP_COUNT 1000 | |
95 | |
96 #ifdef SPEED_TEST | |
97 static int test_s64(int i) | |
98 { | |
99 Sk64 a, b, c; | |
100 | |
101 c.set(0); | |
102 a.set(i); | |
103 b.setMul(i, i); | |
104 a.add(b); | |
105 a.add(c); | |
106 return c.getFixed(); | |
107 } | |
108 | |
109 static int test_native_64(int i) | |
110 { | |
111 int16_t a, b, c; | |
112 | |
113 c = 0; | |
114 a = i; | |
115 b = (int64_t)i * i; | |
116 a += b; | |
117 a += c; | |
118 return (int)(c >> 16); | |
119 } | |
120 | |
121 static void test_drawText(SkBitmap::Config config, SkColor color) | |
122 { | |
123 SkBitmap bm; | |
124 | |
125 bm.setConfig(config, 320, 240); | |
126 bm.allocPixels(); | |
127 | |
128 SkCanvas canvas(bm); | |
129 SkPaint paint; | |
130 | |
131 paint.setAntiAlias(true); | |
132 paint.setTextSize(SkIntToScalar(12)); | |
133 paint.setColor(color); | |
134 | |
135 SkScalar x = SkIntToScalar(20); | |
136 SkScalar y = SkIntToScalar(100); | |
137 const char* text = "Hamburgefons"; | |
138 size_t len = strlen(text); | |
139 | |
140 // draw once to populate the cache | |
141 canvas.drawText(text, len, x, y, paint); | |
142 | |
143 SkMSec now = SkTime::GetMSecs(); | |
144 for (int i = 0; i < TEXT_LOOP_COUNT; i++) | |
145 canvas.drawText(text, len, x, y, paint); | |
146 printf("----------- Config: %d, Color=%x, CPS = %g\n", config, color, | |
147 len * TEXT_LOOP_COUNT * 1000.0 / (SkTime::GetMSecs() - now)); | |
148 } | |
149 | |
150 #endif | |
151 | |
152 #include "SkFloatBits.h" | |
153 | |
154 static inline float fast_inc(float x) { | |
155 SkFloatIntUnion data; | |
156 data.fFloat = x; | |
157 data.fSignBitInt += 1; | |
158 return data.fFloat; | |
159 } | |
160 | |
161 extern float dummy(); | |
162 int time_math() { | |
163 SkMSec now; | |
164 int i; | |
165 int sum = 0; | |
166 const int repeat = 1000000; | |
167 float f; | |
168 | |
169 f = dummy(); | |
170 now = SkTime::GetMSecs(); | |
171 for (i = repeat - 1; i >= 0; --i) { | |
172 sum += (int)f; f = fast_inc(f); | |
173 sum += (int)f; f = fast_inc(f); | |
174 sum += (int)f; f = fast_inc(f); | |
175 sum += (int)f; f = fast_inc(f); | |
176 } | |
177 SkDebugf("---- native cast %d\n", SkTime::GetMSecs() - now); | |
178 | |
179 f = dummy(); | |
180 now = SkTime::GetMSecs(); | |
181 for (i = repeat - 1; i >= 0; --i) { | |
182 sum += SkFloatToIntCast(f); f = fast_inc(f); | |
183 sum += SkFloatToIntCast(f); f = fast_inc(f); | |
184 sum += SkFloatToIntCast(f); f = fast_inc(f); | |
185 sum += SkFloatToIntCast(f); f = fast_inc(f); | |
186 } | |
187 SkDebugf("---- hack cast %d\n", SkTime::GetMSecs() - now); | |
188 | |
189 f = dummy(); | |
190 now = SkTime::GetMSecs(); | |
191 for (i = repeat - 1; i >= 0; --i) { | |
192 sum += (int)floorf(f + 0.5f); f = fast_inc(f); | |
193 sum += (int)floorf(f + 0.5f); f = fast_inc(f); | |
194 sum += (int)floorf(f + 0.5f); f = fast_inc(f); | |
195 sum += (int)floorf(f + 0.5f); f = fast_inc(f); | |
196 } | |
197 SkDebugf("---- native round %d\n", SkTime::GetMSecs() - now); | |
198 | |
199 f = dummy(); | |
200 now = SkTime::GetMSecs(); | |
201 for (i = repeat - 1; i >= 0; --i) { | |
202 sum += SkFloatToIntRound(f); f = fast_inc(f); | |
203 sum += SkFloatToIntRound(f); f = fast_inc(f); | |
204 sum += SkFloatToIntRound(f); f = fast_inc(f); | |
205 sum += SkFloatToIntRound(f); f = fast_inc(f); | |
206 } | |
207 SkDebugf("---- hack round %d\n", SkTime::GetMSecs() - now); | |
208 | |
209 f = dummy(); | |
210 now = SkTime::GetMSecs(); | |
211 for (i = repeat - 1; i >= 0; --i) { | |
212 sum += SkFloat2Bits(floorf(f)); f = fast_inc(f); | |
213 sum += SkFloat2Bits(floorf(f)); f = fast_inc(f); | |
214 sum += SkFloat2Bits(floorf(f)); f = fast_inc(f); | |
215 sum += SkFloat2Bits(floorf(f)); f = fast_inc(f); | |
216 } | |
217 SkDebugf("---- native floor %d\n", SkTime::GetMSecs() - now); | |
218 | |
219 f = dummy(); | |
220 now = SkTime::GetMSecs(); | |
221 for (i = repeat - 1; i >= 0; --i) { | |
222 sum += SkFloatToIntFloor(f); f = fast_inc(f); | |
223 sum += SkFloatToIntFloor(f); f = fast_inc(f); | |
224 sum += SkFloatToIntFloor(f); f = fast_inc(f); | |
225 sum += SkFloatToIntFloor(f); f = fast_inc(f); | |
226 } | |
227 SkDebugf("---- hack floor %d\n", SkTime::GetMSecs() - now); | |
228 | |
229 return sum; | |
230 } | |
231 | |
232 static float time_intToFloat() { | |
233 const int repeat = 1000000; | |
234 int i, n; | |
235 SkMSec now; | |
236 float sum = 0; | |
237 | |
238 n = (int)dummy(); | |
239 now = SkTime::GetMSecs(); | |
240 for (i = repeat - 1; i >= 0; --i) { | |
241 sum += (float)n; n += 1; | |
242 sum += (float)n; n += 1; | |
243 sum += (float)n; n += 1; | |
244 sum += (float)n; n += 1; | |
245 } | |
246 SkDebugf("---- native i2f %d\n", SkTime::GetMSecs() - now); | |
247 | |
248 n = (int)dummy(); | |
249 now = SkTime::GetMSecs(); | |
250 for (i = repeat - 1; i >= 0; --i) { | |
251 sum += SkIntToFloatCast(n); n += 1; | |
252 sum += SkIntToFloatCast(n); n += 1; | |
253 sum += SkIntToFloatCast(n); n += 1; | |
254 sum += SkIntToFloatCast(n); n += 1; | |
255 } | |
256 SkDebugf("---- check i2f %d\n", SkTime::GetMSecs() - now); | |
257 | |
258 n = (int)dummy(); | |
259 now = SkTime::GetMSecs(); | |
260 for (i = repeat - 1; i >= 0; --i) { | |
261 sum += SkIntToFloatCast_NoOverflowCheck(n); n += 1; | |
262 sum += SkIntToFloatCast_NoOverflowCheck(n); n += 1; | |
263 sum += SkIntToFloatCast_NoOverflowCheck(n); n += 1; | |
264 sum += SkIntToFloatCast_NoOverflowCheck(n); n += 1; | |
265 } | |
266 SkDebugf("---- nocheck i2f %d\n", SkTime::GetMSecs() - now); | |
267 | |
268 return sum; | |
269 } | |
270 | |
271 void SkGraphics::Init(bool runUnitTests) | |
272 { | |
273 SkGlobals::Init(); | |
274 | |
275 // time_math(); | |
276 // time_intToFloat(); | |
277 | |
278 #ifdef BUILD_EMBOSS_TABLE | |
279 SkEmbossMask_BuildTable(); | |
280 #endif | |
281 #ifdef BUILD_RADIALGRADIENT_TABLE | |
282 SkRadialGradient_BuildTable(); | |
283 #endif | |
284 | |
285 #ifdef SK_SUPPORT_UNITTEST | |
286 if (runUnitTests == false) | |
287 return; | |
288 int i; | |
289 | |
290 static const struct { | |
291 const char* fTypeName; | |
292 size_t fSizeOf; | |
293 } gTypeSize[] = { | |
294 typesizeline(char), | |
295 typesizeline(short), | |
296 typesizeline(int), | |
297 typesizeline(long), | |
298 typesizeline(size_t), | |
299 typesizeline(void*), | |
300 | |
301 typesizeline(S8CPU), | |
302 typesizeline(U8CPU), | |
303 typesizeline(S16CPU), | |
304 typesizeline(U16CPU), | |
305 | |
306 typesizeline(SkPoint), | |
307 typesizeline(SkRect), | |
308 typesizeline(SkMatrix), | |
309 typesizeline(SkPath), | |
310 typesizeline(SkGlyph), | |
311 typesizeline(SkRefCnt), | |
312 | |
313 typesizeline(SkPaint), | |
314 typesizeline(SkCanvas), | |
315 typesizeline(SkBlitter), | |
316 typesizeline(SkShader), | |
317 typesizeline(SkXfermode), | |
318 typesizeline(SkPathEffect) | |
319 }; | |
320 | |
321 #ifdef SK_CPU_BENDIAN | |
322 SkDebugf("SkGraphics: big-endian\n"); | |
323 #else | |
324 SkDebugf("SkGraphics: little-endian\n"); | |
325 #endif | |
326 | |
327 { | |
328 char test = 0xFF; | |
329 int itest = test; // promote to int, see if it sign-extended | |
330 if (itest < 0) | |
331 SkDebugf("SkGraphics: char is signed\n"); | |
332 else | |
333 SkDebugf("SkGraphics: char is unsigned\n"); | |
334 } | |
335 for (i = 0; i < (int)SK_ARRAY_COUNT(gTypeSize); i++) | |
336 SkDebugf("SkGraphics: sizeof(%s) = %d\n", gTypeSize[i].fTypeName, gTypeS
ize[i].fSizeOf); | |
337 | |
338 static const struct { | |
339 const char* fTypeName; | |
340 void (*fUnitTest)(); | |
341 } gUnitTests[] = { | |
342 unittestline(Sk64), | |
343 unittestline(SkMath), | |
344 unittestline(SkUtils), | |
345 unittestline(SkString), | |
346 unittestline(SkMatrix), | |
347 unittestline(SkGeometry), | |
348 unittestline(SkPath), | |
349 unittestline(SkPathMeasure), | |
350 unittestline(SkStream), | |
351 unittestline(SkWStream), | |
352 }; | |
353 | |
354 for (i = 0; i < (int)SK_ARRAY_COUNT(gUnitTests); i++) | |
355 { | |
356 SkDebugf("SkGraphics: Running UnitTest for %s\n", gUnitTests[i].fTypeNam
e); | |
357 gUnitTests[i].fUnitTest(); | |
358 SkDebugf("SkGraphics: End UnitTest for %s\n", gUnitTests[i].fTypeName); | |
359 } | |
360 SkQSort_UnitTest(); | |
361 | |
362 #endif | |
363 | |
364 if (false) // test asm fixmul | |
365 { | |
366 int j; | |
367 SkMSec now = SkTime::GetMSecs(); | |
368 for (j = 0; j < BIG_LOOP_COUNT; j++) { | |
369 (void)SkFixedMul_portable(0x8000, 0x150000); | |
370 } | |
371 SkMSec now2 = SkTime::GetMSecs(); | |
372 printf("-------- SkFixedMul_portable = %d\n", now2 - now); | |
373 | |
374 for (j = 0; j < BIG_LOOP_COUNT; j++) { | |
375 (void)SkFixedMul(0x8000, 0x150000); | |
376 } | |
377 printf("-------- SkFixedMul = %d\n", SkTime::GetMSecs() - now2); | |
378 | |
379 SkRandom rand; | |
380 for (j = 0; j < 10000; j++) { | |
381 SkFixed a = rand.nextS() >> 8; | |
382 SkFixed b = rand.nextS() >> 8; | |
383 SkFixed c1 = SkFixedMul_portable(a, b); | |
384 SkFixed c2 = SkFixedMul(a, b); | |
385 if (SkAbs32(c1 - c2) > 1) | |
386 printf("------ FixMul disagreement: (%x %x) slow=%x fast=%x\n",
a, b, c1, c2); | |
387 } | |
388 } | |
389 | |
390 if (false) // test asm fractmul | |
391 { | |
392 int j; | |
393 SkMSec now = SkTime::GetMSecs(); | |
394 for (j = 0; j < BIG_LOOP_COUNT; j++) { | |
395 (void)SkFractMul_portable(0x800000, 0x1500000); | |
396 } | |
397 SkMSec now2 = SkTime::GetMSecs(); | |
398 printf("-------- SkFractMul_portable = %d\n", now2 - now); | |
399 | |
400 for (j = 0; j < BIG_LOOP_COUNT; j++) { | |
401 (void)SkFractMul(0x800000, 0x1500000); | |
402 } | |
403 printf("-------- SkFractMul = %d\n", SkTime::GetMSecs() - now2); | |
404 | |
405 SkRandom rand; | |
406 for (j = 0; j < 10000; j++) { | |
407 SkFixed a = rand.nextS() >> 1; | |
408 SkFixed b = rand.nextS() >> 1; | |
409 SkFixed c1 = SkFractMul_portable(a, b); | |
410 SkFixed c2 = SkFractMul(a, b); | |
411 if (SkAbs32(c1 - c2) > 1) | |
412 printf("------ FractMul disagreement: (%x %x) slow=%x fast=%x\n"
, a, b, c1, c2); | |
413 } | |
414 } | |
415 | |
416 if (false) // test asm clz | |
417 { | |
418 int j; | |
419 SkMSec now = SkTime::GetMSecs(); | |
420 for (j = 0; j < BIG_LOOP_COUNT; j++) { | |
421 (void)SkCLZ_portable(now); | |
422 } | |
423 SkMSec now2 = SkTime::GetMSecs(); | |
424 printf("-------- SkCLZ_portable = %d\n", now2 - now); | |
425 | |
426 for (j = 0; j < BIG_LOOP_COUNT; j++) { | |
427 (void)SkCLZ(now); | |
428 } | |
429 printf("-------- SkCLZ = %d\n", SkTime::GetMSecs() - now2); | |
430 | |
431 SkRandom rand; | |
432 for (j = 0; j < 10000; j++) { | |
433 uint32_t a = rand.nextU(); | |
434 int c1 = SkCLZ_portable(a); | |
435 int c2 = SkCLZ(a); | |
436 if (c1 != c2) | |
437 printf("------ CLZ disagreement: (%x) slow=%x fast=%x\n", a, c1,
c2); | |
438 } | |
439 } | |
440 | |
441 #ifdef SPEED_TEST | |
442 if (false) { | |
443 int i; | |
444 int (*proc)(int); | |
445 | |
446 static const struct { | |
447 int (*proc)(int); | |
448 const char* name; | |
449 } gList[] = { | |
450 { test_s64, "Sk64" }, | |
451 { test_native_64, "native" } | |
452 }; | |
453 | |
454 for (size_t j = 0; j < SK_ARRAY_COUNT(gList); j++) { | |
455 SkMSec now = SkTime::GetMSecs(); | |
456 proc = gList[j].proc; | |
457 for (i = 0; i < BIG_LOOP_COUNT; i++) { | |
458 proc(i); | |
459 } | |
460 printf("-------- %s = %d\n", gList[j].name, SkTime::GetMSecs() - now
); | |
461 } | |
462 } | |
463 #endif | |
464 | |
465 if (false) { | |
466 size_t i, size = 480; | |
467 char* buffer = (char*)sk_malloc_throw(size); | |
468 uint16_t* buffer16 = (uint16_t*)buffer; | |
469 uint32_t* buffer32 = (uint32_t*)buffer; | |
470 | |
471 SkMSec now = SkTime::GetMSecs(); | |
472 for (i = 0; i < 100000; i++) { | |
473 sk_memset16(buffer16, (uint16_t)i, size >> 1); | |
474 } | |
475 SkMSec now2 = SkTime::GetMSecs(); | |
476 for (i = 0; i < 100000; i++) { | |
477 sk_memset16_portable(buffer16, (uint16_t)i, size >> 1); | |
478 } | |
479 SkMSec now3 = SkTime::GetMSecs(); | |
480 printf("----------- memset16: native %d, portable %d\n", now2 - now, now
3 - now2); | |
481 | |
482 now = SkTime::GetMSecs(); | |
483 for (i = 0; i < 100000; i++) { | |
484 sk_memset32(buffer32, i, size >> 2); | |
485 } | |
486 now2 = SkTime::GetMSecs(); | |
487 for (i = 0; i < 100000; i++) { | |
488 sk_memset32_portable(buffer32, i, size >> 2); | |
489 } | |
490 now3 = SkTime::GetMSecs(); | |
491 printf("----------- memset32: native %d, portable %d\n", now2 - now, now
3 - now2); | |
492 | |
493 sk_free(buffer); | |
494 } | |
495 | |
496 #ifdef SPEED_TEST | |
497 if (false) { | |
498 test_drawText(SkBitmap::kARGB_8888_Config, SK_ColorBLACK); | |
499 test_drawText(SkBitmap::kARGB_8888_Config, SK_ColorRED); | |
500 test_drawText(SkBitmap::kRGB_565_Config, SK_ColorBLACK); | |
501 test_drawText(SkBitmap::kRGB_565_Config, SK_ColorRED); | |
502 } | |
503 #endif | |
504 | |
505 // if (true) { | |
506 // test_sort(); | |
507 // } | |
508 } | |
509 | |
510 //////////////////////////////////////////////////////////////////////////// | |
511 | |
512 #include "SkGlyphCache.h" | |
513 #include "SkImageDecoder.h" | |
514 | |
515 void SkGraphics::Term() { | |
516 SkGraphics::SetFontCacheUsed(0); | |
517 SkGlobals::Term(); | |
518 } | |
519 | |
520 size_t SkGraphics::GetFontCacheUsed() { | |
521 return SkGlyphCache::GetCacheUsed(); | |
522 } | |
523 | |
524 bool SkGraphics::SetFontCacheUsed(size_t usageInBytes) { | |
525 return SkGlyphCache::SetCacheUsed(usageInBytes); | |
526 } | |
527 | |
528 float dummy() { return 1.25f; } | |
OLD | NEW |