diff options
Diffstat (limited to 'src/effects/gradients')
-rw-r--r-- | src/effects/gradients/SkGradientShader.cpp | 75 | ||||
-rw-r--r-- | src/effects/gradients/SkGradientShaderPriv.h | 3 |
2 files changed, 65 insertions, 13 deletions
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp index ada9859017..e43a0264de 100644 --- a/src/effects/gradients/SkGradientShader.cpp +++ b/src/effects/gradients/SkGradientShader.cpp @@ -17,6 +17,8 @@ SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc, const SkMatri { SkASSERT(desc.fCount > 1); + fMapper = desc.fMapper; + SkSafeRef(fMapper); fGradFlags = SkToU8(desc.fGradFlags); SkASSERT((unsigned)desc.fTileMode < SkShader::kTileModeCount); @@ -140,10 +142,7 @@ static uint32_t unpack_flags(uint32_t packed) { } SkGradientShaderBase::SkGradientShaderBase(SkReadBuffer& buffer) : INHERITED(buffer) { - if (buffer.isVersionLT(SkReadBuffer::kNoUnitMappers_Version)) { - // skip the old SkUnitMapper slot - buffer.skipFlattenable(); - } + fMapper = buffer.readUnitMapper(); int colorCount = fColorCount = buffer.getArrayCount(); if (colorCount > kColorStorageCount) { @@ -182,6 +181,7 @@ SkGradientShaderBase::~SkGradientShaderBase() { if (fOrigColors != fStorage) { sk_free(fOrigColors); } + SkSafeUnref(fMapper); } void SkGradientShaderBase::initCommon() { @@ -194,6 +194,7 @@ void SkGradientShaderBase::initCommon() { void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const { this->INHERITED::flatten(buffer); + buffer.writeFlattenable(fMapper); buffer.writeColorArray(fOrigColors, fColorCount); buffer.writeUInt(pack_mode_flags(fTileMode, fGradFlags)); if (fColorCount > 2) { @@ -515,6 +516,20 @@ void SkGradientShaderBase::GradientShaderCache::initCache16(GradientShaderCache* prevIndex = nextIndex; } } + + if (cache->fShader.fMapper) { + cache->fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize); + uint16_t* linear = cache->fCache16; // just computed linear data + uint16_t* mapped = cache->fCache16Storage; // storage for mapped data + SkUnitMapper* map = cache->fShader.fMapper; + for (int i = 0; i < kCache16Count; i++) { + int index = map->mapUnit16(bitsTo16(i, kCache16Bits)) >> kCache16Shift; + mapped[i] = linear[index]; + mapped[i + kCache16Count] = linear[index + kCache16Count]; + } + sk_free(cache->fCache16); + cache->fCache16 = cache->fCache16Storage; + } } const SkPMColor* SkGradientShaderBase::GradientShaderCache::getCache32() { @@ -552,6 +567,23 @@ void SkGradientShaderBase::GradientShaderCache::initCache32(GradientShaderCache* prevIndex = nextIndex; } } + + if (cache->fShader.fMapper) { + SkMallocPixelRef* newPR = SkMallocPixelRef::NewAllocate(info, 0, NULL); + SkPMColor* linear = cache->fCache32; // just computed linear data + SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data + SkUnitMapper* map = cache->fShader.fMapper; + for (int i = 0; i < kCache32Count; i++) { + int index = map->mapUnit16((i << 8) | i) >> 8; + mapped[i + kCache32Count*0] = linear[index + kCache32Count*0]; + mapped[i + kCache32Count*1] = linear[index + kCache32Count*1]; + mapped[i + kCache32Count*2] = linear[index + kCache32Count*2]; + mapped[i + kCache32Count*3] = linear[index + kCache32Count*3]; + } + cache->fCache32PixelRef->unref(); + cache->fCache32PixelRef = newPR; + cache->fCache32 = (SkPMColor*)newPR->getAddr(); + } } /* @@ -583,6 +615,15 @@ void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const { // built with 0xFF SkAutoTUnref<GradientShaderCache> cache(this->refCache(0xFF)); + // don't have a way to put the mapper into our cache-key yet + if (fMapper) { + // force our cache32pixelref to be built + (void)cache->getCache32(); + bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1)); + bitmap->setPixelRef(cache->getCache32PixelRef()); + return; + } + // build our key: [numColors + colors[] + {positions[]} + flags ] int count = 1 + fColorCount + 1; if (fColorCount > 2) { @@ -691,6 +732,8 @@ void SkGradientShaderBase::toString(SkString* str) const { str->append(" "); str->append(gTileModeName[fTileMode]); + // TODO: add "fMapper->toString(str);" when SkUnitMapper::toString is added + this->INHERITED::toString(str); } #endif @@ -715,11 +758,13 @@ void SkGradientShaderBase::toString(SkString* str) const { static void desc_init(SkGradientShaderBase::Descriptor* desc, const SkColor colors[], const SkScalar pos[], int colorCount, - SkShader::TileMode mode, uint32_t flags) { + SkShader::TileMode mode, + SkUnitMapper* mapper, uint32_t flags) { desc->fColors = colors; desc->fPos = pos; desc->fCount = colorCount; desc->fTileMode = mode; + desc->fMapper = mapper; desc->fGradFlags = flags; } @@ -727,6 +772,7 @@ SkShader* SkGradientShader::CreateLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int colorCount, SkShader::TileMode mode, + SkUnitMapper* mapper, uint32_t flags, const SkMatrix* localMatrix) { if (NULL == pts || NULL == colors || colorCount < 1) { @@ -735,7 +781,7 @@ SkShader* SkGradientShader::CreateLinear(const SkPoint pts[2], EXPAND_1_COLOR(colorCount); SkGradientShaderBase::Descriptor desc; - desc_init(&desc, colors, pos, colorCount, mode, flags); + desc_init(&desc, colors, pos, colorCount, mode, mapper, flags); return SkNEW_ARGS(SkLinearGradient, (pts, desc, localMatrix)); } @@ -743,6 +789,7 @@ SkShader* SkGradientShader::CreateRadial(const SkPoint& center, SkScalar radius, const SkColor colors[], const SkScalar pos[], int colorCount, SkShader::TileMode mode, + SkUnitMapper* mapper, uint32_t flags, const SkMatrix* localMatrix) { if (radius <= 0 || NULL == colors || colorCount < 1) { @@ -751,7 +798,7 @@ SkShader* SkGradientShader::CreateRadial(const SkPoint& center, SkScalar radius, EXPAND_1_COLOR(colorCount); SkGradientShaderBase::Descriptor desc; - desc_init(&desc, colors, pos, colorCount, mode, flags); + desc_init(&desc, colors, pos, colorCount, mode, mapper, flags); return SkNEW_ARGS(SkRadialGradient, (center, radius, desc, localMatrix)); } @@ -763,6 +810,7 @@ SkShader* SkGradientShader::CreateTwoPointRadial(const SkPoint& start, const SkScalar pos[], int colorCount, SkShader::TileMode mode, + SkUnitMapper* mapper, uint32_t flags, const SkMatrix* localMatrix) { if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) { @@ -771,7 +819,7 @@ SkShader* SkGradientShader::CreateTwoPointRadial(const SkPoint& start, EXPAND_1_COLOR(colorCount); SkGradientShaderBase::Descriptor desc; - desc_init(&desc, colors, pos, colorCount, mode, flags); + desc_init(&desc, colors, pos, colorCount, mode, mapper, flags); return SkNEW_ARGS(SkTwoPointRadialGradient, (start, startRadius, end, endRadius, desc, localMatrix)); } @@ -784,6 +832,7 @@ SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start, const SkScalar pos[], int colorCount, SkShader::TileMode mode, + SkUnitMapper* mapper, uint32_t flags, const SkMatrix* localMatrix) { if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) { @@ -800,7 +849,7 @@ SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start, SkGradientShaderBase::Descriptor desc; if (!flipGradient) { - desc_init(&desc, colors, pos, colorCount, mode, flags); + desc_init(&desc, colors, pos, colorCount, mode, mapper, flags); return SkNEW_ARGS(SkTwoPointConicalGradient, (start, startRadius, end, endRadius, flipGradient, desc, localMatrix)); } else { @@ -814,9 +863,9 @@ SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start, for (int i = 0; i < colorCount; ++i) { posNew[i] = 1 - pos[colorCount - i - 1]; } - desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, flags); + desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, mapper, flags); } else { - desc_init(&desc, colorsNew.get(), NULL, colorCount, mode, flags); + desc_init(&desc, colorsNew.get(), NULL, colorCount, mode, mapper, flags); } return SkNEW_ARGS(SkTwoPointConicalGradient, @@ -827,7 +876,7 @@ SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start, SkShader* SkGradientShader::CreateSweep(SkScalar cx, SkScalar cy, const SkColor colors[], const SkScalar pos[], - int colorCount, + int colorCount, SkUnitMapper* mapper, uint32_t flags, const SkMatrix* localMatrix) { if (NULL == colors || colorCount < 1) { @@ -836,7 +885,7 @@ SkShader* SkGradientShader::CreateSweep(SkScalar cx, SkScalar cy, EXPAND_1_COLOR(colorCount); SkGradientShaderBase::Descriptor desc; - desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, flags); + desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, mapper, flags); return SkNEW_ARGS(SkSweepGradient, (cx, cy, desc, localMatrix)); } diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h index 9613537803..a699c4ce00 100644 --- a/src/effects/gradients/SkGradientShaderPriv.h +++ b/src/effects/gradients/SkGradientShaderPriv.h @@ -14,6 +14,7 @@ #include "SkReadBuffer.h" #include "SkWriteBuffer.h" #include "SkMallocPixelRef.h" +#include "SkUnitMapper.h" #include "SkUtils.h" #include "SkTemplates.h" #include "SkBitmapCache.h" @@ -93,6 +94,7 @@ public: const SkScalar* fPos; int fCount; SkShader::TileMode fTileMode; + SkUnitMapper* fMapper; uint32_t fGradFlags; }; @@ -199,6 +201,7 @@ protected: virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; SK_TO_STRING_OVERRIDE() + SkUnitMapper* fMapper; SkMatrix fPtsToUnit; // set by subclass TileMode fTileMode; TileProc fTileProc; |