Delete legacy radial gradient impl

Raster pipeline FTW!

Change-Id: Ia2e600cf6c6e780f5a1519374c178197cf229776
Reviewed-on: https://skia-review.googlesource.com/29884
Commit-Queue: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
This commit is contained in:
Florin Malita 2017-08-02 11:03:44 -04:00 committed by Skia Commit-Bot
parent 5131678123
commit 5b6c7c6455
3 changed files with 3 additions and 181 deletions

View File

@ -91,6 +91,8 @@ bool SkShaderBase::asLuminanceColor(SkColor* colorPtr) const {
} }
SkShaderBase::Context* SkShaderBase::makeContext(const ContextRec& rec, SkArenaAlloc* alloc) const { SkShaderBase::Context* SkShaderBase::makeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
SkASSERT(!this->isRasterPipelineOnly());
return this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, nullptr) return this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, nullptr)
? this->onMakeContext(rec, alloc) ? this->onMakeContext(rec, alloc)
: nullptr; : nullptr;

View File

@ -7,19 +7,9 @@
#include "SkColorSpaceXformer.h" #include "SkColorSpaceXformer.h"
#include "SkRadialGradient.h" #include "SkRadialGradient.h"
#include "SkNx.h"
namespace { namespace {
// GCC doesn't like using static functions as template arguments. So force these to be non-static.
inline SkFixed mirror_tileproc_nonstatic(SkFixed x) {
return mirror_tileproc(x);
}
inline SkFixed repeat_tileproc_nonstatic(SkFixed x) {
return repeat_tileproc(x);
}
SkMatrix rad_to_unit_matrix(const SkPoint& center, SkScalar radius) { SkMatrix rad_to_unit_matrix(const SkPoint& center, SkScalar radius) {
SkScalar inv = SkScalarInvert(radius); SkScalar inv = SkScalarInvert(radius);
@ -29,7 +19,6 @@ SkMatrix rad_to_unit_matrix(const SkPoint& center, SkScalar radius) {
return matrix; return matrix;
} }
} // namespace } // namespace
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
@ -40,20 +29,6 @@ SkRadialGradient::SkRadialGradient(const SkPoint& center, SkScalar radius, const
, fRadius(radius) { , fRadius(radius) {
} }
SkShaderBase::Context* SkRadialGradient::onMakeContext(
const ContextRec& rec, SkArenaAlloc* alloc) const
{
return CheckedMakeContext<RadialGradientContext>(alloc, *this, rec);
}
SkRadialGradient::RadialGradientContext::RadialGradientContext(
const SkRadialGradient& shader, const ContextRec& rec)
: INHERITED(shader, rec) {
#ifndef SK_SUPPORT_LEGACY_RADIAL_GRADIENT
SkASSERT(shader.getTileMode() == SkShader::kClamp_TileMode);
#endif
}
SkShader::GradientType SkRadialGradient::asAGradient(GradientInfo* info) const { SkShader::GradientType SkRadialGradient::asAGradient(GradientInfo* info) const {
if (info) { if (info) {
commonAsAGradient(info); commonAsAGradient(info);
@ -81,142 +56,6 @@ void SkRadialGradient::flatten(SkWriteBuffer& buffer) const {
buffer.writeScalar(fRadius); buffer.writeScalar(fRadius);
} }
namespace {
inline bool radial_completely_pinned(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy) {
// fast, overly-conservative test: checks unit square instead of unit circle
bool xClamped = (fx >= 1 && dx >= 0) || (fx <= -1 && dx <= 0);
bool yClamped = (fy >= 1 && dy >= 0) || (fy <= -1 && dy <= 0);
return xClamped || yClamped;
}
typedef void (* RadialShadeProc)(SkScalar sfx, SkScalar sdx,
SkScalar sfy, SkScalar sdy,
SkPMColor* dstC, const SkPMColor* cache,
int count, int toggle);
static inline Sk4f fast_sqrt(const Sk4f& R) {
return R * R.rsqrt();
}
static inline Sk4f sum_squares(const Sk4f& a, const Sk4f& b) {
return a * a + b * b;
}
void shadeSpan_radial_clamp2(SkScalar sfx, SkScalar sdx, SkScalar sfy, SkScalar sdy,
SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
int count, int toggle) {
if (radial_completely_pinned(sfx, sdx, sfy, sdy)) {
unsigned fi = SkGradientShaderBase::kCache32Count - 1;
sk_memset32_dither(dstC,
cache[toggle + fi],
cache[next_dither_toggle(toggle) + fi],
count);
} else {
const Sk4f min(SK_ScalarNearlyZero);
const Sk4f max(255);
const float scale = 255;
sfx *= scale;
sfy *= scale;
sdx *= scale;
sdy *= scale;
const Sk4f fx4(sfx, sfx + sdx, sfx + 2*sdx, sfx + 3*sdx);
const Sk4f fy4(sfy, sfy + sdy, sfy + 2*sdy, sfy + 3*sdy);
const Sk4f dx4(sdx * 4);
const Sk4f dy4(sdy * 4);
Sk4f tmpxy = fx4 * dx4 + fy4 * dy4;
Sk4f tmpdxdy = sum_squares(dx4, dy4);
Sk4f R = Sk4f::Max(sum_squares(fx4, fy4), min);
Sk4f dR = tmpxy + tmpxy + tmpdxdy;
const Sk4f ddR = tmpdxdy + tmpdxdy;
for (int i = 0; i < (count >> 2); ++i) {
Sk4f dist = Sk4f::Min(fast_sqrt(R), max);
R = Sk4f::Max(R + dR, min);
dR = dR + ddR;
uint8_t fi[4];
SkNx_cast<uint8_t>(dist).store(fi);
for (int i = 0; i < 4; i++) {
*dstC++ = cache[toggle + fi[i]];
toggle = next_dither_toggle(toggle);
}
}
count &= 3;
if (count) {
Sk4f dist = Sk4f::Min(fast_sqrt(R), max);
uint8_t fi[4];
SkNx_cast<uint8_t>(dist).store(fi);
for (int i = 0; i < count; i++) {
*dstC++ = cache[toggle + fi[i]];
toggle = next_dither_toggle(toggle);
}
}
}
}
// Unrolling this loop doesn't seem to help (when float); we're stalling to
// get the results of the sqrt (?), and don't have enough extra registers to
// have many in flight.
template <SkFixed (*TileProc)(SkFixed)>
void shadeSpan_radial(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy,
SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
int count, int toggle) {
do {
const SkFixed dist = SkFloatToFixed(sk_float_sqrt(fx*fx + fy*fy));
const unsigned fi = TileProc(dist);
SkASSERT(fi <= 0xFFFF);
*dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache32Shift)];
toggle = next_dither_toggle(toggle);
fx += dx;
fy += dy;
} while (--count != 0);
}
void shadeSpan_radial_mirror(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy,
SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
int count, int toggle) {
shadeSpan_radial<mirror_tileproc_nonstatic>(fx, dx, fy, dy, dstC, cache, count, toggle);
}
void shadeSpan_radial_repeat(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy,
SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
int count, int toggle) {
shadeSpan_radial<repeat_tileproc_nonstatic>(fx, dx, fy, dy, dstC, cache, count, toggle);
}
} // namespace
void SkRadialGradient::RadialGradientContext::shadeSpan(int x, int y,
SkPMColor* SK_RESTRICT dstC, int count) {
SkASSERT(count > 0);
const SkRadialGradient& radialGradient = static_cast<const SkRadialGradient&>(fShader);
SkPoint srcPt;
SkMatrix::MapXYProc dstProc = fDstToIndexProc;
const SkPMColor* SK_RESTRICT cache = fCache->getCache32();
int toggle = init_dither_toggle(x, y);
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);
}
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
@ -369,14 +208,6 @@ sk_sp<SkShader> SkRadialGradient::onMakeColorSpace(SkColorSpaceXformer* xformer)
&this->getLocalMatrix()); &this->getLocalMatrix());
} }
bool SkRadialGradient::onIsRasterPipelineOnly() const {
#ifdef SK_SUPPORT_LEGACY_RADIAL_GRADIENT
return false;
#else
return true;
#endif
}
void SkRadialGradient::appendGradientStages(SkArenaAlloc*, SkRasterPipeline* p, void SkRadialGradient::appendGradientStages(SkArenaAlloc*, SkRasterPipeline* p,
SkRasterPipeline*) const { SkRasterPipeline*) const {
p->append(SkRasterPipeline::xy_to_radius); p->append(SkRasterPipeline::xy_to_radius);

View File

@ -14,16 +14,6 @@ class SkRadialGradient final : public SkGradientShaderBase {
public: public:
SkRadialGradient(const SkPoint& center, SkScalar radius, const Descriptor&); SkRadialGradient(const SkPoint& center, SkScalar radius, const Descriptor&);
class RadialGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
public:
RadialGradientContext(const SkRadialGradient&, const ContextRec&);
void shadeSpan(int x, int y, SkPMColor dstC[], int count) override;
private:
typedef SkGradientShaderBase::GradientShaderBaseContext INHERITED;
};
GradientType asAGradient(GradientInfo* info) const override; GradientType asAGradient(GradientInfo* info) const override;
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override; sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
@ -35,13 +25,12 @@ public:
protected: protected:
SkRadialGradient(SkReadBuffer& buffer); SkRadialGradient(SkReadBuffer& buffer);
void flatten(SkWriteBuffer& buffer) const override; void flatten(SkWriteBuffer& buffer) const override;
Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override; sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline, void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
SkRasterPipeline* postPipeline) const override; SkRasterPipeline* postPipeline) const override;
bool onIsRasterPipelineOnly() const override; bool onIsRasterPipelineOnly() const override { return true; }
private: private:
const SkPoint fCenter; const SkPoint fCenter;