// V21: add pushCull, popCull
// V22: SK_PICT_FACTORY_TAG's size is now the chunk size in bytes
// V23: SkPaint::FilterLevel became a real enum
- // V24: SkTwoPointConicalGradient now has fFlipped flag for gradient flipping
// Note: If the picture version needs to be increased then please follow the
// steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw
// Only SKPs within the min/current picture version range (inclusive) can be read.
static const uint32_t MIN_PICTURE_VERSION = 19;
- static const uint32_t CURRENT_PICTURE_VERSION = 24;
+ static const uint32_t CURRENT_PICTURE_VERSION = 23;
mutable uint32_t fUniqueID;
buffer.writeMatrix(fPtsToUnit);
}
-// V23_COMPATIBILITY_CODE
-void SkGradientShaderBase::flipGradientColors() {
- SkAutoSTArray<8, SkColor> colorsTemp(fColorCount);
- for (int i = 0; i < fColorCount; ++i) {
- int offset = fColorCount - i - 1;
- colorsTemp[i] = fOrigColors[offset];
- }
- if (fColorCount > 2) {
- SkAutoSTArray<8, Rec> recsTemp(fColorCount);
- for (int i = 0; i < fColorCount; ++i) {
- int offset = fColorCount - i - 1;
- recsTemp[i].fPos = 1 - fRecs[offset].fPos;
- recsTemp[i].fScale = fRecs[offset].fScale;
- }
- memcpy(fRecs, recsTemp.get(), fColorCount * sizeof(Rec));
- }
- memcpy(fOrigColors, colorsTemp.get(), fColorCount * sizeof(SkColor));
-}
-
bool SkGradientShaderBase::isOpaque() const {
return fColorsAreOpaque;
}
if (start == end && startRadius == endRadius) {
return SkNEW(SkEmptyShader);
}
-
EXPAND_1_COLOR(colorCount);
- bool flipGradient = startRadius > endRadius;
-
SkGradientShaderBase::Descriptor desc;
-
- if (!flipGradient) {
- desc_init(&desc, colors, pos, colorCount, mode, mapper, flags);
- return SkNEW_ARGS(SkTwoPointConicalGradient,
- (start, startRadius, end, endRadius, flipGradient, desc));
- } else {
- SkAutoSTArray<8, SkColor> colorsNew(colorCount);
- SkAutoSTArray<8, SkScalar> posNew(colorCount);
- for (int i = 0; i < colorCount; ++i) {
- colorsNew[i] = colors[colorCount - i - 1];
- }
-
- if (pos) {
- for (int i = 0; i < colorCount; ++i) {
- posNew[i] = 1 - pos[colorCount - i - 1];
- }
- desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, mapper, flags);
- } else {
- desc_init(&desc, colorsNew.get(), NULL, colorCount, mode, mapper, flags);
- }
-
- return SkNEW_ARGS(SkTwoPointConicalGradient,
- (end, endRadius, start, startRadius, flipGradient, desc));
- }
+ desc_init(&desc, colors, pos, colorCount, mode, mapper, flags);
+ return SkNEW_ARGS(SkTwoPointConicalGradient,
+ (start, startRadius, end, endRadius, desc));
}
SkShader* SkGradientShader::CreateSweep(SkScalar cx, SkScalar cy,
void commonAsAGradient(GradientInfo*) const;
- // V23_COMPATIBILITY_CODE
- // Used for 2-pt conical gradients since we sort start/end cirlces by radius
- // Assumes space has already been allocated for fOrigColors
- void flipGradientColors();
-
private:
enum {
kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
// Return the number of distinct real roots, and write them into roots[] in
// ascending order
-static int find_quad_roots(float A, float B, float C, float roots[2], bool descendingOrder = false) {
+static int find_quad_roots(float A, float B, float C, float roots[2]) {
SkASSERT(roots);
if (A == 0) {
float r1 = C / Q;
roots[0] = r0 < r1 ? r0 : r1;
roots[1] = r0 > r1 ? r0 : r1;
- if (descendingOrder) {
- SkTSwap(roots[0], roots[1]);
- }
return 2;
}
static float sqr(float x) { return x * x; }
void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0,
- const SkPoint& center1, SkScalar rad1,
- bool flipped) {
+ const SkPoint& center1, SkScalar rad1) {
fCenterX = SkScalarToFloat(center0.fX);
fCenterY = SkScalarToFloat(center0.fY);
fDCenterX = SkScalarToFloat(center1.fX) - fCenterX;
fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius);
fRadius2 = sqr(fRadius);
fRDR = fRadius * fDRadius;
-
- fFlipped = flipped;
}
TwoPtRadialContext::TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkScalar fy,
float roots[2];
float C = sqr(fRelX) + sqr(fRelY) - fRec.fRadius2;
- int countRoots = find_quad_roots(fRec.fA, fB, C, roots, fRec.fFlipped);
+ int countRoots = find_quad_roots(fRec.fA, fB, C, roots);
fRelX += fIncX;
fRelY += fIncY;
}
void SkTwoPointConicalGradient::init() {
- fRec.init(fCenter1, fRadius1, fCenter2, fRadius2, fFlippedGrad);
+ fRec.init(fCenter1, fRadius1, fCenter2, fRadius2);
fPtsToUnit.reset();
}
SkTwoPointConicalGradient::SkTwoPointConicalGradient(
const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
- bool flippedGrad, const Descriptor& desc)
+ const Descriptor& desc)
: SkGradientShaderBase(desc),
fCenter1(start),
fCenter2(end),
fRadius1(startRadius),
- fRadius2(endRadius),
- fFlippedGrad(flippedGrad) {
+ fRadius2(endRadius) {
// this is degenerate, and should be caught by our caller
SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2);
this->init();
fCenter2(buffer.readPoint()),
fRadius1(buffer.readScalar()),
fRadius2(buffer.readScalar()) {
- if (buffer.pictureVersion() >= 24 || 0 == buffer.pictureVersion()) {
- fFlippedGrad = buffer.readBool();
- } else {
- // V23_COMPATIBILITY_CODE
- // Sort gradient by radius size for old pictures
- if (fRadius2 < fRadius1) {
- SkTSwap(fCenter1, fCenter2);
- SkTSwap(fRadius1, fRadius2);
- this->flipGradientColors();
- fFlippedGrad = true;
- } else {
- fFlippedGrad = false;
- }
- }
this->init();
};
buffer.writePoint(fCenter2);
buffer.writeScalar(fRadius1);
buffer.writeScalar(fRadius2);
- buffer.writeBool(fFlippedGrad);
}
#if SK_SUPPORT_GPU
float fA;
float fRadius2;
float fRDR;
- bool fFlipped;
void init(const SkPoint& center0, SkScalar rad0,
- const SkPoint& center1, SkScalar rad1,
- bool flipped);
+ const SkPoint& center1, SkScalar rad1);
static bool DontDrawT(SkFixed t) {
return kDontDrawT == (uint32_t)t;
public:
SkTwoPointConicalGradient(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
- bool flippedGrad, const Descriptor&);
+ const Descriptor&);
virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
const SkPoint& getStartCenter() const { return fCenter1; }
const SkPoint& getEndCenter() const { return fCenter2; }
SkScalar getEndRadius() const { return fRadius2; }
- bool isFlippedGrad() const { return fFlippedGrad; }
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTwoPointConicalGradient)
virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
private:
- SkPoint fCenter1;
- SkPoint fCenter2;
- SkScalar fRadius1;
- SkScalar fRadius2;
- bool fFlippedGrad;
+ const SkPoint fCenter1;
+ const SkPoint fCenter2;
+ const SkScalar fRadius1;
+ const SkScalar fRadius2;
typedef SkGradientShaderBase INHERITED;
};
// The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
bool isDegenerate() const { return SkScalarAbs(fDiffRadius) == SkScalarAbs(fCenterX1); }
- bool isFlipped() const { return fIsFlipped; }
SkScalar center() const { return fCenterX1; }
SkScalar diffRadius() const { return fDiffRadius; }
SkScalar radius() const { return fRadius0; }
return (INHERITED::onIsEqual(sBase) &&
this->fCenterX1 == s.fCenterX1 &&
this->fRadius0 == s.fRadius0 &&
- this->fDiffRadius == s.fDiffRadius &&
- this->fIsFlipped == s.fIsFlipped);
+ this->fDiffRadius == s.fDiffRadius);
}
Default2PtConicalEffect(GrContext* ctx,
: INHERITED(ctx, shader, matrix, tm),
fCenterX1(shader.getCenterX1()),
fRadius0(shader.getStartRadius()),
- fDiffRadius(shader.getDiffRadius()),
- fIsFlipped(shader.isFlippedGrad()) {
+ fDiffRadius(shader.getDiffRadius()) {
// We pass the linear part of the quadratic as a varying.
// float b = -2.0 * (fCenterX1 * x + fRadius0 * fDiffRadius * z)
fBTransform = this->getCoordTransform();
SkScalar fCenterX1;
SkScalar fRadius0;
SkScalar fDiffRadius;
- bool fIsFlipped;
// @}
const char* fFSVaryingName;
bool fIsDegenerate;
- bool fIsFlipped;
// @{
/// Values last uploaded as uniforms
const Default2PtConicalEffect& data = drawEffect.castEffect<Default2PtConicalEffect>();
fIsDegenerate = data.isDegenerate();
- fIsFlipped = data.isFlipped();
}
void GLDefault2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
// Note: If there are two roots that both generate radius(t) > 0, the
// Canvas spec says to choose the larger t.
- // so we'll look at the larger one first (or smaller if flipped):
- if (!fIsFlipped) {
- builder->fsCodeAppendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str(),
- r0Name.c_str(), r1Name.c_str());
- } else {
- builder->fsCodeAppendf("\t\tfloat %s = min(%s, %s);\n", tName.c_str(),
- r0Name.c_str(), r1Name.c_str());
- }
+ // so we'll look at the larger one first:
+ builder->fsCodeAppendf("\t\tfloat %s = max(%s, %s);\n", tName.c_str(),
+ r0Name.c_str(), r1Name.c_str());
// if r(t) > 0, then we're done; t will be our x coordinate
builder->fsCodeAppendf("\t\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
// otherwise, if r(t) for the larger root was <= 0, try the other root
builder->fsCodeAppend("\t\t} else {\n");
- if (!fIsFlipped) {
- builder->fsCodeAppendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(),
- r0Name.c_str(), r1Name.c_str());
- } else {
- builder->fsCodeAppendf("\t\t\t%s = max(%s, %s);\n", tName.c_str(),
- r0Name.c_str(), r1Name.c_str());
- }
+ builder->fsCodeAppendf("\t\t\t%s = min(%s, %s);\n", tName.c_str(),
+ r0Name.c_str(), r1Name.c_str());
// if r(t) > 0 for the smaller root, then t will be our x coordinate
builder->fsCodeAppendf("\t\t\tif (%s * %s + %s > 0.0) {\n",
INHERITED::setData(uman, drawEffect);
const Default2PtConicalEffect& data = drawEffect.castEffect<Default2PtConicalEffect>();
SkASSERT(data.isDegenerate() == fIsDegenerate);
- SkASSERT(data.isFlipped() == fIsFlipped);
SkScalar centerX1 = data.center();
SkScalar radius0 = data.radius();
SkScalar diffRadius = data.diffRadius();
const GrGLCaps&) {
enum {
kIsDegenerate = 1 << kBaseKeyBitCnt,
- kIsFlipped = 1 << (kBaseKeyBitCnt + 1),
};
EffectKey key = GenBaseGradientKey(drawEffect);
if (drawEffect.castEffect<Default2PtConicalEffect>().isDegenerate()) {
key |= kIsDegenerate;
}
- if (drawEffect.castEffect<Default2PtConicalEffect>().isFlipped()) {
- key |= kIsFlipped;
- }
return key;
}