Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Unified Diff: src/effects/gradients/SkGradientShader.cpp

Issue 207683004: Extract most of the mutable state of SkShader into a separate Context object. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase & cleanup Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/effects/gradients/SkGradientShader.cpp
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index b1fa560dfcc13df980c92815711e22a1932202be..3b40043a4cb04d2b3abb420cb57cdc883986a2dc 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -15,8 +15,6 @@
SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc) {
SkASSERT(desc.fCount > 1);
- fCacheAlpha = 256; // init to a value that paint.getAlpha() can't return
-
fMapper = desc.fMapper;
SkSafeRef(fMapper);
fGradFlags = SkToU8(desc.fFlags);
@@ -26,10 +24,6 @@ SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc) {
fTileMode = desc.fTileMode;
fTileProc = gTileProcs[desc.fTileMode];
- fCache16 = fCache16Storage = 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
In these cases, we insert dummy entries to ensure that the final data
@@ -144,14 +138,8 @@ static uint32_t unpack_flags(uint32_t packed) {
}
SkGradientShaderBase::SkGradientShaderBase(SkReadBuffer& buffer) : INHERITED(buffer) {
- fCacheAlpha = 256;
-
fMapper = buffer.readUnitMapper();
- fCache16 = fCache16Storage = NULL;
- fCache32 = NULL;
- fCache32PixelRef = NULL;
-
int colorCount = fColorCount = buffer.getArrayCount();
if (colorCount > kColorStorageCount) {
size_t allocSize = (sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec)) * colorCount;
@@ -186,10 +174,6 @@ SkGradientShaderBase::SkGradientShaderBase(SkReadBuffer& buffer) : INHERITED(buf
}
SkGradientShaderBase::~SkGradientShaderBase() {
- if (fCache16Storage) {
- sk_free(fCache16Storage);
- }
- SkSafeUnref(fCache32PixelRef);
if (fOrigColors != fStorage) {
sk_free(fOrigColors);
}
@@ -197,7 +181,6 @@ SkGradientShaderBase::~SkGradientShaderBase() {
}
void SkGradientShaderBase::initCommon() {
- fFlags = 0;
unsigned colorAlpha = 0xFF;
for (int i = 0; i < fColorCount; i++) {
colorAlpha &= SkColorGetA(fOrigColors[i]);
@@ -224,49 +207,45 @@ bool SkGradientShaderBase::isOpaque() const {
return fColorsAreOpaque;
}
-bool SkGradientShaderBase::setContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix) {
- if (!this->INHERITED::setContext(device, paint, matrix)) {
- return false;
- }
-
+SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext(
+ const SkGradientShaderBase& shader, const SkBitmap& device,
+ const SkPaint& paint, const SkMatrix& matrix)
+ : INHERITED(shader, device, paint, matrix)
+ , fCache(this->getPaintAlpha())
+{
const SkMatrix& inverse = this->getTotalInverse();
- fDstToIndex.setConcat(fPtsToUnit, inverse);
+ fDstToIndex.setConcat(shader.fPtsToUnit, inverse);
+
fDstToIndexProc = fDstToIndex.getMapXYProc();
- fDstToIndexClass = (uint8_t)SkShader::ComputeMatrixClass(fDstToIndex);
+ fDstToIndexClass = (uint8_t)SkShader::Context::ComputeMatrixClass(fDstToIndex);
// now convert our colors in to PMColors
unsigned paintAlpha = this->getPaintAlpha();
fFlags = this->INHERITED::getFlags();
- if (fColorsAreOpaque && paintAlpha == 0xFF) {
+ if (shader.fColorsAreOpaque && paintAlpha == 0xFF) {
fFlags |= kOpaqueAlpha_Flag;
}
// we can do span16 as long as our individual colors are opaque,
// regardless of the paint's alpha
- if (fColorsAreOpaque) {
+ if (shader.fColorsAreOpaque) {
fFlags |= kHasSpan16_Flag;
}
+}
- this->setCacheAlpha(paintAlpha);
- return true;
+SkGradientShaderBase::GradientShaderCache::GradientShaderCache(U8CPU alpha) {
+ // Only initialize the cache in getCache16/32.
+ fCache16 = NULL;
+ fCache32 = NULL;
+ fCache16Storage = NULL;
+ fCache32PixelRef = NULL;
+ fCacheAlpha = alpha;
}
-void SkGradientShaderBase::setCacheAlpha(U8CPU alpha) const {
- // if the new alpha differs from the previous time we were called, inval our cache
- // this will trigger the cache to be rebuilt.
- // we don't care about the first time, since the cache ptrs will already be NULL
- if (fCacheAlpha != alpha) {
- fCache16 = NULL; // inval the cache
- fCache32 = NULL; // inval the cache
- fCacheAlpha = alpha; // record the new alpha
- // inform our subclasses
- if (fCache32PixelRef) {
- fCache32PixelRef->notifyPixelsChanged();
- }
- }
+SkGradientShaderBase::GradientShaderCache::~GradientShaderCache() {
+ sk_free(fCache16Storage);
+ SkSafeUnref(fCache32PixelRef);
}
#define Fixed_To_Dot8(x) (((x) + 0x80) >> 8)
@@ -275,8 +254,8 @@ void SkGradientShaderBase::setCacheAlpha(U8CPU alpha) const {
build a 16bit table as long as the original colors are opaque, even if the
paint specifies a non-opaque alpha.
*/
-void SkGradientShaderBase::Build16bitCache(uint16_t cache[], SkColor c0, SkColor c1,
- int count) {
+void SkGradientShaderBase::GradientShaderCache::Build16bitCache(
+ uint16_t cache[], SkColor c0, SkColor c1, int count) {
SkASSERT(count > 1);
SkASSERT(SkColorGetA(c0) == 0xFF);
SkASSERT(SkColorGetA(c1) == 0xFF);
@@ -324,8 +303,9 @@ void SkGradientShaderBase::Build16bitCache(uint16_t cache[], SkColor c0, SkColor
*/
typedef uint32_t SkUFixed;
-void SkGradientShaderBase::Build32bitCache(SkPMColor cache[], SkColor c0, SkColor c1,
- int count, U8CPU paintAlpha, uint32_t gradFlags) {
+void SkGradientShaderBase::GradientShaderCache::Build32bitCache(
+ SkPMColor cache[], SkColor c0, SkColor c1,
+ int count, U8CPU paintAlpha, uint32_t gradFlags) {
SkASSERT(count > 1);
// need to apply paintAlpha to our two endpoints
@@ -468,7 +448,8 @@ static inline U16CPU bitsTo16(unsigned x, const unsigned bits) {
return 0;
}
-const uint16_t* SkGradientShaderBase::getCache16() const {
+const uint16_t* SkGradientShaderBase::GradientShaderCache::getCache16(
+ const SkGradientShaderBase& shader) {
if (fCache16 == NULL) {
// double the count for dither entries
const int entryCount = kCache16Count * 2;
@@ -478,27 +459,28 @@ const uint16_t* SkGradientShaderBase::getCache16() const {
fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize);
}
fCache16 = fCache16Storage;
- if (fColorCount == 2) {
- Build16bitCache(fCache16, fOrigColors[0], fOrigColors[1],
+ if (shader.fColorCount == 2) {
+ Build16bitCache(fCache16, shader.fOrigColors[0], shader.fOrigColors[1],
kCache16Count);
} else {
- Rec* rec = fRecs;
+ Rec* rec = shader.fRecs;
int prevIndex = 0;
- for (int i = 1; i < fColorCount; i++) {
+ for (int i = 1; i < shader.fColorCount; i++) {
int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache16Shift;
SkASSERT(nextIndex < kCache16Count);
if (nextIndex > prevIndex)
- Build16bitCache(fCache16 + prevIndex, fOrigColors[i-1], fOrigColors[i], nextIndex - prevIndex + 1);
+ Build16bitCache(fCache16 + prevIndex, shader.fOrigColors[i-1],
+ shader.fOrigColors[i], nextIndex - prevIndex + 1);
prevIndex = nextIndex;
}
}
- if (fMapper) {
+ if (shader.fMapper) {
fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize);
uint16_t* linear = fCache16; // just computed linear data
uint16_t* mapped = fCache16Storage; // storage for mapped data
- SkUnitMapper* map = fMapper;
+ SkUnitMapper* map = shader.fMapper;
for (int i = 0; i < kCache16Count; i++) {
int index = map->mapUnit16(bitsTo16(i, kCache16Bits)) >> kCache16Shift;
mapped[i] = linear[index];
@@ -511,7 +493,8 @@ const uint16_t* SkGradientShaderBase::getCache16() const {
return fCache16;
}
-const SkPMColor* SkGradientShaderBase::getCache32() const {
+const SkPMColor* SkGradientShaderBase::GradientShaderCache::getCache32(
+ const SkGradientShaderBase& shader) {
if (fCache32 == NULL) {
SkImageInfo info;
info.fWidth = kCache32Count;
@@ -523,29 +506,29 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
fCache32PixelRef = SkMallocPixelRef::NewAllocate(info, 0, NULL);
}
fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
- if (fColorCount == 2) {
- Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1],
- kCache32Count, fCacheAlpha, fGradFlags);
+ if (shader.fColorCount == 2) {
+ Build32bitCache(fCache32, shader.fOrigColors[0], shader.fOrigColors[1],
+ kCache32Count, fCacheAlpha, shader.fGradFlags);
} else {
- Rec* rec = fRecs;
+ Rec* rec = shader.fRecs;
int prevIndex = 0;
- for (int i = 1; i < fColorCount; i++) {
+ for (int i = 1; i < shader.fColorCount; i++) {
int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache32Shift;
SkASSERT(nextIndex < kCache32Count);
if (nextIndex > prevIndex)
- Build32bitCache(fCache32 + prevIndex, fOrigColors[i-1],
- fOrigColors[i], nextIndex - prevIndex + 1,
- fCacheAlpha, fGradFlags);
+ Build32bitCache(fCache32 + prevIndex, shader.fOrigColors[i-1],
+ shader.fOrigColors[i], nextIndex - prevIndex + 1,
+ fCacheAlpha, shader.fGradFlags);
prevIndex = nextIndex;
}
}
- if (fMapper) {
+ if (shader.fMapper) {
SkMallocPixelRef* newPR = SkMallocPixelRef::NewAllocate(info, 0, NULL);
SkPMColor* linear = fCache32; // just computed linear data
SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
- SkUnitMapper* map = fMapper;
+ SkUnitMapper* map = shader.fMapper;
for (int i = 0; i < kCache32Count; i++) {
int index = map->mapUnit16((i << 8) | i) >> 8;
mapped[i + kCache32Count*0] = linear[index + kCache32Count*0];
@@ -572,14 +555,14 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const {
// our caller assumes no external alpha, so we ensure that our cache is
// built with 0xFF
- this->setCacheAlpha(0xFF);
+ GradientShaderCache cache(0xFF);
// 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();
+ (void)cache.getCache32(*this);
bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1));
- bitmap->setPixelRef(fCache32PixelRef);
+ bitmap->setPixelRef(cache.getCache32PixelRef());
return;
}
@@ -618,9 +601,9 @@ void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const {
if (!gCache->find(storage.get(), size, bitmap)) {
// force our cahce32pixelref to be built
- (void)this->getCache32();
+ (void)cache.getCache32(*this);
bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1));
- bitmap->setPixelRef(fCache32PixelRef);
+ bitmap->setPixelRef(cache.getCache32PixelRef());
gCache->add(storage.get(), size, *bitmap);
}

Powered by Google App Engine
This is Rietveld 408576698