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 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 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 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 void 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 364 void SkGraphics::Term() { 365 SkGraphics::SetFontCacheUsed(0); 366 SkGlobals::Term(); 367 } 368 369 size_t SkGraphics::GetFontCacheUsed() { 370 return SkGlyphCache::GetCacheUsed(); 371 } 372 373 bool SkGraphics::SetFontCacheUsed(size_t usageInBytes) { 374 return SkGlyphCache::SetCacheUsed(usageInBytes); 375 } 376 377