#include "SkTwoPointConicalGradient.h"
#include "SkSweepGradient.h"
-SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc, const SkMatrix* localMatrix)
- : INHERITED(localMatrix)
+void SkGradientShaderBase::Descriptor::flatten(SkWriteBuffer& buffer) const {
+ buffer.writeColorArray(fColors, fCount);
+ if (fPos) {
+ buffer.writeBool(true);
+ buffer.writeScalarArray(fPos, fCount);
+ } else {
+ buffer.writeBool(false);
+ }
+ buffer.write32(fTileMode);
+ buffer.write32(fGradFlags);
+ if (fLocalMatrix) {
+ buffer.writeBool(true);
+ buffer.writeMatrix(*fLocalMatrix);
+ } else {
+ buffer.writeBool(false);
+ }
+}
+
+bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) {
+ fCount = buffer.getArrayCount();
+ if (fCount > kStorageCount) {
+ size_t allocSize = (sizeof(SkColor) + sizeof(SkScalar)) * fCount;
+ fDynamicStorage.reset(allocSize);
+ fColors = (SkColor*)fDynamicStorage.get();
+ fPos = (SkScalar*)(fColors + fCount);
+ } else {
+ fColors = fColorStorage;
+ fPos = fPosStorage;
+ }
+
+ if (!buffer.readColorArray(const_cast<SkColor*>(fColors), fCount)) {
+ return false;
+ }
+ if (buffer.readBool()) {
+ if (!buffer.readScalarArray(const_cast<SkScalar*>(fPos), fCount)) {
+ return false;
+ }
+ } else {
+ fPos = NULL;
+ }
+
+ fTileMode = (SkShader::TileMode)buffer.read32();
+ fGradFlags = buffer.read32();
+
+ if (buffer.readBool()) {
+ fLocalMatrix = &fLocalMatrixStorage;
+ buffer.readMatrix(&fLocalMatrixStorage);
+ } else {
+ fLocalMatrix = NULL;
+ }
+ return buffer.isValid();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+
+SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc)
+ : INHERITED(desc.fLocalMatrix)
{
SkASSERT(desc.fCount > 1);
if (fColorCount > kColorStorageCount) {
size_t size = sizeof(SkColor) + sizeof(Rec);
+ if (desc.fPos) {
+ size += sizeof(SkScalar);
+ }
fOrigColors = reinterpret_cast<SkColor*>(
sk_malloc_throw(size * fColorCount));
}
}
}
- fRecs = (Rec*)(fOrigColors + fColorCount);
+ if (desc.fPos && fColorCount) {
+ fOrigPos = (SkScalar*)(fOrigColors + fColorCount);
+ fRecs = (Rec*)(fOrigPos + fColorCount);
+ } else {
+ fOrigPos = NULL;
+ fRecs = (Rec*)(fOrigColors + fColorCount);
+ }
+
if (fColorCount > 2) {
Rec* recs = fRecs;
recs->fPos = 0;
// recs->fScale = 0; // unused;
recs += 1;
if (desc.fPos) {
+ SkScalar* origPosPtr = fOrigPos;
+ *origPosPtr++ = 0;
+
/* We need to convert the user's array of relative positions into
fixed-point positions and scale factors. We need these results
to be strictly monotonic (no two values equal or out of order).
value if it sees a segment out of order, and it assures that
we start at 0 and end at 1.0
*/
- SkFixed prev = 0;
+ SkScalar prev = 0;
int startIndex = dummyFirst ? 0 : 1;
int count = desc.fCount + dummyLast;
for (int i = startIndex; i < count; i++) {
// force the last value to be 1.0
- SkFixed curr;
+ SkScalar curr;
if (i == desc.fCount) { // we're really at the dummyLast
- curr = SK_Fixed1;
+ curr = 1;
} else {
- curr = SkScalarToFixed(desc.fPos[i]);
- }
- // pin curr withing range
- if (curr < 0) {
- curr = 0;
- } else if (curr > SK_Fixed1) {
- curr = SK_Fixed1;
+ curr = SkScalarPin(desc.fPos[i], 0, 1);
}
- recs->fPos = curr;
- if (curr > prev) {
- recs->fScale = (1 << 24) / (curr - prev);
+ *origPosPtr++ = curr;
+
+ recs->fPos = SkScalarToFixed(curr);
+ SkFixed diff = SkScalarToFixed(curr - prev);
+ if (diff > 0) {
+ recs->fScale = (1 << 24) / diff;
} else {
recs->fScale = 0; // ignore this segment
}
recs += 1;
}
} else { // assume even distribution
+ fOrigPos = NULL;
+
SkFixed dp = SK_Fixed1 / (desc.fCount - 1);
SkFixed p = dp;
SkFixed scale = (desc.fCount - 1) << 8; // (1 << 24) / dp
recs->fPos = SK_Fixed1;
recs->fScale = scale;
}
+ } else if (desc.fPos) {
+ SkASSERT(2 == fColorCount);
+ fOrigPos[0] = SkScalarPin(desc.fPos[0], 0, 1);
+ fOrigPos[1] = SkScalarPin(desc.fPos[1], fOrigPos[0], 1);
+ if (0 == fOrigPos[0] && 1 == fOrigPos[1]) {
+ fOrigPos = NULL;
+ }
}
this->initCommon();
}
-static uint32_t pack_mode_flags(SkShader::TileMode mode, uint32_t flags) {
- SkASSERT(0 == (flags >> 28));
- SkASSERT(0 == ((uint32_t)mode >> 4));
- return (flags << 4) | mode;
-}
-
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
static SkShader::TileMode unpack_mode(uint32_t packed) {
return (SkShader::TileMode)(packed & 0xF);
}
int colorCount = fColorCount = buffer.getArrayCount();
if (colorCount > kColorStorageCount) {
- size_t allocSize = (sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec)) * colorCount;
+ size_t allocSize = (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec)) * colorCount;
if (buffer.validateAvailable(allocSize)) {
fOrigColors = reinterpret_cast<SkColor*>(sk_malloc_throw(allocSize));
} else {
}
buffer.readColorArray(fOrigColors, colorCount);
+ fOrigPos = (SkScalar*)(fOrigColors + colorCount);
+
{
uint32_t packed = buffer.readUInt();
fGradFlags = SkToU8(unpack_flags(packed));
fTileMode = unpack_mode(packed);
}
fTileProc = gTileProcs[fTileMode];
- fRecs = (Rec*)(fOrigColors + colorCount);
+ fRecs = (Rec*)(fOrigPos + colorCount);
if (colorCount > 2) {
Rec* recs = fRecs;
recs[0].fPos = 0;
+ fOrigPos[0] = 0;
for (int i = 1; i < colorCount; i++) {
recs[i].fPos = buffer.readInt();
recs[i].fScale = buffer.readUInt();
+ fOrigPos[i] = SkFixedToScalar(recs[i].fPos);
}
+ } else {
+ fOrigPos = NULL;
}
buffer.readMatrix(&fPtsToUnit);
this->initCommon();
}
+#endif
SkGradientShaderBase::~SkGradientShaderBase() {
if (fOrigColors != fStorage) {
}
void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const {
- this->INHERITED::flatten(buffer);
- buffer.writeColorArray(fOrigColors, fColorCount);
- buffer.writeUInt(pack_mode_flags(fTileMode, fGradFlags));
- if (fColorCount > 2) {
- Rec* recs = fRecs;
- for (int i = 1; i < fColorCount; i++) {
- buffer.writeInt(recs[i].fPos);
- buffer.writeUInt(recs[i].fScale);
- }
- }
- buffer.writeMatrix(fPtsToUnit);
+ Descriptor desc;
+ desc.fColors = fOrigColors;
+ desc.fPos = fOrigPos;
+ desc.fCount = fColorCount;
+ desc.fTileMode = fTileMode;
+ desc.fGradFlags = fGradFlags;
+
+ const SkMatrix& m = this->getLocalMatrix();
+ desc.fLocalMatrix = m.isIdentity() ? NULL : &m;
+ desc.flatten(buffer);
}
SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor colors[3]) const {
return fColorsAreOpaque;
}
+static unsigned rounded_divide(unsigned numer, unsigned denom) {
+ return (numer + (denom >> 1)) / denom;
+}
+
+bool SkGradientShaderBase::onAsLuminanceColor(SkColor* lum) const {
+ // we just compute an average color.
+ // possibly we could weight this based on the proportional width for each color
+ // assuming they are not evenly distributed in the fPos array.
+ int r = 0;
+ int g = 0;
+ int b = 0;
+ const int n = fColorCount;
+ for (int i = 0; i < n; ++i) {
+ SkColor c = fOrigColors[i];
+ r += SkColorGetR(c);
+ g += SkColorGetG(c);
+ b += SkColorGetB(c);
+ }
+ *lum = SkColorSetRGB(rounded_divide(r, n), rounded_divide(g, n), rounded_divide(b, n));
+ return true;
+}
+
SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext(
const SkGradientShaderBase& shader, const ContextRec& rec)
: INHERITED(shader, rec)
}
void SkGradientShaderBase::GradientShaderCache::initCache32(GradientShaderCache* cache) {
- SkImageInfo info;
- info.fWidth = kCache32Count;
- info.fHeight = 4; // for our 4 dither rows
- info.fAlphaType = kPremul_SkAlphaType;
- info.fColorType = kN32_SkColorType;
+ const int kNumberOfDitherRows = 4;
+ const SkImageInfo info = SkImageInfo::MakeN32Premul(kCache32Count, kNumberOfDitherRows);
SkASSERT(NULL == cache->fCache32PixelRef);
cache->fCache32PixelRef = SkMallocPixelRef::NewAllocate(info, 0, NULL);
return fCache;
}
+SK_DECLARE_STATIC_MUTEX(gGradientCacheMutex);
/*
* 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,
///////////////////////////////////
- SK_DECLARE_STATIC_MUTEX(gMutex);
- static SkBitmapCache* gCache;
+ static SkGradientBitmapCache* 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);
+ SkAutoMutexAcquire ama(gGradientCacheMutex);
if (NULL == gCache) {
- gCache = SkNEW_ARGS(SkBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS));
+ gCache = SkNEW_ARGS(SkGradientBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS));
}
size_t size = count * sizeof(int32_t);
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-#include "SkEmptyShader.h"
-
// assumes colors is SkColor* and pos is SkScalar*
#define EXPAND_1_COLOR(count) \
SkColor tmp[2]; \
} while (0)
static void desc_init(SkGradientShaderBase::Descriptor* desc,
- const SkColor colors[],
- const SkScalar pos[], int colorCount,
- SkShader::TileMode mode, uint32_t flags) {
+ const SkColor colors[], const SkScalar pos[], int colorCount,
+ SkShader::TileMode mode, uint32_t flags, const SkMatrix* localMatrix) {
desc->fColors = colors;
desc->fPos = pos;
desc->fCount = colorCount;
desc->fTileMode = mode;
desc->fGradFlags = flags;
+ desc->fLocalMatrix = localMatrix;
}
SkShader* SkGradientShader::CreateLinear(const SkPoint pts[2],
EXPAND_1_COLOR(colorCount);
SkGradientShaderBase::Descriptor desc;
- desc_init(&desc, colors, pos, colorCount, mode, flags);
- return SkNEW_ARGS(SkLinearGradient, (pts, desc, localMatrix));
+ desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
+ return SkNEW_ARGS(SkLinearGradient, (pts, desc));
}
SkShader* SkGradientShader::CreateRadial(const SkPoint& center, SkScalar radius,
EXPAND_1_COLOR(colorCount);
SkGradientShaderBase::Descriptor desc;
- desc_init(&desc, colors, pos, colorCount, mode, flags);
- return SkNEW_ARGS(SkRadialGradient, (center, radius, desc, localMatrix));
+ desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
+ return SkNEW_ARGS(SkRadialGradient, (center, radius, desc));
}
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, flags, localMatrix);
return SkNEW_ARGS(SkTwoPointRadialGradient,
- (start, startRadius, end, endRadius, desc, localMatrix));
+ (start, startRadius, end, endRadius, desc));
}
SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start,
return NULL;
}
if (start == end && startRadius == endRadius) {
- return SkNEW(SkEmptyShader);
+ return SkShader::CreateEmptyShader();
}
EXPAND_1_COLOR(colorCount);
SkGradientShaderBase::Descriptor desc;
if (!flipGradient) {
- desc_init(&desc, colors, pos, colorCount, mode, flags);
+ desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
return SkNEW_ARGS(SkTwoPointConicalGradient,
- (start, startRadius, end, endRadius, flipGradient, desc, localMatrix));
+ (start, startRadius, end, endRadius, flipGradient, desc));
} else {
SkAutoSTArray<8, SkColor> colorsNew(colorCount);
SkAutoSTArray<8, SkScalar> posNew(colorCount);
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, flags, localMatrix);
} else {
- desc_init(&desc, colorsNew.get(), NULL, colorCount, mode, flags);
+ desc_init(&desc, colorsNew.get(), NULL, colorCount, mode, flags, localMatrix);
}
return SkNEW_ARGS(SkTwoPointConicalGradient,
- (end, endRadius, start, startRadius, flipGradient, desc, localMatrix));
+ (end, endRadius, start, startRadius, flipGradient, desc));
}
}
EXPAND_1_COLOR(colorCount);
SkGradientShaderBase::Descriptor desc;
- desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, flags);
- return SkNEW_ARGS(SkSweepGradient, (cx, cy, desc, localMatrix));
+ desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, flags, localMatrix);
+ return SkNEW_ARGS(SkSweepGradient, (cx, cy, desc));
}
SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader)
#if SK_SUPPORT_GPU
#include "effects/GrTextureStripAtlas.h"
-#include "GrTBackendEffectFactory.h"
+#include "GrTBackendProcessorFactory.h"
+#include "gl/builders/GrGLProgramBuilder.h"
#include "SkGr.h"
-GrGLGradientEffect::GrGLGradientEffect(const GrBackendEffectFactory& factory)
+GrGLGradientEffect::GrGLGradientEffect(const GrBackendProcessorFactory& factory)
: INHERITED(factory)
, fCachedYCoord(SK_ScalarMax) {
}
GrGLGradientEffect::~GrGLGradientEffect() { }
-void GrGLGradientEffect::emitUniforms(GrGLShaderBuilder* builder, EffectKey key) {
+void GrGLGradientEffect::emitUniforms(GrGLFPBuilder* builder, uint32_t baseKey) {
- if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(key)) { // 2 Color case
- fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(baseKey)) { // 2 Color case
+ fColorStartUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "GradientStartColor");
- fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fColorEndUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "GradientEndColor");
- } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(key)){ // 3 Color Case
- fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(baseKey)){ // 3 Color Case
+ fColorStartUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "GradientStartColor");
- fColorMidUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fColorMidUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "GradientMidColor");
- fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fColorEndUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, "GradientEndColor");
} else { // if not a fast case
- fFSYUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
+ fFSYUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, "GradientYCoordFS");
}
}
-static inline void set_color_uni(const GrGLUniformManager& uman,
- const GrGLUniformManager::UniformHandle uni,
+static inline void set_color_uni(const GrGLProgramDataManager& pdman,
+ const GrGLProgramDataManager::UniformHandle uni,
const SkColor* color) {
- uman.set4f(uni,
- SkColorGetR(*color) / 255.f,
- SkColorGetG(*color) / 255.f,
- SkColorGetB(*color) / 255.f,
- SkColorGetA(*color) / 255.f);
+ pdman.set4f(uni,
+ SkColorGetR(*color) / 255.f,
+ SkColorGetG(*color) / 255.f,
+ SkColorGetB(*color) / 255.f,
+ SkColorGetA(*color) / 255.f);
}
-static inline void set_mul_color_uni(const GrGLUniformManager& uman,
- const GrGLUniformManager::UniformHandle uni,
+static inline void set_mul_color_uni(const GrGLProgramDataManager& pdman,
+ const GrGLProgramDataManager::UniformHandle uni,
const SkColor* color){
float a = SkColorGetA(*color) / 255.f;
float aDiv255 = a / 255.f;
- uman.set4f(uni,
- SkColorGetR(*color) * aDiv255,
- SkColorGetG(*color) * aDiv255,
- SkColorGetB(*color) * aDiv255,
- a);
+ pdman.set4f(uni,
+ SkColorGetR(*color) * aDiv255,
+ SkColorGetG(*color) * aDiv255,
+ SkColorGetB(*color) * aDiv255,
+ a);
}
-void GrGLGradientEffect::setData(const GrGLUniformManager& uman,
- const GrDrawEffect& drawEffect) {
+void GrGLGradientEffect::setData(const GrGLProgramDataManager& pdman,
+ const GrProcessor& processor) {
- const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
+ const GrGradientEffect& e = processor.cast<GrGradientEffect>();
if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()){
if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
- set_mul_color_uni(uman, fColorStartUni, e.getColors(0));
- set_mul_color_uni(uman, fColorEndUni, e.getColors(1));
+ set_mul_color_uni(pdman, fColorStartUni, e.getColors(0));
+ set_mul_color_uni(pdman, fColorEndUni, e.getColors(1));
} else {
- set_color_uni(uman, fColorStartUni, e.getColors(0));
- set_color_uni(uman, fColorEndUni, e.getColors(1));
+ set_color_uni(pdman, fColorStartUni, e.getColors(0));
+ set_color_uni(pdman, fColorEndUni, e.getColors(1));
}
} else if (SkGradientShaderBase::kThree_GpuColorType == e.getColorType()){
if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
- set_mul_color_uni(uman, fColorStartUni, e.getColors(0));
- set_mul_color_uni(uman, fColorMidUni, e.getColors(1));
- set_mul_color_uni(uman, fColorEndUni, e.getColors(2));
+ set_mul_color_uni(pdman, fColorStartUni, e.getColors(0));
+ set_mul_color_uni(pdman, fColorMidUni, e.getColors(1));
+ set_mul_color_uni(pdman, fColorEndUni, e.getColors(2));
} else {
- set_color_uni(uman, fColorStartUni, e.getColors(0));
- set_color_uni(uman, fColorMidUni, e.getColors(1));
- set_color_uni(uman, fColorEndUni, e.getColors(2));
+ set_color_uni(pdman, fColorStartUni, e.getColors(0));
+ set_color_uni(pdman, fColorMidUni, e.getColors(1));
+ set_color_uni(pdman, fColorEndUni, e.getColors(2));
}
} else {
SkScalar yCoord = e.getYCoord();
if (yCoord != fCachedYCoord) {
- uman.set1f(fFSYUni, yCoord);
+ pdman.set1f(fFSYUni, yCoord);
fCachedYCoord = yCoord;
}
}
}
-GrGLEffect::EffectKey GrGLGradientEffect::GenBaseGradientKey(const GrDrawEffect& drawEffect) {
- const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
+uint32_t GrGLGradientEffect::GenBaseGradientKey(const GrProcessor& processor) {
+ const GrGradientEffect& e = processor.cast<GrGradientEffect>();
- EffectKey key = 0;
+ uint32_t key = 0;
if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()) {
key |= kTwoColorKey;
return key;
}
-void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
+void GrGLGradientEffect::emitColor(GrGLFPBuilder* builder,
const char* gradientTValue,
- EffectKey key,
+ uint32_t baseKey,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) {
- if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(key)){
- builder->fsCodeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
+ GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+ if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(baseKey)){
+ fsBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
builder->getUniformVariable(fColorStartUni).c_str(),
builder->getUniformVariable(fColorEndUni).c_str(),
gradientTValue);
// The gradient SkShader reporting opaque is more restrictive than necessary in the two pt
// case. Make sure the key reflects this optimization (and note that it can use the same
// shader as thekBeforeIterp case). This same optimization applies to the 3 color case below.
- if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(key)) {
- builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
+ if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(baseKey)) {
+ fsBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
}
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
- } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(key)){
- builder->fsCodeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
+ } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(baseKey)){
+ fsBuilder->codeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
gradientTValue);
- builder->fsCodeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n",
+ fsBuilder->codeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n",
builder->getUniformVariable(fColorStartUni).c_str());
if (kTegra3_GrGLRenderer == builder->ctxInfo().renderer()) {
// The Tegra3 compiler will sometimes never return if we have
// min(abs(oneMinus2t), 1.0), or do the abs first in a separate expression.
- builder->fsCodeAppend("\tfloat minAbs = abs(oneMinus2t);\n");
- builder->fsCodeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n");
- builder->fsCodeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n",
+ fsBuilder->codeAppend("\tfloat minAbs = abs(oneMinus2t);\n");
+ fsBuilder->codeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n");
+ fsBuilder->codeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n",
builder->getUniformVariable(fColorMidUni).c_str());
} else {
- builder->fsCodeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n",
+ fsBuilder->codeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n",
builder->getUniformVariable(fColorMidUni).c_str());
}
- builder->fsCodeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n",
+ fsBuilder->codeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n",
builder->getUniformVariable(fColorEndUni).c_str());
- if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(key)) {
- builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
+ if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(baseKey)) {
+ fsBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
}
- builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
(GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
} else {
- builder->fsCodeAppendf("\tvec2 coord = vec2(%s, %s);\n",
+ fsBuilder->codeAppendf("\tvec2 coord = vec2(%s, %s);\n",
gradientTValue,
builder->getUniformVariable(fFSYUni).c_str());
- builder->fsCodeAppendf("\t%s = ", outputColor);
- builder->fsAppendTextureLookupAndModulate(inputColor,
+ fsBuilder->codeAppendf("\t%s = ", outputColor);
+ fsBuilder->appendTextureLookupAndModulate(inputColor,
samplers[0],
"coord");
- builder->fsCodeAppend(";\n");
+ fsBuilder->codeAppend(";\n");
}
}
desc.fContext = ctx;
desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info());
fAtlas = GrTextureStripAtlas::GetAtlas(desc);
- SkASSERT(NULL != fAtlas);
+ SkASSERT(fAtlas);
// We always filter the gradient table. Each table is one row of a texture, always y-clamp.
GrTextureParams params;
fRow = fAtlas->lockRow(bitmap);
if (-1 != fRow) {
- fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf *
- fAtlas->getVerticalScaleFactor();
+ fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf * fAtlas->getNormalizedTexelHeight();
fCoordTransform.reset(kCoordSet, matrix, fAtlas->getTexture());
fTextureAccess.reset(fAtlas->getTexture(), params);
} else {
- GrTexture* texture = GrLockAndRefCachedBitmapTexture(ctx, bitmap, ¶ms);
+ SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(ctx, bitmap, ¶ms));
fCoordTransform.reset(kCoordSet, matrix, texture);
fTextureAccess.reset(texture, params);
fYCoord = SK_ScalarHalf;
-
- // Unlock immediately, this is not great, but we don't have a way of
- // knowing when else to unlock it currently, so it may get purged from
- // the cache, but it'll still be ref'd until it's no longer being used.
- GrUnlockAndUnrefCachedBitmapTexture(texture);
}
this->addTextureAccess(&fTextureAccess);
}
}
}
-bool GrGradientEffect::onIsEqual(const GrEffect& effect) const {
- const GrGradientEffect& s = CastEffect<GrGradientEffect>(effect);
+bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const {
+ const GrGradientEffect& s = processor.cast<GrGradientEffect>();
if (this->fColorType == s.getColorType()){
}
}
- return fTextureAccess.getTexture() == s.fTextureAccess.getTexture() &&
- fTextureAccess.getParams().getTileModeX() ==
- s.fTextureAccess.getParams().getTileModeX() &&
- this->useAtlas() == s.useAtlas() &&
- fCoordTransform.getMatrix().cheapEqualTo(s.fCoordTransform.getMatrix());
+ SkASSERT(this->useAtlas() == s.useAtlas());
+ return true;
}
return false;
}
-void GrGradientEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
- if (fIsOpaque && (kA_GrColorComponentFlag & *validFlags) && 0xff == GrColorUnpackA(*color)) {
- *validFlags = kA_GrColorComponentFlag;
+void GrGradientEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
+ if (fIsOpaque) {
+ inout->mulByUnknownOpaqueColor();
} else {
- *validFlags = 0;
+ inout->mulByUnknownColor();
}
}
SkScalar stop = 0.f;
for (int i = 0; i < outColors; ++i) {
colors[i] = random->nextU();
- if (NULL != *stops) {
+ if (*stops) {
(*stops)[i] = stop;
stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - stop) : 1.f;
}