| Index: src/effects/gradients/SkTwoPointConicalGradient.cpp
|
| diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp
|
| index 1e6a0d81268a28c30e630a3be37039510e761aea..b7aba827bbe77df4c5c8955b751facd4be7258e8 100644
|
| --- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
|
| +++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
|
| @@ -9,6 +9,18 @@
|
|
|
| #include "SkTwoPointConicalGradient_gpu.h"
|
|
|
| +struct TwoPtRadialContext {
|
| + const TwoPtRadial& fRec;
|
| + float fRelX, fRelY;
|
| + const float fIncX, fIncY;
|
| + float fB;
|
| + const float fDB;
|
| +
|
| + TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkScalar fy,
|
| + SkScalar dfx, SkScalar dfy);
|
| + SkFixed nextT();
|
| +};
|
| +
|
| static int valid_divide(float numer, float denom, float* ratio) {
|
| SkASSERT(ratio);
|
| if (0 == denom) {
|
| @@ -83,47 +95,48 @@ void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0,
|
| fFlipped = flipped;
|
| }
|
|
|
| -void TwoPtRadial::setup(SkScalar fx, SkScalar fy, SkScalar dfx, SkScalar dfy) {
|
| - fRelX = SkScalarToFloat(fx) - fCenterX;
|
| - fRelY = SkScalarToFloat(fy) - fCenterY;
|
| - fIncX = SkScalarToFloat(dfx);
|
| - fIncY = SkScalarToFloat(dfy);
|
| - fB = -2 * (fDCenterX * fRelX + fDCenterY * fRelY + fRDR);
|
| - fDB = -2 * (fDCenterX * fIncX + fDCenterY * fIncY);
|
| -}
|
| -
|
| -SkFixed TwoPtRadial::nextT() {
|
| +TwoPtRadialContext::TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkScalar fy,
|
| + SkScalar dfx, SkScalar dfy)
|
| + : fRec(rec)
|
| + , fRelX(SkScalarToFloat(fx) - rec.fCenterX)
|
| + , fRelY(SkScalarToFloat(fy) - rec.fCenterY)
|
| + , fIncX(SkScalarToFloat(dfx))
|
| + , fIncY(SkScalarToFloat(dfy))
|
| + , fB(-2 * (rec.fDCenterX * fRelX + rec.fDCenterY * fRelY + rec.fRDR))
|
| + , fDB(-2 * (rec.fDCenterX * fIncX + rec.fDCenterY * fIncY)) {}
|
| +
|
| +SkFixed TwoPtRadialContext::nextT() {
|
| float roots[2];
|
|
|
| - float C = sqr(fRelX) + sqr(fRelY) - fRadius2;
|
| - int countRoots = find_quad_roots(fA, fB, C, roots, fFlipped);
|
| + float C = sqr(fRelX) + sqr(fRelY) - fRec.fRadius2;
|
| + int countRoots = find_quad_roots(fRec.fA, fB, C, roots, fRec.fFlipped);
|
|
|
| fRelX += fIncX;
|
| fRelY += fIncY;
|
| fB += fDB;
|
|
|
| if (0 == countRoots) {
|
| - return kDontDrawT;
|
| + return TwoPtRadial::kDontDrawT;
|
| }
|
|
|
| // Prefer the bigger t value if both give a radius(t) > 0
|
| // find_quad_roots returns the values sorted, so we start with the last
|
| float t = roots[countRoots - 1];
|
| - float r = lerp(fRadius, fDRadius, t);
|
| + float r = lerp(fRec.fRadius, fRec.fDRadius, t);
|
| if (r <= 0) {
|
| t = roots[0]; // might be the same as roots[countRoots-1]
|
| - r = lerp(fRadius, fDRadius, t);
|
| + r = lerp(fRec.fRadius, fRec.fDRadius, t);
|
| if (r <= 0) {
|
| - return kDontDrawT;
|
| + return TwoPtRadial::kDontDrawT;
|
| }
|
| }
|
| return SkFloatToFixed(t);
|
| }
|
|
|
| -typedef void (*TwoPointConicalProc)(TwoPtRadial* rec, SkPMColor* dstC,
|
| +typedef void (*TwoPointConicalProc)(TwoPtRadialContext* rec, SkPMColor* dstC,
|
| const SkPMColor* cache, int toggle, int count);
|
|
|
| -static void twopoint_clamp(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
|
| +static void twopoint_clamp(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC,
|
| const SkPMColor* SK_RESTRICT cache, int toggle,
|
| int count) {
|
| for (; count > 0; --count) {
|
| @@ -140,7 +153,7 @@ static void twopoint_clamp(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
|
| }
|
| }
|
|
|
| -static void twopoint_repeat(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
|
| +static void twopoint_repeat(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC,
|
| const SkPMColor* SK_RESTRICT cache, int toggle,
|
| int count) {
|
| for (; count > 0; --count) {
|
| @@ -157,7 +170,7 @@ static void twopoint_repeat(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
|
| }
|
| }
|
|
|
| -static void twopoint_mirror(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
|
| +static void twopoint_mirror(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC,
|
| const SkPMColor* SK_RESTRICT cache, int toggle,
|
| int count) {
|
| for (; count > 0; --count) {
|
| @@ -203,8 +216,39 @@ bool SkTwoPointConicalGradient::isOpaque() const {
|
| return false;
|
| }
|
|
|
| -void SkTwoPointConicalGradient::shadeSpan(int x, int y, SkPMColor* dstCParam,
|
| - int count) {
|
| +size_t SkTwoPointConicalGradient::contextSize() const {
|
| + return sizeof(TwoPointConicalGradientContext);
|
| +}
|
| +
|
| +SkShader::Context* SkTwoPointConicalGradient::createContext(
|
| + const SkBitmap& device, const SkPaint& paint,
|
| + const SkMatrix& matrix, void* storage) const {
|
| + if (!this->validContext(device, paint, matrix)) {
|
| + return NULL;
|
| + }
|
| +
|
| + return SkNEW_PLACEMENT_ARGS(storage, TwoPointConicalGradientContext,
|
| + (*this, device, paint, matrix));
|
| +}
|
| +
|
| +SkTwoPointConicalGradient::TwoPointConicalGradientContext::TwoPointConicalGradientContext(
|
| + const SkTwoPointConicalGradient& shader, const SkBitmap& device,
|
| + const SkPaint& paint, const SkMatrix& matrix)
|
| + : INHERITED(shader, device, paint, matrix)
|
| +{
|
| + // we don't have a span16 proc
|
| + fFlags &= ~kHasSpan16_Flag;
|
| +
|
| + // in general, we might discard based on computed-radius, so clear
|
| + // this flag (todo: sometimes we can detect that we never discard...)
|
| + fFlags &= ~kOpaqueAlpha_Flag;
|
| +}
|
| +
|
| +void SkTwoPointConicalGradient::TwoPointConicalGradientContext::shadeSpan(
|
| + int x, int y, SkPMColor* dstCParam, int count) {
|
| + const SkTwoPointConicalGradient& twoPointConicalGradient =
|
| + static_cast<const SkTwoPointConicalGradient&>(fShader);
|
| +
|
| int toggle = init_dither_toggle(x, y);
|
|
|
| SkASSERT(count > 0);
|
| @@ -213,15 +257,15 @@ void SkTwoPointConicalGradient::shadeSpan(int x, int y, SkPMColor* dstCParam,
|
|
|
| SkMatrix::MapXYProc dstProc = fDstToIndexProc;
|
|
|
| - const SkPMColor* SK_RESTRICT cache = this->getCache32();
|
| + const SkPMColor* SK_RESTRICT cache = fCache->getCache32();
|
|
|
| TwoPointConicalProc shadeProc = twopoint_repeat;
|
| - if (SkShader::kClamp_TileMode == fTileMode) {
|
| + if (SkShader::kClamp_TileMode == twoPointConicalGradient.fTileMode) {
|
| shadeProc = twopoint_clamp;
|
| - } else if (SkShader::kMirror_TileMode == fTileMode) {
|
| + } else if (SkShader::kMirror_TileMode == twoPointConicalGradient.fTileMode) {
|
| shadeProc = twopoint_mirror;
|
| } else {
|
| - SkASSERT(SkShader::kRepeat_TileMode == fTileMode);
|
| + SkASSERT(SkShader::kRepeat_TileMode == twoPointConicalGradient.fTileMode);
|
| }
|
|
|
| if (fDstToIndexClass != kPerspective_MatrixClass) {
|
| @@ -242,16 +286,16 @@ void SkTwoPointConicalGradient::shadeSpan(int x, int y, SkPMColor* dstCParam,
|
| dy = fDstToIndex.getSkewY();
|
| }
|
|
|
| - fRec.setup(fx, fy, dx, dy);
|
| - (*shadeProc)(&fRec, dstC, cache, toggle, count);
|
| + TwoPtRadialContext rec(twoPointConicalGradient.fRec, fx, fy, dx, dy);
|
| + (*shadeProc)(&rec, dstC, cache, toggle, count);
|
| } else { // perspective case
|
| SkScalar dstX = SkIntToScalar(x) + SK_ScalarHalf;
|
| SkScalar dstY = SkIntToScalar(y) + SK_ScalarHalf;
|
| for (; count > 0; --count) {
|
| SkPoint srcPt;
|
| dstProc(fDstToIndex, dstX, dstY, &srcPt);
|
| - fRec.setup(srcPt.fX, srcPt.fY, 0, 0);
|
| - (*shadeProc)(&fRec, dstC, cache, toggle, 1);
|
| + TwoPtRadialContext rec(twoPointConicalGradient.fRec, srcPt.fX, srcPt.fY, 0, 0);
|
| + (*shadeProc)(&rec, dstC, cache, toggle, 1);
|
|
|
| dstX += SK_Scalar1;
|
| toggle = next_dither_toggle(toggle);
|
| @@ -260,23 +304,6 @@ void SkTwoPointConicalGradient::shadeSpan(int x, int y, SkPMColor* dstCParam,
|
| }
|
| }
|
|
|
| -bool SkTwoPointConicalGradient::setContext(const SkBitmap& device,
|
| - const SkPaint& paint,
|
| - const SkMatrix& matrix) {
|
| - if (!this->INHERITED::setContext(device, paint, matrix)) {
|
| - return false;
|
| - }
|
| -
|
| - // we don't have a span16 proc
|
| - fFlags &= ~kHasSpan16_Flag;
|
| -
|
| - // in general, we might discard based on computed-radius, so clear
|
| - // this flag (todo: sometimes we can detect that we never discard...)
|
| - fFlags &= ~kOpaqueAlpha_Flag;
|
| -
|
| - return true;
|
| -}
|
| -
|
| SkShader::BitmapType SkTwoPointConicalGradient::asABitmap(
|
| SkBitmap* bitmap, SkMatrix* matrix, SkShader::TileMode* xy) const {
|
| SkPoint diff = fCenter2 - fCenter1;
|
|
|