diff options
-rw-r--r-- | src/effects/SkBitmapCache.cpp | 146 | ||||
-rw-r--r-- | src/effects/SkBitmapCache.h | 45 | ||||
-rw-r--r-- | src/effects/SkGradientShader.cpp | 232 | ||||
-rw-r--r-- | src/effects/effects_files.mk | 1 | ||||
-rw-r--r-- | xcode/effects/effects.xcodeproj/project.pbxproj | 15 |
5 files changed, 380 insertions, 59 deletions
diff --git a/src/effects/SkBitmapCache.cpp b/src/effects/SkBitmapCache.cpp new file mode 100644 index 0000000000..dd65ecbf41 --- /dev/null +++ b/src/effects/SkBitmapCache.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2010 Tetrark Inc. + */ + +#include "SkBitmapCache.h" + +struct SkBitmapCache::Entry { + Entry* fPrev; + Entry* fNext; + + void* fBuffer; + size_t fSize; + SkBitmap fBitmap; + + Entry(const void* buffer, size_t size, const SkBitmap& bm) : fBitmap(bm) { + fBuffer = sk_malloc_throw(size); + fSize = size; + memcpy(fBuffer, buffer, size); + } + + ~Entry() { sk_free(fBuffer); } + + bool equals(const void* buffer, size_t size) const { + return (fSize == size) && !memcmp(fBuffer, buffer, size); + } +}; + +SkBitmapCache::SkBitmapCache(int max) : fMaxEntries(max) { + fEntryCount = 0; + fHead = fTail = NULL; + + this->validate(); +} + +SkBitmapCache::~SkBitmapCache() { + this->validate(); + + Entry* entry = fHead; + while (entry) { + Entry* next = entry->fNext; + delete entry; + entry = next; + } +} + +SkBitmapCache::Entry* SkBitmapCache::detach(Entry* entry) const { + if (entry->fPrev) { + SkASSERT(fHead != entry); + entry->fPrev->fNext = entry->fNext; + } else { + SkASSERT(fHead == entry); + fHead = entry->fNext; + } + if (entry->fNext) { + SkASSERT(fTail != entry); + entry->fNext->fPrev = entry->fPrev; + } else { + SkASSERT(fTail == entry); + fTail = entry->fPrev; + } + return entry; +} + +void SkBitmapCache::attachToHead(Entry* entry) const { + entry->fPrev = NULL; + entry->fNext = fHead; + if (fHead) { + fHead->fPrev = entry; + } else { + fTail = entry; + } + fHead = entry; +} + +bool SkBitmapCache::find(const void* buffer, size_t size, SkBitmap* bm) const { + AutoValidate av(this); + + Entry* entry = fHead; + while (entry) { + if (entry->equals(buffer, size)) { + if (bm) { + *bm = entry->fBitmap; + } + // move to the head of our list, so we purge it last + this->detach(entry); + this->attachToHead(entry); + return true; + } + entry = entry->fNext; + } + return false; +} + +void SkBitmapCache::add(const void* buffer, size_t len, const SkBitmap& bm) { + AutoValidate av(this); + + if (fEntryCount == fMaxEntries) { + if (fTail) { + delete this->detach(fTail); + } + } + + Entry* entry = new Entry(buffer, len, bm); + this->attachToHead(entry); + fEntryCount += 1; +} + +/////////////////////////////////////////////////////////////////////////////// + +#ifdef SK_DEBUG + +void SkBitmapCache::validate() const { + SkASSERT(fEntryCount >= 0 && fEntryCount <= fMaxEntries); + + if (fEntryCount > 0) { + SkASSERT(NULL == fHead->fPrev); + SkASSERT(NULL == fTail->fNext); + + if (fEntryCount == 1) { + SkASSERT(fHead == fTail); + } else { + SkASSERT(fHead != fTail); + } + + Entry* entry = fHead; + int count = 0; + while (entry) { + count += 1; + entry = entry->fNext; + } + SkASSERT(count == fEntryCount); + + entry = fTail; + while (entry) { + count -= 1; + entry = entry->fPrev; + } + SkASSERT(0 == count); + } else { + SkASSERT(NULL == fHead); + SkASSERT(NULL == fTail); + } +} + +#endif + diff --git a/src/effects/SkBitmapCache.h b/src/effects/SkBitmapCache.h new file mode 100644 index 0000000000..b914b6bb01 --- /dev/null +++ b/src/effects/SkBitmapCache.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2010 Tetrark Inc. + */ + +#ifndef SkBitmapCache_DEFINED +#define SkBitmapCache_DEFINED + +#include "SkBitmap.h" + +class SkBitmapCache : SkNoncopyable { +public: + SkBitmapCache(int maxEntries); + ~SkBitmapCache(); + + bool find(const void* buffer, size_t len, SkBitmap*) const; + void add(const void* buffer, size_t len, const SkBitmap&); + +private: + int fEntryCount; + const int fMaxEntries; + + struct Entry; + mutable Entry* fHead; + mutable Entry* fTail; + + inline Entry* detach(Entry*) const; + inline void attachToHead(Entry*) const; + +#ifdef SK_DEBUG + void validate() const; +#else + void validate() const {} +#endif + + class AutoValidate : SkNoncopyable { + public: + AutoValidate(const SkBitmapCache* bc) : fBC(bc) { bc->validate(); } + ~AutoValidate() { fBC->validate(); } + private: + const SkBitmapCache* fBC; + }; +}; + +#endif + diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp index 5a3a80ab16..cabce20fc2 100644 --- a/src/effects/SkGradientShader.cpp +++ b/src/effects/SkGradientShader.cpp @@ -17,8 +17,11 @@ #include "SkGradientShader.h" #include "SkColorPriv.h" +#include "SkMallocPixelRef.h" #include "SkUnitMapper.h" #include "SkUtils.h" +#include "SkTemplates.h" +#include "SkBitmapCache.h" /////////////////////////////////////////////////////////////////////////// @@ -119,8 +122,9 @@ protected: const uint16_t* getCache16(); const SkPMColor* getCache32(); - // called when we kill our cached colors (to be rebuilt later on demand) - virtual void onCacheReset() = 0; + SkMallocPixelRef* fCache32PixelRef; + + void commonAsABitmap(SkBitmap*); private: enum { @@ -135,7 +139,6 @@ private: SkPMColor* fCache32; // working ptr. If this is NULL, we need to recompute the cache values uint16_t* fCache16Storage; // storage for fCache16, allocated on demand - SkPMColor* fCache32Storage; // storage for fCache32, allocated on demand unsigned fCacheAlpha; // the alpha value we used when we computed the cache. larger than 8bits so we can store uninitialized value static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count); @@ -168,7 +171,8 @@ Gradient_Shader::Gradient_Shader(const SkColor colors[], const SkScalar pos[], fTileProc = gTileProcs[mode]; fCache16 = fCache16Storage = NULL; - fCache32 = fCache32Storage = NULL; + fCache32 = NULL; + fCache32PixelRef = NULL; /* Note: we let the caller skip the first and/or last position. i.e. pos[0] = 0.3, pos[1] = 0.7 @@ -276,7 +280,8 @@ Gradient_Shader::Gradient_Shader(SkFlattenableReadBuffer& buffer) : fMapper = static_cast<SkUnitMapper*>(buffer.readFlattenable()); fCache16 = fCache16Storage = NULL; - fCache32 = fCache32Storage = NULL; + fCache32 = NULL; + fCache32PixelRef = NULL; int colorCount = fColorCount = buffer.readU32(); if (colorCount > kColorStorageCount) { @@ -306,9 +311,7 @@ Gradient_Shader::~Gradient_Shader() { if (fCache16Storage) { sk_free(fCache16Storage); } - if (fCache32Storage) { - sk_free(fCache32Storage); - } + SkSafeUnref(fCache32PixelRef); if (fOrigColors != fStorage) { sk_free(fOrigColors); } @@ -377,7 +380,9 @@ bool Gradient_Shader::setContext(const SkBitmap& device, fCache32 = NULL; // inval the cache fCacheAlpha = paintAlpha; // record the new alpha // inform our subclasses - this->onCacheReset(); + if (fCache32PixelRef) { + fCache32PixelRef->notifyPixelsChanged(); + } } return true; } @@ -542,10 +547,12 @@ const uint16_t* Gradient_Shader::getCache16() { const SkPMColor* Gradient_Shader::getCache32() { if (fCache32 == NULL) { - if (fCache32Storage == NULL) // set the storage and our working ptr - fCache32Storage = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor) * kCache32Count); - - fCache32 = fCache32Storage; + if (NULL == fCache32PixelRef) { + fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef, (NULL, + sizeof(SkPMColor) * kCache32Count, + NULL)); + } + fCache32 = (SkPMColor*)fCache32PixelRef->getAddr(); if (fColorCount == 2) { build_32bit_cache(fCache32, fOrigColors[0], fOrigColors[1], kCache32Count, fCacheAlpha); @@ -566,20 +573,84 @@ const SkPMColor* Gradient_Shader::getCache32() { } if (fMapper) { - fCache32Storage = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor) * kCache32Count); + SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef, + (NULL, + sizeof(SkPMColor) * kCache32Count, + NULL)); SkPMColor* linear = fCache32; // just computed linear data - SkPMColor* mapped = fCache32Storage; // storage for mapped data + SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data SkUnitMapper* map = fMapper; for (int i = 0; i < 256; i++) { mapped[i] = linear[map->mapUnit16((i << 8) | i) >> 8]; } - sk_free(fCache32); - fCache32 = fCache32Storage; + fCache32PixelRef->unref(); + fCache32PixelRef = newPR; + fCache32 = (SkPMColor*)newPR->getAddr(); } } return fCache32; } +/* + * Because our caller might rebuild the same (logically the same) gradient + * over and over, we'd like to return exactly the same "bitmap" if possible, + * allowing the client to utilize a cache of our bitmap (e.g. with a GPU). + * To do that, we maintain a private cache of built-bitmaps, based on our + * colors and positions. Note: we don't try to flatten the fMapper, so if one + * is present, we skip the cache for now. + */ +void Gradient_Shader::commonAsABitmap(SkBitmap* bitmap) { + // don't have a way to put the mapper into our cache-key yet + if (fMapper) { + // force our cahce32pixelref to be built + (void)this->getCache32(); + bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1); + bitmap->setPixelRef(fCache32PixelRef); + return; + } + + // build our key: [numColors + colors[] + {positions[]} ] + int count = 1 + fColorCount; + if (fColorCount > 2) { + count += fColorCount - 1; // fRecs[].fPos + } + + SkAutoSTMalloc<16, int32_t> storage(count); + int32_t* buffer = storage.get(); + + *buffer++ = fColorCount; + memcpy(buffer, fOrigColors, fColorCount * sizeof(SkColor)); + buffer += fColorCount; + if (fColorCount > 2) { + for (int i = 1; i < fColorCount; i++) { + *buffer++ = fRecs[i].fPos; + } + } + SkASSERT(buffer - storage.get() == count); + + /////////////////////////////////// + + static SkMutex gMutex; + static SkBitmapCache* gCache; + // each cache cost 1K of RAM, since each bitmap will be 1x256 at 32bpp + static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32; + SkAutoMutexAcquire ama(gMutex); + + if (NULL == gCache) { + gCache = new SkBitmapCache(MAX_NUM_CACHED_GRADIENT_BITMAPS); + } + size_t size = count * sizeof(int32_t); + + if (!gCache->find(storage.get(), size, bitmap)) { + // force our cahce32pixelref to be built + (void)this->getCache32(); + bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1); + bitmap->setPixelRef(fCache32PixelRef); + + gCache->add(storage.get(), size, *bitmap); + } +} + /////////////////////////////////////////////////////////////////////////// static void pts_to_unit_matrix(const SkPoint pts[2], SkMatrix* matrix) { @@ -602,39 +673,24 @@ public: SkShader::TileMode mode, SkUnitMapper* mapper) : Gradient_Shader(colors, pos, colorCount, mode, mapper) { - fCachedBitmap = NULL; pts_to_unit_matrix(pts, &fPtsToUnit); } - virtual ~Linear_Gradient() { - if (fCachedBitmap) { - SkDELETE(fCachedBitmap); - } - } virtual bool setContext(const SkBitmap&, const SkPaint&, const SkMatrix&); virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count); virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count); - virtual bool asABitmap(SkBitmap*, SkMatrix*, TileMode*); - virtual void onCacheReset() { - if (fCachedBitmap) { - SkDELETE(fCachedBitmap); - fCachedBitmap = NULL; - } - } + virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, + TileMode*, SkScalar* twoPointRadialParams); static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(Linear_Gradient, (buffer)); } protected: - Linear_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) { - fCachedBitmap = NULL; - } + Linear_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {} virtual Factory getFactory() { return CreateProc; } private: - SkBitmap* fCachedBitmap; // allocated on demand - typedef Gradient_Shader INHERITED; }; @@ -674,10 +730,9 @@ void Linear_Gradient::shadeSpan(int x, int y, SkPMColor dstC[], int count) const SkPMColor* cache = this->getCache32(); if (fDstToIndexClass != kPerspective_MatrixClass) { - dstProc(fDstToIndex, SkIntToScalar(x), SkIntToScalar(y), &srcPt); + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); SkFixed dx, fx = SkScalarToFixed(srcPt.fX); - // preround fx by half the amount we throw away - fx += 1 << 7; if (fDstToIndexClass == kFixedStepInX_MatrixClass) { SkFixed dxStorage[1]; @@ -752,18 +807,12 @@ void Linear_Gradient::shadeSpan(int x, int y, SkPMColor dstC[], int count) } } -bool Linear_Gradient::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, - TileMode xy[]) { - // we cache our "bitmap", so it's generationID will be const on subsequent - // calls to asABitmap - if (NULL == fCachedBitmap) { - fCachedBitmap = SkNEW(SkBitmap); - fCachedBitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1); - fCachedBitmap->setPixels((void*)this->getCache32(), NULL); - } - +SkShader::BitmapType Linear_Gradient::asABitmap(SkBitmap* bitmap, + SkMatrix* matrix, + TileMode xy[], + SkScalar* twoPointRadialParams) { if (bitmap) { - *bitmap = *fCachedBitmap; + this->commonAsABitmap(bitmap); } if (matrix) { matrix->setScale(SkIntToScalar(kCache32Count), SK_Scalar1); @@ -773,7 +822,7 @@ bool Linear_Gradient::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, xy[0] = fTileMode; xy[1] = kClamp_TileMode; } - return true; + return kDefault_BitmapType; } static void dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, @@ -802,10 +851,9 @@ void Linear_Gradient::shadeSpan16(int x, int y, uint16_t dstC[], int count) int toggle = ((x ^ y) & 1) << kCache16Bits; if (fDstToIndexClass != kPerspective_MatrixClass) { - dstProc(fDstToIndex, SkIntToScalar(x), SkIntToScalar(y), &srcPt); + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); SkFixed dx, fx = SkScalarToFixed(srcPt.fX); - // preround fx by half the amount we throw away - fx += 1 << 7; if (fDstToIndexClass == kFixedStepInX_MatrixClass) { SkFixed dxStorage[1]; @@ -934,7 +982,8 @@ public: if (fDstToIndexClass != kPerspective_MatrixClass) { - dstProc(fDstToIndex, SkIntToScalar(x), SkIntToScalar(y), &srcPt); + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); SkFixed dx, fx = SkScalarToFixed(srcPt.fX); SkFixed dy, fy = SkScalarToFixed(srcPt.fY); @@ -1017,7 +1066,8 @@ public: int toggle = ((x ^ y) & 1) << kCache16Bits; if (fDstToIndexClass != kPerspective_MatrixClass) { - dstProc(fDstToIndex, SkIntToScalar(x), SkIntToScalar(y), &srcPt); + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); SkFixed dx, fx = SkScalarToFixed(srcPt.fX); SkFixed dy, fy = SkScalarToFixed(srcPt.fY); @@ -1107,6 +1157,24 @@ public: } } + virtual BitmapType asABitmap(SkBitmap* bitmap, + SkMatrix* matrix, + TileMode* xy, + SkScalar* twoPointRadialParams) { + if (bitmap) { + this->commonAsABitmap(bitmap); + } + if (matrix) { + matrix->setScale(SkIntToScalar(kCache32Count), SkIntToScalar(kCache32Count)); + matrix->preConcat(fPtsToUnit); + } + if (xy) { + xy[0] = fTileMode; + xy[1] = kClamp_TileMode; + } + return kRadial_BitmapType; + } + static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(Radial_Gradient, (buffer)); } @@ -1114,7 +1182,6 @@ public: protected: Radial_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {}; virtual Factory getFactory() { return CreateProc; } - virtual void onCacheReset() {} private: typedef Gradient_Shader INHERITED; @@ -1228,6 +1295,37 @@ public: fPtsToUnit.setTranslate(-start.fX, -start.fY); fPtsToUnit.postScale(inv, inv); } + + virtual BitmapType asABitmap(SkBitmap* bitmap, + SkMatrix* matrix, + TileMode* xy, + SkScalar* twoPointRadialParams) { + if (bitmap) { + this->commonAsABitmap(bitmap); + } + SkScalar diffL = 0; // just to avoid gcc warning + if (matrix || twoPointRadialParams) { + diffL = SkScalarSqrt(SkScalarSquare(fDiff.fX) + + SkScalarSquare(fDiff.fY)); + } + if (matrix) { + SkScalar invDiffL = SkScalarInvert(diffL); + matrix->setSinCos(-SkScalarMul(invDiffL, fDiff.fY), + SkScalarMul(invDiffL, fDiff.fX)); + matrix->preConcat(fPtsToUnit); + } + if (xy) { + xy[0] = fTileMode; + xy[1] = kClamp_TileMode; + } + if (NULL != twoPointRadialParams) { + twoPointRadialParams[0] = diffL; + twoPointRadialParams[1] = fStartRadius; + twoPointRadialParams[2] = fDiffRadius; + } + return kTwoPointRadial_BitmapType; + } + virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) { SkASSERT(count > 0); @@ -1250,7 +1348,8 @@ public: if (fDstToIndexClass != kPerspective_MatrixClass) { SkPoint srcPt; - dstProc(fDstToIndex, SkIntToScalar(x), SkIntToScalar(y), &srcPt); + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); SkFixed dx, fx = SkScalarToFixed(srcPt.fX); SkFixed dy, fy = SkScalarToFixed(srcPt.fY); @@ -1365,7 +1464,6 @@ protected: fOneOverTwoA = buffer.readScalar(); }; virtual Factory getFactory() { return CreateProc; } - virtual void onCacheReset() {} private: typedef Gradient_Shader INHERITED; @@ -1386,6 +1484,23 @@ public: virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count); virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count); + virtual BitmapType asABitmap(SkBitmap* bitmap, + SkMatrix* matrix, + TileMode* xy, + SkScalar* twoPointRadialParams) { + if (bitmap) { + this->commonAsABitmap(bitmap); + } + if (matrix) { + *matrix = fPtsToUnit; + } + if (xy) { + xy[0] = fTileMode; + xy[1] = kClamp_TileMode; + } + return kSweep_BitmapType; + } + static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(Sweep_Gradient, (buffer)); } @@ -1393,7 +1508,6 @@ public: protected: Sweep_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {} virtual Factory getFactory() { return CreateProc; } - virtual void onCacheReset() {} private: typedef Gradient_Shader INHERITED; diff --git a/src/effects/effects_files.mk b/src/effects/effects_files.mk index f570f15536..00d9e7dc3a 100644 --- a/src/effects/effects_files.mk +++ b/src/effects/effects_files.mk @@ -1,6 +1,7 @@ SOURCE := \ Sk1DPathEffect.cpp \ Sk2DPathEffect.cpp \ + SkBitmapCache.cpp \ SkTransparentShader.cpp \ SkAvoidXfermode.cpp \ SkBlurDrawLooper.cpp \ diff --git a/xcode/effects/effects.xcodeproj/project.pbxproj b/xcode/effects/effects.xcodeproj/project.pbxproj index 6030f4b573..d131583627 100644 --- a/xcode/effects/effects.xcodeproj/project.pbxproj +++ b/xcode/effects/effects.xcodeproj/project.pbxproj @@ -44,6 +44,8 @@ 002886D40EFAEA260083E387 /* SkUnitMappers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 002886CC0EFAEA260083E387 /* SkUnitMappers.cpp */; }; 005362261035F920001189E0 /* SkNWayCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 005362251035F920001189E0 /* SkNWayCanvas.cpp */; }; 005E92230FEFC571008965B9 /* SkPorterDuff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 005E92220FEFC571008965B9 /* SkPorterDuff.cpp */; }; + 009F9CA512C39FB500C7FD4A /* SkBitmapCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009F9CA312C39FB500C7FD4A /* SkBitmapCache.cpp */; }; + 009F9CA612C39FB500C7FD4A /* SkBitmapCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 009F9CA412C39FB500C7FD4A /* SkBitmapCache.h */; }; 2762F61D0FCCC92C002BD8B4 /* SkGroupShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F61A0FCCC92C002BD8B4 /* SkGroupShape.cpp */; }; 2762F61F0FCCC92C002BD8B4 /* SkRectShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2762F61C0FCCC92C002BD8B4 /* SkRectShape.cpp */; }; /* End PBXBuildFile section */ @@ -86,6 +88,8 @@ 002886CC0EFAEA260083E387 /* SkUnitMappers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkUnitMappers.cpp; path = ../../src/utils/SkUnitMappers.cpp; sourceTree = SOURCE_ROOT; }; 005362251035F920001189E0 /* SkNWayCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkNWayCanvas.cpp; path = ../../src/utils/SkNWayCanvas.cpp; sourceTree = SOURCE_ROOT; }; 005E92220FEFC571008965B9 /* SkPorterDuff.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkPorterDuff.cpp; path = ../../src/effects/SkPorterDuff.cpp; sourceTree = SOURCE_ROOT; }; + 009F9CA312C39FB500C7FD4A /* SkBitmapCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkBitmapCache.cpp; path = ../../src/effects/SkBitmapCache.cpp; sourceTree = SOURCE_ROOT; }; + 009F9CA412C39FB500C7FD4A /* SkBitmapCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SkBitmapCache.h; path = ../../src/effects/SkBitmapCache.h; sourceTree = SOURCE_ROOT; }; 2762F61A0FCCC92C002BD8B4 /* SkGroupShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkGroupShape.cpp; path = ../../src/effects/SkGroupShape.cpp; sourceTree = SOURCE_ROOT; }; 2762F61C0FCCC92C002BD8B4 /* SkRectShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkRectShape.cpp; path = ../../src/effects/SkRectShape.cpp; sourceTree = SOURCE_ROOT; }; D2AAC046055464E500DB518D /* libeffects.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libeffects.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -136,6 +140,8 @@ 08FB7795FE84155DC02AAC07 /* effects */ = { isa = PBXGroup; children = ( + 009F9CA312C39FB500C7FD4A /* SkBitmapCache.cpp */, + 009F9CA412C39FB500C7FD4A /* SkBitmapCache.h */, 2762F61A0FCCC92C002BD8B4 /* SkGroupShape.cpp */, 2762F61C0FCCC92C002BD8B4 /* SkRectShape.cpp */, 002886620EFAE7500083E387 /* Sk1DPathEffect.cpp */, @@ -192,6 +198,7 @@ 002886870EFAE7500083E387 /* SkEmbossMask.h in Headers */, 002886880EFAE7500083E387 /* SkEmbossMask_Table.h in Headers */, 002886900EFAE7500083E387 /* SkRadialGradient_Table.h in Headers */, + 009F9CA612C39FB500C7FD4A /* SkBitmapCache.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -222,7 +229,14 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "effects" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 08FB7794FE84155DC02AAC07 /* effects */; projectDirPath = ""; projectRoot = ""; @@ -272,6 +286,7 @@ 000A99700FD97113007E45BD /* SkParsePath.cpp in Sources */, 005E92230FEFC571008965B9 /* SkPorterDuff.cpp in Sources */, 005362261035F920001189E0 /* SkNWayCanvas.cpp in Sources */, + 009F9CA512C39FB500C7FD4A /* SkBitmapCache.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; |