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