diff options
author | 2017-05-30 16:39:47 -0400 | |
---|---|---|
committer | 2017-05-30 21:01:46 +0000 | |
commit | 5edba45dca995baed5e66dfaaa7859132e716314 (patch) | |
tree | 0333422088e6ed781db5c6e2cf4ed330b69a0957 /src/effects/gradients/SkRadialGradient.cpp | |
parent | 64790a3714467300848971aa153aca8cea91cf7b (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.cpp | 405 |
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 |