diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkGlyphCache.h | 65 | ||||
-rw-r--r-- | src/core/SkMaskGamma.h | 16 | ||||
-rw-r--r-- | src/core/SkPaint.cpp | 42 | ||||
-rw-r--r-- | src/core/SkScalerContext.h | 11 |
4 files changed, 111 insertions, 23 deletions
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h index 8b404dcc09..d18b61a0a9 100644 --- a/src/core/SkGlyphCache.h +++ b/src/core/SkGlyphCache.h @@ -244,37 +244,72 @@ private: friend class SkGlyphCache_Globals; }; -class SkAutoGlyphCache { +class SkAutoGlyphCacheBase { public: - SkAutoGlyphCache(SkGlyphCache* cache) : fCache(cache) {} - SkAutoGlyphCache(SkTypeface* typeface, const SkDescriptor* desc) { + SkGlyphCache* getCache() const { return fCache; } + + void release() { + if (fCache) { + SkGlyphCache::AttachCache(fCache); + fCache = NULL; + } + } + +protected: + // Hide the constructors so we can't create one of these directly. + // Create SkAutoGlyphCache or SkAutoGlyphCacheNoCache instead. + SkAutoGlyphCacheBase(SkGlyphCache* cache) : fCache(cache) {} + SkAutoGlyphCacheBase(SkTypeface* typeface, const SkDescriptor* desc) { fCache = SkGlyphCache::DetachCache(typeface, desc); } + SkAutoGlyphCacheBase(const SkPaint& paint, + const SkDeviceProperties* deviceProperties, + const SkMatrix* matrix) { + fCache = NULL; + } + SkAutoGlyphCacheBase() {} + + SkGlyphCache* fCache; + +private: + static bool DetachProc(const SkGlyphCache*, void*); +}; + +class SkAutoGlyphCache : public SkAutoGlyphCacheBase { +public: + SkAutoGlyphCache(SkGlyphCache* cache) : SkAutoGlyphCacheBase(cache) {} + SkAutoGlyphCache(SkTypeface* typeface, const SkDescriptor* desc) : + SkAutoGlyphCacheBase(typeface, desc) {} SkAutoGlyphCache(const SkPaint& paint, const SkDeviceProperties* deviceProperties, const SkMatrix* matrix) { - fCache = paint.detachCache(deviceProperties, matrix); + fCache = paint.detachCache(deviceProperties, matrix, false); } - ~SkAutoGlyphCache() { + SkAutoGlyphCache() : SkAutoGlyphCacheBase() { if (fCache) { SkGlyphCache::AttachCache(fCache); } } +}; +#define SkAutoGlyphCache(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCache) - SkGlyphCache* getCache() const { return fCache; } - - void release() { +class SkAutoGlyphCacheNoGamma : public SkAutoGlyphCacheBase { +public: + SkAutoGlyphCacheNoGamma(SkGlyphCache* cache) : SkAutoGlyphCacheBase(cache) {} + SkAutoGlyphCacheNoGamma(SkTypeface* typeface, const SkDescriptor* desc) : + SkAutoGlyphCacheBase(typeface, desc) {} + SkAutoGlyphCacheNoGamma(const SkPaint& paint, + const SkDeviceProperties* deviceProperties, + const SkMatrix* matrix) { + fCache = paint.detachCache(deviceProperties, matrix, true); + } + SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() { if (fCache) { SkGlyphCache::AttachCache(fCache); - fCache = NULL; } } - -private: - SkGlyphCache* fCache; - - static bool DetachProc(const SkGlyphCache*, void*); }; -#define SkAutoGlyphCache(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCache) +#define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamma) + #endif diff --git a/src/core/SkMaskGamma.h b/src/core/SkMaskGamma.h index 1f2b73caac..08ed97f913 100644 --- a/src/core/SkMaskGamma.h +++ b/src/core/SkMaskGamma.h @@ -136,6 +136,22 @@ public: */ PreBlend preBlend(SkColor color) const; + /** + * Get dimensions for the full table set, so it can be allocated as a block. + */ + void getGammaTableDimensions(int* tableWidth, int* numTables) const { + *tableWidth = 256; + *numTables = (1 << MAX_LUM_BITS); + } + + /** + * Provides direct access to the full table set, so it can be uploaded + * into a texture. + */ + const uint8_t* getGammaTables() const { + return (const uint8_t*) fGammaTables; + } + private: static const int MAX_LUM_BITS = B_LUM_BITS > (R_LUM_BITS > G_LUM_BITS ? R_LUM_BITS : G_LUM_BITS) diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 78d947020b..b08b2c6da7 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -1814,10 +1814,8 @@ void SkScalerContext::PostMakeRec(const SkPaint&, SkScalerContext::Rec* rec) { /* * ignoreGamma tells us that the caller just wants metrics that are unaffected - * by gamma correction, so we jam the luminance field to 0 (most common value - * for black text) in hopes that we get a cache hit easier. A better solution - * would be for the fontcache lookup to know to ignore the luminance field - * entirely, but not sure how to do that and keep it fast. + * by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1, + * contrast = 0, luminanceColor = transparent black. */ void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties, const SkMatrix* deviceMatrix, @@ -1827,7 +1825,7 @@ void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties, SkScalerContext::MakeRec(*this, deviceProperties, deviceMatrix, &rec); if (ignoreGamma) { - rec.setLuminanceColor(0); + rec.ignorePreBlend(); } size_t descSize = sizeof(rec); @@ -1951,9 +1949,10 @@ void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties, } SkGlyphCache* SkPaint::detachCache(const SkDeviceProperties* deviceProperties, - const SkMatrix* deviceMatrix) const { + const SkMatrix* deviceMatrix, + bool ignoreGamma) const { SkGlyphCache* cache; - this->descriptorProc(deviceProperties, deviceMatrix, DetachDescProc, &cache, false); + this->descriptorProc(deviceProperties, deviceMatrix, DetachDescProc, &cache, ignoreGamma); return cache; } @@ -1969,6 +1968,33 @@ SkMaskGamma::PreBlend SkScalerContext::GetMaskPreBlend(const SkScalerContext::Re return maskGamma.preBlend(rec.getLuminanceColor()); } +size_t SkScalerContext::GetGammaLUTSize(SkScalar contrast, SkScalar paintGamma, + SkScalar deviceGamma, int* width, int* height) { + SkAutoMutexAcquire ama(gMaskGammaCacheMutex); + const SkMaskGamma& maskGamma = cachedMaskGamma(contrast, + paintGamma, + deviceGamma); + + maskGamma.getGammaTableDimensions(width, height); + size_t size = (*width)*(*height)*sizeof(uint8_t); + + return size; +} + +void SkScalerContext::GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma, + void* data) { + SkAutoMutexAcquire ama(gMaskGammaCacheMutex); + const SkMaskGamma& maskGamma = cachedMaskGamma(contrast, + paintGamma, + deviceGamma); + int width, height; + maskGamma.getGammaTableDimensions(&width, &height); + size_t size = width*height*sizeof(uint8_t); + const uint8_t* gammaTables = maskGamma.getGammaTables(); + memcpy(data, gammaTables, size); +} + + /////////////////////////////////////////////////////////////////////////////// #include "SkStream.h" @@ -2557,7 +2583,7 @@ SkTextToPathIter::SkTextToPathIter( const char text[], size_t length, fPaint.setPathEffect(NULL); } - fCache = fPaint.detachCache(NULL, NULL); + fCache = fPaint.detachCache(NULL, NULL, false); SkPaint::Style style = SkPaint::kFill_Style; SkPathEffect* pe = NULL; diff --git a/src/core/SkScalerContext.h b/src/core/SkScalerContext.h index f18d217f62..af83685eb6 100644 --- a/src/core/SkScalerContext.h +++ b/src/core/SkScalerContext.h @@ -184,6 +184,17 @@ public: void getPath(const SkGlyph&, SkPath*); void getFontMetrics(SkPaint::FontMetrics*); + /** Return the size in bytes of the associated gamma lookup table + */ + static size_t GetGammaLUTSize(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma, + int* width, int* height); + + /** Get the associated gamma lookup table. The 'data' pointer must point to pre-allocated + memory, with size in bytes greater than or equal to the return value of getGammaLUTSize(). + */ + static void GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma, + void* data); + #ifdef SK_BUILD_FOR_ANDROID unsigned getBaseGlyphCount(SkUnichar charCode); |