diff options
author | 2008-12-17 15:59:43 +0000 | |
---|---|---|
committer | 2008-12-17 15:59:43 +0000 | |
commit | 8a1c16ff38322f0210116fa7293eb8817c7e477e (patch) | |
tree | fe40e07f6c8983318a2f79032b9a706ede1090c1 /src/core/SkGraphics.cpp | |
parent | 2559c629078f738ac37095d896d580b681ac6a30 (diff) |
grab from latest android
git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkGraphics.cpp')
-rw-r--r-- | src/core/SkGraphics.cpp | 526 |
1 files changed, 526 insertions, 0 deletions
diff --git a/src/core/SkGraphics.cpp b/src/core/SkGraphics.cpp new file mode 100644 index 0000000000..64fbab90a1 --- /dev/null +++ b/src/core/SkGraphics.cpp @@ -0,0 +1,526 @@ +/* libs/graphics/sgl/SkGraphics.cpp +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#include "SkGraphics.h" + +#include "Sk64.h" +#include "SkBlitter.h" +#include "SkCanvas.h" +#include "SkFloat.h" +#include "SkGeometry.h" +#include "SkGlobals.h" +#include "SkMath.h" +#include "SkMatrix.h" +#include "SkPath.h" +#include "SkPathEffect.h" +#include "SkPathMeasure.h" +#include "SkRandom.h" +#include "SkRefCnt.h" +#include "SkScalerContext.h" +#include "SkShader.h" +#include "SkStream.h" +#include "SkTSearch.h" +#include "SkTime.h" +#include "SkUtils.h" +#include "SkXfermode.h" + +#if 0 + +#define SK_SORT_TEMPLATE_TYPE int +#define SK_SORT_TEMPLATE_NAME sort_int +#define SK_SORT_TEMPLATE_CMP(a, b) ((a) - (b)) +#include "SkSortTemplate.h" + +#define SK_SORT_TEMPLATE_TYPE int* +#define SK_SORT_TEMPLATE_NAME sort_intptr +#define SK_SORT_TEMPLATE_CMP(a, b) (*(a) - *(b)) +#include "SkSortTemplate.h" + +static void test_sort() +{ + int array[] = { 4, 3, 7, 5, 2, 5, 1, 2, 9, 6, 7, 4, 5, 3, 1, 0 }; + int* ptr[SK_ARRAY_COUNT(array)]; + int i, N = SK_ARRAY_COUNT(array) - 1; + + for (i = 0; i < N; i++) + printf(" %d", array[i]); + printf("\n"); + + for (i = 0; i < N; i++) + ptr[i] = &array[i]; + sort_intptr(ptr, N); + for (i = 0; i < N; i++) + printf(" %d", *ptr[i]); + printf("\n"); + + sort_int(array, N); + for (i = 0; i < N; i++) + printf(" %d", array[i]); + printf("\n"); + +} +#endif + +#define SPEED_TESTx + +#define typesizeline(type) { #type , sizeof(type) } +#define unittestline(type) { #type , type::UnitTest } + + +#ifdef BUILD_EMBOSS_TABLE + extern void SkEmbossMask_BuildTable(); +#endif + +#ifdef BUILD_RADIALGRADIENT_TABLE + extern void SkRadialGradient_BuildTable(); +#endif + +#define BIG_LOOP_COUNT 1000000 +#define TEXT_LOOP_COUNT 1000 + +#ifdef SPEED_TEST +static int test_s64(int i) +{ + Sk64 a, b, c; + + c.set(0); + a.set(i); + b.setMul(i, i); + a.add(b); + a.add(c); + return c.getFixed(); +} + +static int test_native_64(int i) +{ + int16_t a, b, c; + + c = 0; + a = i; + b = (int64_t)i * i; + a += b; + a += c; + return (int)(c >> 16); +} + +static void test_drawText(SkBitmap::Config config, SkColor color) +{ + SkBitmap bm; + + bm.setConfig(config, 320, 240); + bm.allocPixels(); + + SkCanvas canvas(bm); + SkPaint paint; + + paint.setAntiAlias(true); + paint.setTextSize(SkIntToScalar(12)); + paint.setColor(color); + + SkScalar x = SkIntToScalar(20); + SkScalar y = SkIntToScalar(100); + const char* text = "Hamburgefons"; + size_t len = strlen(text); + + // draw once to populate the cache + canvas.drawText(text, len, x, y, paint); + + SkMSec now = SkTime::GetMSecs(); + for (int i = 0; i < TEXT_LOOP_COUNT; i++) + canvas.drawText(text, len, x, y, paint); + printf("----------- Config: %d, Color=%x, CPS = %g\n", config, color, + len * TEXT_LOOP_COUNT * 1000.0 / (SkTime::GetMSecs() - now)); +} + +#endif + +#include "SkFloatBits.h" + +static inline float fast_inc(float x) { + SkFloatIntUnion data; + data.fFloat = x; + data.fSignBitInt += 1; + return data.fFloat; +} + +extern float dummy(); +int time_math() { + SkMSec now; + int i; + int sum = 0; + const int repeat = 1000000; + float f; + + f = dummy(); + now = SkTime::GetMSecs(); + for (i = repeat - 1; i >= 0; --i) { + sum += (int)f; f = fast_inc(f); + sum += (int)f; f = fast_inc(f); + sum += (int)f; f = fast_inc(f); + sum += (int)f; f = fast_inc(f); + } + SkDebugf("---- native cast %d\n", SkTime::GetMSecs() - now); + + f = dummy(); + now = SkTime::GetMSecs(); + for (i = repeat - 1; i >= 0; --i) { + sum += SkFloatToIntCast(f); f = fast_inc(f); + sum += SkFloatToIntCast(f); f = fast_inc(f); + sum += SkFloatToIntCast(f); f = fast_inc(f); + sum += SkFloatToIntCast(f); f = fast_inc(f); + } + SkDebugf("---- hack cast %d\n", SkTime::GetMSecs() - now); + + f = dummy(); + now = SkTime::GetMSecs(); + for (i = repeat - 1; i >= 0; --i) { + sum += (int)floorf(f + 0.5f); f = fast_inc(f); + sum += (int)floorf(f + 0.5f); f = fast_inc(f); + sum += (int)floorf(f + 0.5f); f = fast_inc(f); + sum += (int)floorf(f + 0.5f); f = fast_inc(f); + } + SkDebugf("---- native round %d\n", SkTime::GetMSecs() - now); + + f = dummy(); + now = SkTime::GetMSecs(); + for (i = repeat - 1; i >= 0; --i) { + sum += SkFloatToIntRound(f); f = fast_inc(f); + sum += SkFloatToIntRound(f); f = fast_inc(f); + sum += SkFloatToIntRound(f); f = fast_inc(f); + sum += SkFloatToIntRound(f); f = fast_inc(f); + } + SkDebugf("---- hack round %d\n", SkTime::GetMSecs() - now); + + f = dummy(); + now = SkTime::GetMSecs(); + for (i = repeat - 1; i >= 0; --i) { + sum += SkFloat2Bits(floorf(f)); f = fast_inc(f); + sum += SkFloat2Bits(floorf(f)); f = fast_inc(f); + sum += SkFloat2Bits(floorf(f)); f = fast_inc(f); + sum += SkFloat2Bits(floorf(f)); f = fast_inc(f); + } + SkDebugf("---- native floor %d\n", SkTime::GetMSecs() - now); + + f = dummy(); + now = SkTime::GetMSecs(); + for (i = repeat - 1; i >= 0; --i) { + sum += SkFloatToIntFloor(f); f = fast_inc(f); + sum += SkFloatToIntFloor(f); f = fast_inc(f); + sum += SkFloatToIntFloor(f); f = fast_inc(f); + sum += SkFloatToIntFloor(f); f = fast_inc(f); + } + SkDebugf("---- hack floor %d\n", SkTime::GetMSecs() - now); + + return sum; +} + +static float time_intToFloat() { + const int repeat = 1000000; + int i, n; + SkMSec now; + float sum = 0; + + n = (int)dummy(); + now = SkTime::GetMSecs(); + for (i = repeat - 1; i >= 0; --i) { + sum += (float)n; n += 1; + sum += (float)n; n += 1; + sum += (float)n; n += 1; + sum += (float)n; n += 1; + } + SkDebugf("---- native i2f %d\n", SkTime::GetMSecs() - now); + + n = (int)dummy(); + now = SkTime::GetMSecs(); + for (i = repeat - 1; i >= 0; --i) { + sum += SkIntToFloatCast(n); n += 1; + sum += SkIntToFloatCast(n); n += 1; + sum += SkIntToFloatCast(n); n += 1; + sum += SkIntToFloatCast(n); n += 1; + } + SkDebugf("---- check i2f %d\n", SkTime::GetMSecs() - now); + + n = (int)dummy(); + now = SkTime::GetMSecs(); + for (i = repeat - 1; i >= 0; --i) { + sum += SkIntToFloatCast_NoOverflowCheck(n); n += 1; + sum += SkIntToFloatCast_NoOverflowCheck(n); n += 1; + sum += SkIntToFloatCast_NoOverflowCheck(n); n += 1; + sum += SkIntToFloatCast_NoOverflowCheck(n); n += 1; + } + SkDebugf("---- nocheck i2f %d\n", SkTime::GetMSecs() - now); + + return sum; +} + +void SkGraphics::Init(bool runUnitTests) +{ + SkGlobals::Init(); + +// time_math(); +// time_intToFloat(); + +#ifdef BUILD_EMBOSS_TABLE + SkEmbossMask_BuildTable(); +#endif +#ifdef BUILD_RADIALGRADIENT_TABLE + SkRadialGradient_BuildTable(); +#endif + +#ifdef SK_SUPPORT_UNITTEST + if (runUnitTests == false) + return; + int i; + + static const struct { + const char* fTypeName; + size_t fSizeOf; + } gTypeSize[] = { + typesizeline(char), + typesizeline(short), + typesizeline(int), + typesizeline(long), + typesizeline(size_t), + typesizeline(void*), + + typesizeline(S8CPU), + typesizeline(U8CPU), + typesizeline(S16CPU), + typesizeline(U16CPU), + + typesizeline(SkPoint), + typesizeline(SkRect), + typesizeline(SkMatrix), + typesizeline(SkPath), + typesizeline(SkGlyph), + typesizeline(SkRefCnt), + + typesizeline(SkPaint), + typesizeline(SkCanvas), + typesizeline(SkBlitter), + typesizeline(SkShader), + typesizeline(SkXfermode), + typesizeline(SkPathEffect) + }; + +#ifdef SK_CPU_BENDIAN + SkDebugf("SkGraphics: big-endian\n"); +#else + SkDebugf("SkGraphics: little-endian\n"); +#endif + + { + char test = 0xFF; + int itest = test; // promote to int, see if it sign-extended + if (itest < 0) + SkDebugf("SkGraphics: char is signed\n"); + else + SkDebugf("SkGraphics: char is unsigned\n"); + } + for (i = 0; i < (int)SK_ARRAY_COUNT(gTypeSize); i++) + SkDebugf("SkGraphics: sizeof(%s) = %d\n", gTypeSize[i].fTypeName, gTypeSize[i].fSizeOf); + + static const struct { + const char* fTypeName; + void (*fUnitTest)(); + } gUnitTests[] = { + unittestline(Sk64), + unittestline(SkMath), + unittestline(SkUtils), + unittestline(SkString), + unittestline(SkMatrix), + unittestline(SkGeometry), + unittestline(SkPath), + unittestline(SkPathMeasure), + unittestline(SkStream), + unittestline(SkWStream), + }; + + for (i = 0; i < (int)SK_ARRAY_COUNT(gUnitTests); i++) + { + SkDebugf("SkGraphics: Running UnitTest for %s\n", gUnitTests[i].fTypeName); + gUnitTests[i].fUnitTest(); + SkDebugf("SkGraphics: End UnitTest for %s\n", gUnitTests[i].fTypeName); + } + SkQSort_UnitTest(); + +#endif + + if (false) // test asm fixmul + { + int j; + SkMSec now = SkTime::GetMSecs(); + for (j = 0; j < BIG_LOOP_COUNT; j++) { + (void)SkFixedMul_portable(0x8000, 0x150000); + } + SkMSec now2 = SkTime::GetMSecs(); + printf("-------- SkFixedMul_portable = %d\n", now2 - now); + + for (j = 0; j < BIG_LOOP_COUNT; j++) { + (void)SkFixedMul(0x8000, 0x150000); + } + printf("-------- SkFixedMul = %d\n", SkTime::GetMSecs() - now2); + + SkRandom rand; + for (j = 0; j < 10000; j++) { + SkFixed a = rand.nextS() >> 8; + SkFixed b = rand.nextS() >> 8; + SkFixed c1 = SkFixedMul_portable(a, b); + SkFixed c2 = SkFixedMul(a, b); + if (SkAbs32(c1 - c2) > 1) + printf("------ FixMul disagreement: (%x %x) slow=%x fast=%x\n", a, b, c1, c2); + } + } + + if (false) // test asm fractmul + { + int j; + SkMSec now = SkTime::GetMSecs(); + for (j = 0; j < BIG_LOOP_COUNT; j++) { + (void)SkFractMul_portable(0x800000, 0x1500000); + } + SkMSec now2 = SkTime::GetMSecs(); + printf("-------- SkFractMul_portable = %d\n", now2 - now); + + for (j = 0; j < BIG_LOOP_COUNT; j++) { + (void)SkFractMul(0x800000, 0x1500000); + } + printf("-------- SkFractMul = %d\n", SkTime::GetMSecs() - now2); + + SkRandom rand; + for (j = 0; j < 10000; j++) { + SkFixed a = rand.nextS() >> 1; + SkFixed b = rand.nextS() >> 1; + SkFixed c1 = SkFractMul_portable(a, b); + SkFixed c2 = SkFractMul(a, b); + if (SkAbs32(c1 - c2) > 1) + printf("------ FractMul disagreement: (%x %x) slow=%x fast=%x\n", a, b, c1, c2); + } + } + + if (false) // test asm clz + { + int j; + SkMSec now = SkTime::GetMSecs(); + for (j = 0; j < BIG_LOOP_COUNT; j++) { + (void)SkCLZ_portable(now); + } + SkMSec now2 = SkTime::GetMSecs(); + printf("-------- SkCLZ_portable = %d\n", now2 - now); + + for (j = 0; j < BIG_LOOP_COUNT; j++) { + (void)SkCLZ(now); + } + printf("-------- SkCLZ = %d\n", SkTime::GetMSecs() - now2); + + SkRandom rand; + for (j = 0; j < 10000; j++) { + uint32_t a = rand.nextU(); + int c1 = SkCLZ_portable(a); + int c2 = SkCLZ(a); + if (c1 != c2) + printf("------ CLZ disagreement: (%x) slow=%x fast=%x\n", a, c1, c2); + } + } + +#ifdef SPEED_TEST + if (false) { + int i; + int (*proc)(int); + + static const struct { + int (*proc)(int); + const char* name; + } gList[] = { + { test_s64, "Sk64" }, + { test_native_64, "native" } + }; + + for (size_t j = 0; j < SK_ARRAY_COUNT(gList); j++) { + SkMSec now = SkTime::GetMSecs(); + proc = gList[j].proc; + for (i = 0; i < BIG_LOOP_COUNT; i++) { + proc(i); + } + printf("-------- %s = %d\n", gList[j].name, SkTime::GetMSecs() - now); + } + } +#endif + + if (false) { + size_t i, size = 480; + char* buffer = (char*)sk_malloc_throw(size); + uint16_t* buffer16 = (uint16_t*)buffer; + uint32_t* buffer32 = (uint32_t*)buffer; + + SkMSec now = SkTime::GetMSecs(); + for (i = 0; i < 100000; i++) { + sk_memset16(buffer16, (uint16_t)i, size >> 1); + } + SkMSec now2 = SkTime::GetMSecs(); + for (i = 0; i < 100000; i++) { + sk_memset16_portable(buffer16, (uint16_t)i, size >> 1); + } + SkMSec now3 = SkTime::GetMSecs(); + printf("----------- memset16: native %d, portable %d\n", now2 - now, now3 - now2); + + now = SkTime::GetMSecs(); + for (i = 0; i < 100000; i++) { + sk_memset32(buffer32, i, size >> 2); + } + now2 = SkTime::GetMSecs(); + for (i = 0; i < 100000; i++) { + sk_memset32_portable(buffer32, i, size >> 2); + } + now3 = SkTime::GetMSecs(); + printf("----------- memset32: native %d, portable %d\n", now2 - now, now3 - now2); + + sk_free(buffer); + } + +#ifdef SPEED_TEST + if (false) { + test_drawText(SkBitmap::kARGB_8888_Config, SK_ColorBLACK); + test_drawText(SkBitmap::kARGB_8888_Config, SK_ColorRED); + test_drawText(SkBitmap::kRGB_565_Config, SK_ColorBLACK); + test_drawText(SkBitmap::kRGB_565_Config, SK_ColorRED); + } +#endif + +// if (true) { +// test_sort(); +// } +} + +//////////////////////////////////////////////////////////////////////////// + +#include "SkGlyphCache.h" + +void SkGraphics::Term() { + SkGraphics::SetFontCacheUsed(0); + SkGlobals::Term(); +} + +size_t SkGraphics::GetFontCacheUsed() { + return SkGlyphCache::GetCacheUsed(); +} + +bool SkGraphics::SetFontCacheUsed(size_t usageInBytes) { + return SkGlyphCache::SetCacheUsed(usageInBytes); +} + +float dummy() { return 1.25f; } |