SkGraphics.cpp revision 2043f7d009a795e164c58f4674e6b879aeb679c9
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 149#ifdef SK_CAN_USE_FLOAT 150#include "SkFloatBits.h" 151 152static inline float fast_inc(float x) { 153 SkFloatIntUnion data; 154 data.fFloat = x; 155 data.fSignBitInt += 1; 156 return data.fFloat; 157} 158 159extern float dummy(); 160int 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 231static 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 272void 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 493void SkGraphics::Term() { 494 SkGraphics::SetFontCacheUsed(0); 495 SkGlobals::Term(); 496} 497 498size_t SkGraphics::GetFontCacheUsed() { 499 return SkGlyphCache::GetCacheUsed(); 500} 501 502bool SkGraphics::SetFontCacheUsed(size_t usageInBytes) { 503 return SkGlyphCache::SetCacheUsed(usageInBytes); 504} 505 506float dummy() { return 1.25f; } 507