From 4d41b8f2fdae21a6ed16fca6242d53e7c08349d0 Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Wed, 12 Jul 2017 14:35:46 -0400 Subject: Remove dead gradient perspective code The cool bit here is that Sk4fLinearGradient is now always fast, and never calls the slow base-class impl. This means we can rip out Sk4fGradientBase::{mapTs, shadeSpan4f, etc}. Change-Id: Id3788bc810873b2a209f66efa4187c84b3397e2f Reviewed-on: https://skia-review.googlesource.com/22366 Reviewed-by: Herb Derby Reviewed-by: Mike Reed Commit-Queue: Florin Malita --- src/shaders/gradients/Sk4fGradientBase.cpp | 125 +-------------------------- src/shaders/gradients/Sk4fGradientBase.h | 15 +--- src/shaders/gradients/Sk4fLinearGradient.cpp | 60 +------------ src/shaders/gradients/Sk4fLinearGradient.h | 6 -- src/shaders/gradients/SkGradientShader.cpp | 5 +- src/shaders/gradients/SkLinearGradient.cpp | 54 ++++-------- src/shaders/gradients/SkRadialGradient.cpp | 45 +++------- src/shaders/gradients/SkSweepGradient.cpp | 30 ++----- 8 files changed, 38 insertions(+), 302 deletions(-) (limited to 'src/shaders/gradients') diff --git a/src/shaders/gradients/Sk4fGradientBase.cpp b/src/shaders/gradients/Sk4fGradientBase.cpp index f5d5e7155e..0d9e6d0836 100644 --- a/src/shaders/gradients/Sk4fGradientBase.cpp +++ b/src/shaders/gradients/Sk4fGradientBase.cpp @@ -293,8 +293,8 @@ GradientShaderBase4fContext::GradientShaderBase4fContext(const SkGradientShaderB const SkMatrix& inverse = this->getTotalInverse(); fDstToPos.setConcat(shader.fPtsToUnit, inverse); + SkASSERT(!fDstToPos.hasPerspective()); fDstToPosProc = fDstToPos.getMapXYProc(); - fDstToPosClass = static_cast(INHERITED::ComputeMatrixClass(fDstToPos)); if (shader.fColorsAreOpaque && this->getPaintAlpha() == SK_AlphaOPAQUE) { fFlags |= kOpaqueAlpha_Flag; @@ -315,126 +315,3 @@ GradientShaderBase4fContext::shadeSpan(int x, int y, SkPMColor dst[], int count) // This impl only shades to 4f. SkASSERT(false); } - -void SkGradientShaderBase:: -GradientShaderBase4fContext::shadeSpan4f(int x, int y, SkPM4f dst[], int count) { - if (fColorsArePremul) { - this->shadePremulSpan(x, y, dst, count); - } else { - this->shadePremulSpan(x, y, dst, count); - } -} - -template -void SkGradientShaderBase:: -GradientShaderBase4fContext::shadePremulSpan(int x, int y, SkPM4f dst[], int count) const { - const SkGradientShaderBase& shader = - static_cast(fShader); - - switch (shader.fTileMode) { - case kClamp_TileMode: - this->shadeSpanInternal(x, y, dst, count); - break; - case kRepeat_TileMode: - this->shadeSpanInternal(x, y, dst, count); - break; - case kMirror_TileMode: - this->shadeSpanInternal(x, y, dst, count); - break; - } -} - -template -void SkGradientShaderBase:: -GradientShaderBase4fContext::shadeSpanInternal(int x, int y, SkPM4f dst[], int count) const { - static const int kBufSize = 128; - SkScalar ts[kBufSize]; - TSampler sampler(*this); - - SkASSERT(count > 0); - do { - const int n = SkTMin(kBufSize, count); - this->mapTs(x, y, ts, n); - for (int i = 0; i < n; ++i) { - const Sk4f c = sampler.sample(ts[i]); - DstTraits::store(c, dst++); - } - x += n; - count -= n; - } while (count > 0); -} - -template -class SkGradientShaderBase::GradientShaderBase4fContext::TSampler { -public: - TSampler(const GradientShaderBase4fContext& ctx) - : fCtx(ctx) - , fInterval(nullptr) { - switch (tileMode) { - case kClamp_TileMode: - fLargestIntervalValue = SK_ScalarInfinity; - break; - case kRepeat_TileMode: - fLargestIntervalValue = nextafterf(1, 0); - break; - case kMirror_TileMode: - fLargestIntervalValue = nextafterf(2.0f, 0); - break; - } - } - - Sk4f sample(SkScalar t) { - const auto tiled_t = tileProc(t); - - if (!fInterval) { - // Very first sample => locate the initial interval. - // TODO: maybe do this in ctor to remove a branch? - fInterval = fCtx.fIntervals.find(tiled_t); - this->loadIntervalData(fInterval); - } else if (!fInterval->contains(tiled_t)) { - fInterval = fCtx.fIntervals.findNext(tiled_t, fInterval, t >= fPrevT); - this->loadIntervalData(fInterval); - } - - fPrevT = t; - return lerp(tiled_t); - } - -private: - SkScalar tileProc(SkScalar t) const { - switch (tileMode) { - case kClamp_TileMode: - // synthetic clamp-mode edge intervals allow for a free-floating t: - // [-inf..0)[0..1)[1..+inf) - return t; - case kRepeat_TileMode: - // t % 1 (intervals range: [0..1)) - // Due to the extra arithmetic, we must clamp to ensure the value remains less than 1. - return SkTMin(t - SkScalarFloorToScalar(t), fLargestIntervalValue); - case kMirror_TileMode: - // t % 2 (synthetic mirror intervals expand the range to [0..2) - // Due to the extra arithmetic, we must clamp to ensure the value remains less than 2. - return SkTMin(t - SkScalarFloorToScalar(t / 2) * 2, fLargestIntervalValue); - } - - SK_ABORT("Unhandled tile mode."); - return 0; - } - - Sk4f lerp(SkScalar t) { - SkASSERT(fInterval->contains(t)); - return fCb + fCg * t; - } - - void loadIntervalData(const Sk4fGradientInterval* i) { - fCb = DstTraits::load(i->fCb); - fCg = DstTraits::load(i->fCg); - } - - const GradientShaderBase4fContext& fCtx; - const Sk4fGradientInterval* fInterval; - SkScalar fPrevT; - SkScalar fLargestIntervalValue; - Sk4f fCb; - Sk4f fCg; -}; diff --git a/src/shaders/gradients/Sk4fGradientBase.h b/src/shaders/gradients/Sk4fGradientBase.h index acba642fd7..629b0650f6 100644 --- a/src/shaders/gradients/Sk4fGradientBase.h +++ b/src/shaders/gradients/Sk4fGradientBase.h @@ -60,18 +60,14 @@ public: uint32_t getFlags() const override { return fFlags; } - void shadeSpan(int x, int y, SkPMColor dst[], int count) override; - void shadeSpan4f(int x, int y, SkPM4f dst[], int count) override; + void shadeSpan(int x, int y, SkPMColor dst[], int count) final; bool isValid() const; protected: - virtual void mapTs(int x, int y, SkScalar ts[], int count) const = 0; - Sk4fGradientIntervalBuffer fIntervals; SkMatrix fDstToPos; SkMatrix::MapXYProc fDstToPosProc; - uint8_t fDstToPosClass; uint8_t fFlags; bool fColorsArePremul; @@ -80,15 +76,6 @@ private: void addMirrorIntervals(const SkGradientShaderBase&, const Sk4f& componentScale, bool reverse); - - template - class TSampler; - - template - void shadePremulSpan(int x, int y, SkPM4f[], int count) const; - - template - void shadeSpanInternal(int x, int y, SkPM4f[], int count) const; }; #endif // Sk4fGradientBase_DEFINED diff --git a/src/shaders/gradients/Sk4fLinearGradient.cpp b/src/shaders/gradients/Sk4fLinearGradient.cpp index aab1779c70..700b7fb13e 100644 --- a/src/shaders/gradients/Sk4fLinearGradient.cpp +++ b/src/shaders/gradients/Sk4fLinearGradient.cpp @@ -91,7 +91,7 @@ LinearGradient4fContext::LinearGradient4fContext(const SkLinearGradient& shader, : INHERITED(shader, rec) { // Our fast path expects interval points to be monotonically increasing in x. - const bool reverseIntervals = this->isFast() && std::signbit(fDstToPos.getScaleX()); + const bool reverseIntervals = std::signbit(fDstToPos.getScaleX()); fIntervals.init(shader, rec.fDstColorSpace, shader.fTileMode, fColorsArePremul, rec.fPaint->getAlpha() * (1.0f / 255), reverseIntervals); @@ -141,19 +141,8 @@ SkLinearGradient::LinearGradient4fContext::findInterval(SkScalar fx) const { } } -void SkLinearGradient:: -LinearGradient4fContext::shadeSpan(int x, int y, SkPMColor dst[], int count) { - // This impl only shades to 4f. - SkASSERT(false); -} - void SkLinearGradient:: LinearGradient4fContext::shadeSpan4f(int x, int y, SkPM4f dst[], int count) { - if (!this->isFast()) { - this->INHERITED::shadeSpan4f(x, y, dst, count); - return; - } - SkASSERT(count > 0); if (fColorsArePremul) { this->shadePremulSpan(x, y, dst, count); @@ -353,50 +342,3 @@ private: const SkScalar fDx; // 'dx' for consistency with other impls; actually dt/dx const bool fIsVertical; }; - -void SkLinearGradient:: -LinearGradient4fContext::mapTs(int x, int y, SkScalar ts[], int count) const { - SkASSERT(count > 0); - SkASSERT(fDstToPosClass != kLinear_MatrixClass); - - SkScalar sx = x + SK_ScalarHalf; - const SkScalar sy = y + SK_ScalarHalf; - SkPoint pt; - - if (fDstToPosClass != kPerspective_MatrixClass) { - // kLinear_MatrixClass, kFixedStepInX_MatrixClass => fixed dt per scanline - const SkScalar dtdx = fDstToPos.fixedStepInX(sy).x(); - fDstToPosProc(fDstToPos, sx, sy, &pt); - - const Sk4f dtdx4 = Sk4f(4 * dtdx); - Sk4f t4 = Sk4f(pt.x() + 0 * dtdx, - pt.x() + 1 * dtdx, - pt.x() + 2 * dtdx, - pt.x() + 3 * dtdx); - - while (count >= 4) { - t4.store(ts); - t4 = t4 + dtdx4; - ts += 4; - count -= 4; - } - - if (count & 2) { - *ts++ = t4[0]; - *ts++ = t4[1]; - t4 = SkNx_shuffle<2, 0, 1, 3>(t4); - } - - if (count & 1) { - *ts++ = t4[0]; - } - } else { - for (int i = 0; i < count; ++i) { - fDstToPosProc(fDstToPos, sx, sy, &pt); - // Perspective may yield NaN values. - // Short of a better idea, drop to 0. - ts[i] = SkScalarIsNaN(pt.x()) ? 0 : pt.x(); - sx += SK_Scalar1; - } - } -} diff --git a/src/shaders/gradients/Sk4fLinearGradient.h b/src/shaders/gradients/Sk4fLinearGradient.h index 96af4dfced..11606e1c80 100644 --- a/src/shaders/gradients/Sk4fLinearGradient.h +++ b/src/shaders/gradients/Sk4fLinearGradient.h @@ -16,12 +16,8 @@ LinearGradient4fContext final : public GradientShaderBase4fContext { public: LinearGradient4fContext(const SkLinearGradient&, const ContextRec&); - void shadeSpan(int x, int y, SkPMColor dst[], int count) override; void shadeSpan4f(int x, int y, SkPM4f dst[], int count) override; -protected: - void mapTs(int x, int y, SkScalar ts[], int count) const override; - private: using INHERITED = GradientShaderBase4fContext; @@ -36,8 +32,6 @@ private: const Sk4fGradientInterval* findInterval(SkScalar fx) const; - bool isFast() const { return fDstToPosClass == kLinear_MatrixClass; } - mutable const Sk4fGradientInterval* fCachedInterval; }; diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp index 0619ef0546..63770185b4 100644 --- a/src/shaders/gradients/SkGradientShader.cpp +++ b/src/shaders/gradients/SkGradientShader.cpp @@ -534,12 +534,9 @@ SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext( const SkMatrix& inverse = this->getTotalInverse(); fDstToIndex.setConcat(shader.fPtsToUnit, inverse); + SkASSERT(!fDstToIndex.hasPerspective()); fDstToIndexProc = fDstToIndex.getMapXYProc(); - fDstToIndexClass = (uint8_t)SkShaderBase::Context::ComputeMatrixClass(fDstToIndex); - - // TODO: remove all perspective-related gradient code - SkASSERT(fDstToIndexClass == kLinear_MatrixClass); // now convert our colors in to PMColors unsigned paintAlpha = this->getPaintAlpha(); diff --git a/src/shaders/gradients/SkLinearGradient.cpp b/src/shaders/gradients/SkLinearGradient.cpp index 08ce2db813..fc49d3430d 100644 --- a/src/shaders/gradients/SkLinearGradient.cpp +++ b/src/shaders/gradients/SkLinearGradient.cpp @@ -285,9 +285,7 @@ void SkLinearGradient::LinearGradientContext::shadeSpan(int x, int y, SkPMColor* SkASSERT(count > 0); const SkLinearGradient& linearGradient = static_cast(fShader); - if (SkShader::kClamp_TileMode == linearGradient.fTileMode && - kLinear_MatrixClass == fDstToIndexClass) - { + if (SkShader::kClamp_TileMode == linearGradient.fTileMode) { this->shade4_clamp(x, y, dstC, count); return; } @@ -298,43 +296,22 @@ void SkLinearGradient::LinearGradientContext::shadeSpan(int x, int y, SkPMColor* const SkPMColor* SK_RESTRICT cache = fCache->getCache32(); int toggle = init_dither_toggle(x, y); - if (fDstToIndexClass != kPerspective_MatrixClass) { - dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - SkGradFixed dx, fx = SkScalarPinToGradFixed(srcPt.fX); - - if (fDstToIndexClass == kFixedStepInX_MatrixClass) { - const auto step = fDstToIndex.fixedStepInX(SkIntToScalar(y)); - // todo: do we need a real/high-precision value for dx here? - dx = SkScalarPinToGradFixed(step.fX); - } else { - SkASSERT(fDstToIndexClass == kLinear_MatrixClass); - dx = SkScalarPinToGradFixed(fDstToIndex.getScaleX()); - } - - LinearShadeProc shadeProc = shadeSpan_linear_repeat; - if (0 == dx) { - shadeProc = shadeSpan_linear_vertical_lerp; - } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) { - shadeProc = shadeSpan_linear_clamp; - } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) { - shadeProc = shadeSpan_linear_mirror; - } else { - SkASSERT(SkShader::kRepeat_TileMode == linearGradient.fTileMode); - } - (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count); + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); + SkGradFixed fx = SkScalarPinToGradFixed(srcPt.fX), + dx = SkScalarPinToGradFixed(fDstToIndex.getScaleX()); + + LinearShadeProc shadeProc = shadeSpan_linear_repeat; + if (0 == dx) { + shadeProc = shadeSpan_linear_vertical_lerp; + } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) { + shadeProc = shadeSpan_linear_clamp; + } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) { + shadeProc = shadeSpan_linear_mirror; } else { - SkScalar dstX = SkIntToScalar(x); - SkScalar dstY = SkIntToScalar(y); - do { - dstProc(fDstToIndex, dstX, dstY, &srcPt); - unsigned fi = proc(SkScalarToFixed(srcPt.fX)); - SkASSERT(fi <= 0xFFFF); - *dstC++ = cache[toggle + (fi >> kCache32Shift)]; - toggle = next_dither_toggle(toggle); - dstX += SK_Scalar1; - } while (--count != 0); + SkASSERT(SkShader::kRepeat_TileMode == linearGradient.fTileMode); } + (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count); } SkShader::GradientType SkLinearGradient::asAGradient(GradientInfo* info) const { @@ -756,7 +733,6 @@ void SkLinearGradient::LinearGradientContext::shade4_dx_clamp(SkPMColor dstC[], void SkLinearGradient::LinearGradientContext::shade4_clamp(int x, int y, SkPMColor dstC[], int count) { SkASSERT(count > 0); - SkASSERT(kLinear_MatrixClass == fDstToIndexClass); SkPoint srcPt; fDstToIndexProc(fDstToIndex, x + SK_ScalarHalf, y + SK_ScalarHalf, &srcPt); diff --git a/src/shaders/gradients/SkRadialGradient.cpp b/src/shaders/gradients/SkRadialGradient.cpp index 06135e8e01..0a6a940b18 100644 --- a/src/shaders/gradients/SkRadialGradient.cpp +++ b/src/shaders/gradients/SkRadialGradient.cpp @@ -194,44 +194,23 @@ void SkRadialGradient::RadialGradientContext::shadeSpan(int x, int y, SkPoint srcPt; SkMatrix::MapXYProc dstProc = fDstToIndexProc; - TileProc proc = radialGradient.fTileProc; const SkPMColor* SK_RESTRICT cache = fCache->getCache32(); int toggle = init_dither_toggle(x, y); - if (fDstToIndexClass != kPerspective_MatrixClass) { - dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - SkScalar sdx = fDstToIndex.getScaleX(); - SkScalar sdy = fDstToIndex.getSkewY(); - - if (fDstToIndexClass == kFixedStepInX_MatrixClass) { - const auto step = fDstToIndex.fixedStepInX(SkIntToScalar(y)); - sdx = step.fX; - sdy = step.fY; - } else { - SkASSERT(fDstToIndexClass == kLinear_MatrixClass); - } + dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); + SkScalar sdx = fDstToIndex.getScaleX(); + SkScalar sdy = fDstToIndex.getSkewY(); - RadialShadeProc shadeProc = shadeSpan_radial_repeat; - if (SkShader::kClamp_TileMode == radialGradient.fTileMode) { - shadeProc = shadeSpan_radial_clamp2; - } else if (SkShader::kMirror_TileMode == radialGradient.fTileMode) { - shadeProc = shadeSpan_radial_mirror; - } else { - SkASSERT(SkShader::kRepeat_TileMode == radialGradient.fTileMode); - } - (*shadeProc)(srcPt.fX, sdx, srcPt.fY, sdy, dstC, cache, count, toggle); - } else { // perspective case - SkScalar dstX = SkIntToScalar(x); - SkScalar dstY = SkIntToScalar(y); - do { - dstProc(fDstToIndex, dstX, dstY, &srcPt); - unsigned fi = proc(SkScalarToFixed(srcPt.length())); - SkASSERT(fi <= 0xFFFF); - *dstC++ = cache[fi >> SkGradientShaderBase::kCache32Shift]; - dstX += SK_Scalar1; - } while (--count != 0); + RadialShadeProc shadeProc = shadeSpan_radial_repeat; + if (SkShader::kClamp_TileMode == radialGradient.fTileMode) { + shadeProc = shadeSpan_radial_clamp2; + } else if (SkShader::kMirror_TileMode == radialGradient.fTileMode) { + shadeProc = shadeSpan_radial_mirror; + } else { + SkASSERT(SkShader::kRepeat_TileMode == radialGradient.fTileMode); } + (*shadeProc)(srcPt.fX, sdx, srcPt.fY, sdy, dstC, cache, count, toggle); } ///////////////////////////////////////////////////////////////////// diff --git a/src/shaders/gradients/SkSweepGradient.cpp b/src/shaders/gradients/SkSweepGradient.cpp index 61ddf5c39b..e6bc42c20e 100644 --- a/src/shaders/gradients/SkSweepGradient.cpp +++ b/src/shaders/gradients/SkSweepGradient.cpp @@ -98,21 +98,13 @@ void SkSweepGradient::SweepGradientContext::shadeSpan(int x, int y, SkPMColor* S int toggle = init_dither_toggle(x, y); SkPoint srcPt; - if (fDstToIndexClass != kPerspective_MatrixClass) { - proc(matrix, SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - SkScalar dx, fx = srcPt.fX; - SkScalar dy, fy = srcPt.fY; - - if (fDstToIndexClass == kFixedStepInX_MatrixClass) { - const auto step = matrix.fixedStepInX(SkIntToScalar(y) + SK_ScalarHalf); - dx = step.fX; - dy = step.fY; - } else { - SkASSERT(fDstToIndexClass == kLinear_MatrixClass); - dx = matrix.getScaleX(); - dy = matrix.getSkewY(); - } + proc(matrix, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); + SkScalar fx = srcPt.fX, + fy = srcPt.fY; + + SkScalar dx = matrix.getScaleX(), + dy = matrix.getSkewY(); for (; count > 0; --count) { *dstC++ = cache[toggle + SkATan2_255(fy, fx)]; @@ -120,14 +112,6 @@ void SkSweepGradient::SweepGradientContext::shadeSpan(int x, int y, SkPMColor* S fy += dy; toggle = next_dither_toggle(toggle); } - } else { // perspective case - for (int stop = x + count; x < stop; x++) { - proc(matrix, SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - *dstC++ = cache[toggle + SkATan2_255(srcPt.fY, srcPt.fX)]; - toggle = next_dither_toggle(toggle); - } - } } ///////////////////////////////////////////////////////////////////// -- cgit v1.2.3