diff options
author | Robert Phillips <robertphillips@google.com> | 2016-10-20 13:20:45 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-10-21 13:05:39 +0000 |
commit | 54cfe411c6d77dd2e95e7a1b041cd9fc6b6c2e78 (patch) | |
tree | be1377cec81757ba70f793e2c05159f450bcdb01 /src/effects | |
parent | 8f457591e6a21c240fd2fca56a97281b556ce796 (diff) |
Remove SkRRectsGaussianEdgeShader
This class is no longer used.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3734
Change-Id: I16634760df6b31c7e97c893b7e2b982cd7b1d1fd
Reviewed-on: https://skia-review.googlesource.com/3734
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/effects')
-rw-r--r-- | src/effects/SkRRectsGaussianEdgeShader.cpp | 483 |
1 files changed, 0 insertions, 483 deletions
diff --git a/src/effects/SkRRectsGaussianEdgeShader.cpp b/src/effects/SkRRectsGaussianEdgeShader.cpp deleted file mode 100644 index 3b1d5650c3..0000000000 --- a/src/effects/SkRRectsGaussianEdgeShader.cpp +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkRRectsGaussianEdgeShader.h" -#include "SkReadBuffer.h" -#include "SkWriteBuffer.h" - - /** \class SkRRectsGaussianEdgeShaderImpl - * This shader applies a gaussian edge to the intersection of two round rects. - * The round rects must have the same radii at each corner and the x&y radii - * must also be equal. - */ -class SkRRectsGaussianEdgeShaderImpl : public SkShader { -public: - SkRRectsGaussianEdgeShaderImpl(const SkRRect& first, const SkRRect& second, SkScalar radius) - : fFirst(first) - , fSecond(second) - , fRadius(radius) { - } - - bool isOpaque() const override { return false; } - -#if SK_SUPPORT_GPU - sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override; -#endif - - class GaussianEdgeShaderContext : public SkShader::Context { - public: - GaussianEdgeShaderContext(const SkRRectsGaussianEdgeShaderImpl&, const ContextRec&); - - ~GaussianEdgeShaderContext() override { } - - void shadeSpan(int x, int y, SkPMColor[], int count) override; - - uint32_t getFlags() const override { return 0; } - - private: - SkColor fPaintColor; - - typedef SkShader::Context INHERITED; - }; - - SK_TO_STRING_OVERRIDE() - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRRectsGaussianEdgeShaderImpl) - -protected: - void flatten(SkWriteBuffer&) const override; - size_t onContextSize(const ContextRec&) const override; - Context* onCreateContext(const ContextRec&, void*) const override; - -private: - SkRRect fFirst; - SkRRect fSecond; - SkScalar fRadius; - - friend class SkRRectsGaussianEdgeShader; // for serialization registration system - - typedef SkShader INHERITED; -}; - -//////////////////////////////////////////////////////////////////////////// - -#if SK_SUPPORT_GPU - -#include "GrCoordTransform.h" -#include "GrFragmentProcessor.h" -#include "GrInvariantOutput.h" -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" -#include "glsl/GrGLSLProgramDataManager.h" -#include "glsl/GrGLSLUniformHandler.h" -#include "SkGr.h" -#include "SkGrPriv.h" - -class RRectsGaussianEdgeFP : public GrFragmentProcessor { -public: - enum Mode { - kCircle_Mode, - kRect_Mode, - kSimpleCircular_Mode, - }; - - RRectsGaussianEdgeFP(const SkRRect& first, const SkRRect& second, SkScalar radius) - : fFirst(first) - , fSecond(second) - , fRadius(radius) { - this->initClassID<RRectsGaussianEdgeFP>(); - this->setWillReadFragmentPosition(); - - fFirstMode = ComputeMode(fFirst); - fSecondMode = ComputeMode(fSecond); - } - - class GLSLRRectsGaussianEdgeFP : public GrGLSLFragmentProcessor { - public: - GLSLRRectsGaussianEdgeFP() { } - - // This method emits code so that, for each shape, the distance from the edge is returned - // in 'outputName' clamped to 0..1 with positive distance being towards the center of the - // shape. The distance will have been normalized by the radius. - void emitModeCode(Mode mode, - GrGLSLFPFragmentBuilder* fragBuilder, - const char* posName, - const char* sizesName, - const char* radiiName, - const char* radName, - const char* outputName, - const char indices[2]) { // how to access the params for the 2 rrects - - // Positive distance is towards the center of the circle. - // Map all the cases to the lower right quadrant. - fragBuilder->codeAppendf("vec2 delta = abs(%s.xy - %s.%s);", - fragBuilder->fragmentPosition(), posName, indices); - - switch (mode) { - case kCircle_Mode: - // When a shadow circle gets large we can have some precision issues if - // we do "length(delta)/radius". The scaleDist temporary cuts the - // delta vector down a bit before invoking length. - fragBuilder->codeAppendf("float scaledDist = length(delta/%s);", radName); - fragBuilder->codeAppendf("%s = clamp((%s.%c/%s - scaledDist), 0.0, 1.0);", - outputName, sizesName, indices[0], radName); - break; - case kRect_Mode: - fragBuilder->codeAppendf( - "vec2 rectDist = vec2(1.0 - clamp((%s.%c - delta.x)/%s, 0.0, 1.0)," - "1.0 - clamp((%s.%c - delta.y)/%s, 0.0, 1.0));", - sizesName, indices[0], radName, - sizesName, indices[1], radName); - fragBuilder->codeAppendf("%s = clamp(1.0 - length(rectDist), 0.0, 1.0);", - outputName); - break; - case kSimpleCircular_Mode: - // For the circular round rect we combine 2 distances: - // the fractional position from the corner inset point to the corner's circle - // the minimum perpendicular distance to the bounding rectangle - // The first distance is used when the pixel is inside the ice-cream-cone-shaped - // portion of a corner. The second is used everywhere else. - // This is intended to approximate the interpolation pattern if we had tessellated - // this geometry into a RRect outside and a rect inside. - - //---------------- - // rect distance computation - fragBuilder->codeAppendf("float xDist = (%s.%c - delta.x) / %s;", - sizesName, indices[0], radName); - fragBuilder->codeAppendf("float yDist = (%s.%c - delta.y) / %s;", - sizesName, indices[1], radName); - fragBuilder->codeAppend("float rectDist = clamp(min(xDist, yDist), 0.0, 1.0);"); - - //---------------- - // ice-cream-cone fractional distance computation - - // When the blurRadius is larger than the corner radius we want to use it to - // compute the pointy end of the ice cream cone. If it smaller we just want to use - // the center of the corner's circle. When using the blurRadius the inset amount - // can't exceed the halfwidths of the RRect. - fragBuilder->codeAppendf("float insetDist = min(max(%s, %s.%c),min(%s.%c, %s.%c));", - radName, radiiName, indices[0], - sizesName, indices[0], sizesName, indices[1]); - // "maxValue" is a correction term for if the blurRadius is larger than the - // size of the RRect. In that case we don't want to go all the way to black. - fragBuilder->codeAppendf("float maxValue = insetDist/%s;", radName); - - fragBuilder->codeAppendf("vec2 coneBottom = vec2(%s.%c - insetDist," - "%s.%c - insetDist);", - sizesName, indices[0], sizesName, indices[1]); - - fragBuilder->codeAppendf("vec2 cornerTop = vec2(%s.%c - %s.%c, %s.%c) -" - "coneBottom;", - sizesName, indices[0], radiiName, indices[0], - sizesName, indices[1]); - fragBuilder->codeAppendf("vec2 cornerRight = vec2(%s.%c, %s.%c - %s.%c) -" - "coneBottom;", - sizesName, indices[0], - sizesName, indices[1], radiiName, indices[1]); - - fragBuilder->codeAppend("vec2 ptInConeSpace = delta - coneBottom;"); - fragBuilder->codeAppend("float distToPtInConeSpace = length(ptInConeSpace);"); - - fragBuilder->codeAppend("float cross1 = ptInConeSpace.x * cornerTop.y -" - "ptInConeSpace.y * cornerTop.x;"); - fragBuilder->codeAppend("float cross2 = -ptInConeSpace.x * cornerRight.y + " - "ptInConeSpace.y * cornerRight.x;"); - - fragBuilder->codeAppend("float inCone = step(0.0, cross1) * step(0.0, cross2);"); - - fragBuilder->codeAppendf("vec2 cornerCenterInConeSpace = vec2(insetDist - %s.%c);", - radiiName, indices[0]); - - fragBuilder->codeAppend("vec2 connectingVec = ptInConeSpace -" - "cornerCenterInConeSpace;"); - fragBuilder->codeAppend("ptInConeSpace = normalize(ptInConeSpace);"); - - // "a" (i.e., dot(ptInConeSpace, ptInConeSpace) should always be 1.0f since - // ptInConeSpace is now normalized - fragBuilder->codeAppend("float b = 2.0 * dot(ptInConeSpace, connectingVec);"); - fragBuilder->codeAppendf("float c = dot(connectingVec, connectingVec) - " - "%s.%c * %s.%c;", - radiiName, indices[0], radiiName, indices[0]); - - fragBuilder->codeAppend("float fourAC = 4*c;"); - // This max prevents sqrt(-1) when outside the cone - fragBuilder->codeAppend("float bSq = max(b*b, fourAC);"); - - // lop off negative values that are outside the cone - fragBuilder->codeAppend("float coneDist = max(0.0, " - "0.5 * (-b + sqrt(bSq - fourAC)));"); - // make the coneDist a fraction of how far it is from the edge to the cone's base - fragBuilder->codeAppend("coneDist = (maxValue*coneDist) /" - "(coneDist+distToPtInConeSpace);"); - fragBuilder->codeAppend("coneDist = clamp(coneDist, 0.0, 1.0);"); - - //---------------- - fragBuilder->codeAppendf("%s = (inCone * coneDist) + ((1.0-inCone) * rectDist);", - outputName); - break; - } - } - - void emitCode(EmitArgs& args) override { - const RRectsGaussianEdgeFP& fp = args.fFp.cast<RRectsGaussianEdgeFP>(); - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - - const char* positionsUniName = nullptr; - fPositionsUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec4f_GrSLType, kDefault_GrSLPrecision, - "Positions", &positionsUniName); - const char* sizesUniName = nullptr; - fSizesUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec4f_GrSLType, kDefault_GrSLPrecision, - "Sizes", &sizesUniName); - const char* radiiUniName = nullptr; - if (fp.fFirstMode == kSimpleCircular_Mode || fp.fSecondMode == kSimpleCircular_Mode) { - fRadiiUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec4f_GrSLType, kDefault_GrSLPrecision, - "Radii", &radiiUniName); - } - const char* radUniName = nullptr; - fRadiusUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, kDefault_GrSLPrecision, - "Radius", &radUniName); - - fragBuilder->codeAppend("float firstDist;"); - fragBuilder->codeAppend("{"); - this->emitModeCode(fp.firstMode(), fragBuilder, - positionsUniName, sizesUniName, radiiUniName, - radUniName, "firstDist", "xy"); - fragBuilder->codeAppend("}"); - - fragBuilder->codeAppend("float secondDist;"); - fragBuilder->codeAppend("{"); - this->emitModeCode(fp.secondMode(), fragBuilder, - positionsUniName, sizesUniName, radiiUniName, - radUniName, "secondDist", "zw"); - fragBuilder->codeAppend("}"); - - fragBuilder->codeAppend("vec2 distVec = vec2(1.0 - firstDist, 1.0 - secondDist);"); - - // Finally use the distance to apply the Gaussian edge - fragBuilder->codeAppend("float factor = clamp(length(distVec), 0.0, 1.0);"); - fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;"); - fragBuilder->codeAppendf("%s = factor*%s;", - args.fOutputColor, args.fInputColor); - } - - static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, - GrProcessorKeyBuilder* b) { - const RRectsGaussianEdgeFP& fp = proc.cast<RRectsGaussianEdgeFP>(); - - b->add32(fp.firstMode() | (fp.secondMode() << 4)); - } - - protected: - void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override { - const RRectsGaussianEdgeFP& edgeFP = proc.cast<RRectsGaussianEdgeFP>(); - - const SkRRect& first = edgeFP.first(); - const SkRRect& second = edgeFP.second(); - - pdman.set4f(fPositionsUni, - first.getBounds().centerX(), - first.getBounds().centerY(), - second.getBounds().centerX(), - second.getBounds().centerY()); - - pdman.set4f(fSizesUni, - 0.5f * first.rect().width(), - 0.5f * first.rect().height(), - 0.5f * second.rect().width(), - 0.5f * second.rect().height()); - - if (edgeFP.firstMode() == kSimpleCircular_Mode || - edgeFP.secondMode() == kSimpleCircular_Mode) { - // This is a bit of overkill since fX should equal fY for both round rects but it - // makes the shader code simpler. - pdman.set4f(fRadiiUni, - first.getSimpleRadii().fX, first.getSimpleRadii().fY, - second.getSimpleRadii().fX, second.getSimpleRadii().fY); - } - - pdman.set1f(fRadiusUni, edgeFP.radius()); - } - - private: - // The centers of the two round rects (x1, y1, x2, y2) - GrGLSLProgramDataManager::UniformHandle fPositionsUni; - - // The half widths and half heights of the two round rects (w1/2, h1/2, w2/2, h2/2) - // For circles we still upload both width & height to simplify things - GrGLSLProgramDataManager::UniformHandle fSizesUni; - - // The corner radii of the two round rects (rx1, ry1, rx2, ry2) - // We upload both the x&y radii (although they are currently always the same) to make - // the indexing in the shader code simpler. In some future world we could also support - // non-circular corner round rects & ellipses. - GrGLSLProgramDataManager::UniformHandle fRadiiUni; - - // The radius parameters (radius) - GrGLSLProgramDataManager::UniformHandle fRadiusUni; - - typedef GrGLSLFragmentProcessor INHERITED; - }; - - void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { - GLSLRRectsGaussianEdgeFP::GenKey(*this, caps, b); - } - - const char* name() const override { return "RRectsGaussianEdgeFP"; } - - void onComputeInvariantOutput(GrInvariantOutput* inout) const override { - inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); - } - - const SkRRect& first() const { return fFirst; } - Mode firstMode() const { return fFirstMode; } - const SkRRect& second() const { return fSecond; } - Mode secondMode() const { return fSecondMode; } - SkScalar radius() const { return fRadius; } - -private: - static Mode ComputeMode(const SkRRect& rr) { - if (rr.isCircle()) { - return kCircle_Mode; - } else if (rr.isRect()) { - return kRect_Mode; - } else { - SkASSERT(rr.isSimpleCircular()); - return kSimpleCircular_Mode; - } - } - - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { - return new GLSLRRectsGaussianEdgeFP; - } - - bool onIsEqual(const GrFragmentProcessor& proc) const override { - const RRectsGaussianEdgeFP& edgeFP = proc.cast<RRectsGaussianEdgeFP>(); - return fFirst == edgeFP.fFirst && - fSecond == edgeFP.fSecond && - fRadius == edgeFP.fRadius; - } - - SkRRect fFirst; - Mode fFirstMode; - SkRRect fSecond; - Mode fSecondMode; - SkScalar fRadius; - - typedef GrFragmentProcessor INHERITED; -}; - -//////////////////////////////////////////////////////////////////////////// - -sk_sp<GrFragmentProcessor> SkRRectsGaussianEdgeShaderImpl::asFragmentProcessor( - const AsFPArgs& args) const { - return sk_make_sp<RRectsGaussianEdgeFP>(fFirst, fSecond, fRadius); -} - -#endif - -//////////////////////////////////////////////////////////////////////////// - -SkRRectsGaussianEdgeShaderImpl::GaussianEdgeShaderContext::GaussianEdgeShaderContext( - const SkRRectsGaussianEdgeShaderImpl& shader, - const ContextRec& rec) - : INHERITED(shader, rec) { - - fPaintColor = rec.fPaint->getColor(); -} - -void SkRRectsGaussianEdgeShaderImpl::GaussianEdgeShaderContext::shadeSpan(int x, int y, - SkPMColor result[], - int count) { - // TODO: implement - for (int i = 0; i < count; ++i) { - result[i] = fPaintColor; - } -} - -//////////////////////////////////////////////////////////////////////////// - -#ifndef SK_IGNORE_TO_STRING -void SkRRectsGaussianEdgeShaderImpl::toString(SkString* str) const { - str->appendf("RRectsGaussianEdgeShader: ()"); -} -#endif - -sk_sp<SkFlattenable> SkRRectsGaussianEdgeShaderImpl::CreateProc(SkReadBuffer& buf) { - // Discarding SkShader flattenable params - bool hasLocalMatrix = buf.readBool(); - SkAssertResult(!hasLocalMatrix); - - SkRect rect1, rect2; - - buf.readRect(&rect1); - SkScalar xRad1 = buf.readScalar(); - SkScalar yRad1 = buf.readScalar(); - - buf.readRect(&rect2); - SkScalar xRad2 = buf.readScalar(); - SkScalar yRad2 = buf.readScalar(); - - SkScalar radius = buf.readScalar(); - - return sk_make_sp<SkRRectsGaussianEdgeShaderImpl>(SkRRect::MakeRectXY(rect1, xRad1, yRad1), - SkRRect::MakeRectXY(rect2, xRad2, yRad2), - radius); -} - -void SkRRectsGaussianEdgeShaderImpl::flatten(SkWriteBuffer& buf) const { - INHERITED::flatten(buf); - - SkASSERT(fFirst.isRect() || fFirst.isCircle() || fFirst.isSimpleCircular()); - buf.writeRect(fFirst.rect()); - const SkVector& radii1 = fFirst.getSimpleRadii(); - buf.writeScalar(radii1.fX); - buf.writeScalar(radii1.fY); - - SkASSERT(fSecond.isRect() || fSecond.isCircle() || fSecond.isSimpleCircular()); - buf.writeRect(fSecond.rect()); - const SkVector& radii2 = fSecond.getSimpleRadii(); - buf.writeScalar(radii2.fX); - buf.writeScalar(radii2.fY); - - buf.writeScalar(fRadius); -} - -size_t SkRRectsGaussianEdgeShaderImpl::onContextSize(const ContextRec& rec) const { - return sizeof(GaussianEdgeShaderContext); -} - -SkShader::Context* SkRRectsGaussianEdgeShaderImpl::onCreateContext(const ContextRec& rec, - void* storage) const { - return new (storage) GaussianEdgeShaderContext(*this, rec); -} - -/////////////////////////////////////////////////////////////////////////////// - -sk_sp<SkShader> SkRRectsGaussianEdgeShader::Make(const SkRRect& first, - const SkRRect& second, - SkScalar radius, SkScalar unused) { - if ((!first.isRect() && !first.isCircle() && !first.isSimpleCircular()) || - (!second.isRect() && !second.isCircle() && !second.isSimpleCircular())) { - // we only deal with the shapes where the x & y radii are equal - // and the same for all four corners - return nullptr; - } - - return sk_make_sp<SkRRectsGaussianEdgeShaderImpl>(first, second, radius); -} - -/////////////////////////////////////////////////////////////////////////////// - -SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkRRectsGaussianEdgeShader) -SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRRectsGaussianEdgeShaderImpl) -SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END - -/////////////////////////////////////////////////////////////////////////////// |