aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/gradients/SkRadialGradient.cpp
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2017-05-30 16:39:47 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-30 21:01:46 +0000
commit5edba45dca995baed5e66dfaaa7859132e716314 (patch)
tree0333422088e6ed781db5c6e2cf4ed330b69a0957 /src/effects/gradients/SkRadialGradient.cpp
parent64790a3714467300848971aa153aca8cea91cf7b (diff)
[Reland] Relocate shaders to own dir
Consolidate all shader impls under src/shaders/. (reland of https://skia-review.googlesource.com/c/17927/) Change-Id: I7918bdc1aafe842ed194412ba95b9ae53a2ec1d7 Reviewed-on: https://skia-review.googlesource.com/18146 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'src/effects/gradients/SkRadialGradient.cpp')
-rw-r--r--src/effects/gradients/SkRadialGradient.cpp405
1 files changed, 0 insertions, 405 deletions
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
deleted file mode 100644
index d49b3dd8e1..0000000000
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkColorSpaceXformer.h"
-#include "SkRadialGradient.h"
-#include "SkNx.h"
-
-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) {
- SkScalar inv = SkScalarInvert(radius);
-
- SkMatrix matrix;
- matrix.setTranslate(-center.fX, -center.fY);
- matrix.postScale(inv, inv);
- return matrix;
-}
-
-
-} // namespace
-
-/////////////////////////////////////////////////////////////////////
-
-SkRadialGradient::SkRadialGradient(const SkPoint& center, SkScalar radius, const Descriptor& desc)
- : SkGradientShaderBase(desc, rad_to_unit_matrix(center, radius))
- , fCenter(center)
- , 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) {}
-
-SkShader::GradientType SkRadialGradient::asAGradient(GradientInfo* info) const {
- if (info) {
- commonAsAGradient(info);
- info->fPoint[0] = fCenter;
- info->fRadius[0] = fRadius;
- }
- return kRadial_GradientType;
-}
-
-sk_sp<SkFlattenable> SkRadialGradient::CreateProc(SkReadBuffer& buffer) {
- DescriptorScope desc;
- if (!desc.unflatten(buffer)) {
- return nullptr;
- }
- const SkPoint center = buffer.readPoint();
- const SkScalar radius = buffer.readScalar();
- return SkGradientShader::MakeRadial(center, radius, desc.fColors, std::move(desc.fColorSpace),
- desc.fPos, desc.fCount, desc.fTileMode, desc.fGradFlags,
- desc.fLocalMatrix);
-}
-
-void SkRadialGradient::flatten(SkWriteBuffer& buffer) const {
- this->INHERITED::flatten(buffer);
- buffer.writePoint(fCenter);
- 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;
- 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);
- }
-
- 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);
- }
-}
-
-/////////////////////////////////////////////////////////////////////
-
-#if SK_SUPPORT_GPU
-
-#include "SkGr.h"
-#include "GrShaderCaps.h"
-#include "glsl/GrGLSLFragmentShaderBuilder.h"
-
-class GrRadialGradient : public GrGradientEffect {
-public:
- class GLSLRadialProcessor;
-
- static sk_sp<GrFragmentProcessor> Make(const CreateArgs& args) {
- return sk_sp<GrFragmentProcessor>(new GrRadialGradient(args));
- }
-
- ~GrRadialGradient() override {}
-
- const char* name() const override { return "Radial Gradient"; }
-
-private:
- GrRadialGradient(const CreateArgs& args) : INHERITED(args, args.fShader->colorsAreOpaque()) {
- this->initClassID<GrRadialGradient>();
- }
-
- GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
-
- virtual void onGetGLSLProcessorKey(const GrShaderCaps& caps,
- GrProcessorKeyBuilder* b) const override;
-
- GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
-
- typedef GrGradientEffect INHERITED;
-};
-
-/////////////////////////////////////////////////////////////////////
-
-class GrRadialGradient::GLSLRadialProcessor : public GrGradientEffect::GLSLProcessor {
-public:
- GLSLRadialProcessor(const GrProcessor&) {}
- ~GLSLRadialProcessor() override {}
-
- virtual void emitCode(EmitArgs&) override;
-
- static void GenKey(const GrProcessor& processor, const GrShaderCaps&, GrProcessorKeyBuilder* b) {
- b->add32(GenBaseGradientKey(processor));
- }
-
-private:
- typedef GrGradientEffect::GLSLProcessor INHERITED;
-
-};
-
-/////////////////////////////////////////////////////////////////////
-
-GrGLSLFragmentProcessor* GrRadialGradient::onCreateGLSLInstance() const {
- return new GrRadialGradient::GLSLRadialProcessor(*this);
-}
-
-void GrRadialGradient::onGetGLSLProcessorKey(const GrShaderCaps& caps,
- GrProcessorKeyBuilder* b) const {
- GrRadialGradient::GLSLRadialProcessor::GenKey(*this, caps, b);
-}
-
-/////////////////////////////////////////////////////////////////////
-
-GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRadialGradient);
-
-#if GR_TEST_UTILS
-sk_sp<GrFragmentProcessor> GrRadialGradient::TestCreate(GrProcessorTestData* d) {
- sk_sp<SkShader> shader;
- do {
- RandomGradientParams params(d->fRandom);
- SkPoint center = {d->fRandom->nextUScalar1(), d->fRandom->nextUScalar1()};
- SkScalar radius = d->fRandom->nextUScalar1();
- shader = params.fUseColors4f
- ? SkGradientShader::MakeRadial(center, radius, params.fColors4f,
- params.fColorSpace, params.fStops,
- params.fColorCount, params.fTileMode)
- : SkGradientShader::MakeRadial(center, radius, params.fColors,
- params.fStops, params.fColorCount,
- params.fTileMode);
- } while (!shader);
- GrTest::TestAsFPArgs asFPArgs(d);
- sk_sp<GrFragmentProcessor> fp = as_SB(shader)->asFragmentProcessor(asFPArgs.args());
- GrAlwaysAssert(fp);
- return fp;
-}
-#endif
-
-/////////////////////////////////////////////////////////////////////
-
-void GrRadialGradient::GLSLRadialProcessor::emitCode(EmitArgs& args) {
- const GrRadialGradient& ge = args.fFp.cast<GrRadialGradient>();
- this->emitUniforms(args.fUniformHandler, ge);
- SkString t("length(");
- t.append(args.fFragBuilder->ensureCoords2D(args.fTransformedCoords[0]));
- t.append(")");
- this->emitColor(args.fFragBuilder,
- args.fUniformHandler,
- args.fShaderCaps,
- ge, t.c_str(),
- args.fOutputColor,
- args.fInputColor,
- args.fTexSamplers);
-}
-
-/////////////////////////////////////////////////////////////////////
-
-sk_sp<GrFragmentProcessor> SkRadialGradient::asFragmentProcessor(const AsFPArgs& args) const {
- SkASSERT(args.fContext);
-
- SkMatrix matrix;
- if (!this->getLocalMatrix().invert(&matrix)) {
- return nullptr;
- }
- if (args.fLocalMatrix) {
- SkMatrix inv;
- if (!args.fLocalMatrix->invert(&inv)) {
- return nullptr;
- }
- matrix.postConcat(inv);
- }
- matrix.postConcat(fPtsToUnit);
- sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(fColorSpace.get(),
- args.fDstColorSpace);
- sk_sp<GrFragmentProcessor> inner(GrRadialGradient::Make(
- GrGradientEffect::CreateArgs(args.fContext, this, &matrix, fTileMode,
- std::move(colorSpaceXform), SkToBool(args.fDstColorSpace))));
- return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner));
-}
-
-#endif
-
-sk_sp<SkShader> SkRadialGradient::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
- SkSTArray<8, SkColor> xformedColors(fColorCount);
- xformer->apply(xformedColors.begin(), fOrigColors, fColorCount);
- return SkGradientShader::MakeRadial(fCenter, fRadius, xformedColors.begin(), fOrigPos,
- fColorCount, fTileMode, fGradFlags,
- &this->getLocalMatrix());
-}
-
-bool SkRadialGradient::adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
- SkMatrix* matrix,
- SkRasterPipeline* p) const {
- matrix->postTranslate(-fCenter.fX, -fCenter.fY);
- matrix->postScale(1/fRadius, 1/fRadius);
-
- p->append(SkRasterPipeline::xy_to_radius);
- return true;
-}
-
-#ifndef SK_IGNORE_TO_STRING
-void SkRadialGradient::toString(SkString* str) const {
- str->append("SkRadialGradient: (");
-
- str->append("center: (");
- str->appendScalar(fCenter.fX);
- str->append(", ");
- str->appendScalar(fCenter.fY);
- str->append(") radius: ");
- str->appendScalar(fRadius);
- str->append(" ");
-
- this->INHERITED::toString(str);
-
- str->append(")");
-}
-#endif