SkGraphics.cpp revision 34245c7871f6339de8cc2be8fb1090ca3cba54ef
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
52static 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
94static 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
106static 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
118static 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
149void SkGraphics::Init() {
150    SkGlobals::Init();
151
152#ifdef BUILD_EMBOSS_TABLE
153    SkEmbossMask_BuildTable();
154#endif
155#ifdef BUILD_RADIALGRADIENT_TABLE
156    SkRadialGradient_BuildTable();
157#endif
158
159#ifdef SK_DEBUGx
160    int i;
161
162    static const struct {
163        const char* fTypeName;
164        size_t      fSizeOf;
165    } gTypeSize[] = {
166        typesizeline(char),
167        typesizeline(short),
168        typesizeline(int),
169        typesizeline(long),
170        typesizeline(size_t),
171        typesizeline(void*),
172
173        typesizeline(S8CPU),
174        typesizeline(U8CPU),
175        typesizeline(S16CPU),
176        typesizeline(U16CPU),
177
178        typesizeline(SkPoint),
179        typesizeline(SkRect),
180        typesizeline(SkMatrix),
181        typesizeline(SkPath),
182        typesizeline(SkGlyph),
183        typesizeline(SkRefCnt),
184
185        typesizeline(SkPaint),
186        typesizeline(SkCanvas),
187        typesizeline(SkBlitter),
188        typesizeline(SkShader),
189        typesizeline(SkXfermode),
190        typesizeline(SkPathEffect)
191    };
192
193#ifdef SK_CPU_BENDIAN
194    SkDebugf("SkGraphics: big-endian\n");
195#else
196    SkDebugf("SkGraphics: little-endian\n");
197#endif
198
199    {
200        char    test = 0xFF;
201        int     itest = test;   // promote to int, see if it sign-extended
202        if (itest < 0)
203            SkDebugf("SkGraphics: char is signed\n");
204        else
205            SkDebugf("SkGraphics: char is unsigned\n");
206    }
207    for (i = 0; i < (int)SK_ARRAY_COUNT(gTypeSize); i++) {
208        SkDebugf("SkGraphics: sizeof(%s) = %d\n",
209                 gTypeSize[i].fTypeName, gTypeSize[i].fSizeOf);
210    }
211
212#endif
213
214    if (false)  // test asm fixmul
215    {
216        int j;
217        SkMSec now = SkTime::GetMSecs();
218        for (j = 0; j < BIG_LOOP_COUNT; j++) {
219            (void)SkFixedMul_portable(0x8000, 0x150000);
220        }
221        SkMSec now2 = SkTime::GetMSecs();
222        printf("-------- SkFixedMul_portable = %d\n", now2 - now);
223
224        for (j = 0; j < BIG_LOOP_COUNT; j++) {
225            (void)SkFixedMul(0x8000, 0x150000);
226        }
227        printf("-------- SkFixedMul = %d\n", SkTime::GetMSecs() - now2);
228
229        SkRandom rand;
230        for (j = 0; j < 10000; j++) {
231            SkFixed a = rand.nextS() >> 8;
232            SkFixed b = rand.nextS() >> 8;
233            SkFixed c1 = SkFixedMul_portable(a, b);
234            SkFixed c2 = SkFixedMul(a, b);
235            if (SkAbs32(c1 - c2) > 1)
236                printf("------ FixMul disagreement: (%x %x) slow=%x fast=%x\n", a, b, c1, c2);
237        }
238    }
239
240    if (false)  // test asm fractmul
241    {
242        int j;
243        SkMSec now = SkTime::GetMSecs();
244        for (j = 0; j < BIG_LOOP_COUNT; j++) {
245            (void)SkFractMul_portable(0x800000, 0x1500000);
246        }
247        SkMSec now2 = SkTime::GetMSecs();
248        printf("-------- SkFractMul_portable = %d\n", now2 - now);
249
250        for (j = 0; j < BIG_LOOP_COUNT; j++) {
251            (void)SkFractMul(0x800000, 0x1500000);
252        }
253        printf("-------- SkFractMul = %d\n", SkTime::GetMSecs() - now2);
254
255        SkRandom rand;
256        for (j = 0; j < 10000; j++) {
257            SkFixed a = rand.nextS() >> 1;
258            SkFixed b = rand.nextS() >> 1;
259            SkFixed c1 = SkFractMul_portable(a, b);
260            SkFixed c2 = SkFractMul(a, b);
261            if (SkAbs32(c1 - c2) > 1)
262                printf("------ FractMul disagreement: (%x %x) slow=%x fast=%x\n", a, b, c1, c2);
263        }
264    }
265
266    if (false)   // test asm clz
267    {
268        int j;
269        SkMSec now = SkTime::GetMSecs();
270        for (j = 0; j < BIG_LOOP_COUNT; j++) {
271            (void)SkCLZ_portable(now);
272        }
273        SkMSec now2 = SkTime::GetMSecs();
274        printf("-------- SkCLZ_portable = %d\n", now2 - now);
275
276        for (j = 0; j < BIG_LOOP_COUNT; j++) {
277            (void)SkCLZ(now);
278        }
279        printf("-------- SkCLZ = %d\n", SkTime::GetMSecs() - now2);
280
281        SkRandom rand;
282        for (j = 0; j < 10000; j++) {
283            uint32_t a = rand.nextU();
284            int c1 = SkCLZ_portable(a);
285            int c2 = SkCLZ(a);
286            if (c1 != c2)
287                printf("------ CLZ disagreement: (%x) slow=%x fast=%x\n", a, c1, c2);
288        }
289    }
290
291#ifdef SPEED_TEST
292    if (false) {
293        int i;
294        int (*proc)(int);
295
296        static const struct {
297            int (*proc)(int);
298            const char* name;
299        } gList[] = {
300            { test_s64, "Sk64" },
301            { test_native_64, "native" }
302        };
303
304        for (size_t j = 0; j < SK_ARRAY_COUNT(gList); j++) {
305            SkMSec now = SkTime::GetMSecs();
306            proc = gList[j].proc;
307            for (i = 0; i < BIG_LOOP_COUNT; i++) {
308                proc(i);
309            }
310            printf("-------- %s = %d\n", gList[j].name, SkTime::GetMSecs() - now);
311        }
312    }
313#endif
314
315    if (false) {
316        size_t i, size = 480;
317        char* buffer = (char*)sk_malloc_throw(size);
318        uint16_t* buffer16 = (uint16_t*)buffer;
319        uint32_t* buffer32 = (uint32_t*)buffer;
320
321        SkMSec now = SkTime::GetMSecs();
322        for (i = 0; i < 100000; i++) {
323            sk_memset16(buffer16, (uint16_t)i, size >> 1);
324        }
325        SkMSec now2 = SkTime::GetMSecs();
326        for (i = 0; i < 100000; i++) {
327            sk_memset16_portable(buffer16, (uint16_t)i, size >> 1);
328        }
329        SkMSec now3 = SkTime::GetMSecs();
330        printf("----------- memset16: native %d, portable %d\n", now2 - now, now3 - now2);
331
332        now = SkTime::GetMSecs();
333        for (i = 0; i < 100000; i++) {
334            sk_memset32(buffer32, i, size >> 2);
335        }
336        now2 = SkTime::GetMSecs();
337        for (i = 0; i < 100000; i++) {
338            sk_memset32_portable(buffer32, i, size >> 2);
339        }
340        now3 = SkTime::GetMSecs();
341        printf("----------- memset32: native %d, portable %d\n", now2 - now, now3 - now2);
342
343        sk_free(buffer);
344    }
345
346#ifdef SPEED_TEST
347    if (false) {
348        test_drawText(SkBitmap::kARGB_8888_Config, SK_ColorBLACK);
349        test_drawText(SkBitmap::kARGB_8888_Config, SK_ColorRED);
350        test_drawText(SkBitmap::kRGB_565_Config, SK_ColorBLACK);
351        test_drawText(SkBitmap::kRGB_565_Config, SK_ColorRED);
352    }
353#endif
354
355//    if (true) {
356//        test_sort();
357//    }
358}
359
360////////////////////////////////////////////////////////////////////////////
361
362#include "SkGlyphCache.h"
363
364void SkGraphics::Term() {
365    SkGraphics::SetFontCacheUsed(0);
366    SkGlobals::Term();
367}
368
369size_t SkGraphics::GetFontCacheUsed() {
370    return SkGlyphCache::GetCacheUsed();
371}
372
373bool SkGraphics::SetFontCacheUsed(size_t usageInBytes) {
374    return SkGlyphCache::SetCacheUsed(usageInBytes);
375}
376
377