diff options
author | Jim Van Verth <jvanverth@google.com> | 2017-01-25 11:05:01 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-01-25 16:37:59 +0000 |
commit | 58abc9e2c56464336472493745e91133819deb96 (patch) | |
tree | a9bc4cdab83eb6f265f40865f25173735a9f2287 /src/effects | |
parent | de80f7f35d472c03ce882ec31434e59c002f58db (diff) |
Move SkShadowTessellator to GrShadowTessellator
BUG=skia:6119
Change-Id: I9756b5aeaced1f21a65063470ccb013c7b856f28
Reviewed-on: https://skia-review.googlesource.com/7505
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'src/effects')
-rwxr-xr-x | src/effects/shadows/SkAmbientShadowMaskFilter.cpp | 4 | ||||
-rwxr-xr-x | src/effects/shadows/SkShadowTessellator.cpp | 314 | ||||
-rwxr-xr-x | src/effects/shadows/SkShadowTessellator.h | 75 |
3 files changed, 2 insertions, 391 deletions
diff --git a/src/effects/shadows/SkAmbientShadowMaskFilter.cpp b/src/effects/shadows/SkAmbientShadowMaskFilter.cpp index e378c184b9..d92a7b548c 100755 --- a/src/effects/shadows/SkAmbientShadowMaskFilter.cpp +++ b/src/effects/shadows/SkAmbientShadowMaskFilter.cpp @@ -18,11 +18,11 @@ #include "GrStyle.h" #include "GrTexture.h" #include "GrTextureProxy.h" +#include "effects/GrShadowTessellator.h" #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" #include "glsl/GrGLSLUniformHandler.h" -#include "SkShadowTessellator.h" #include "SkStrokeRec.h" #endif @@ -238,7 +238,7 @@ bool SkAmbientShadowMaskFilterImpl::directFilterMaskGPU(GrTextureProvider* texPr GrColor umbraColor = GrColorPackRGBA(0, 0, fAmbientAlpha*255.9999f, umbraAlpha*255.9999f); GrColor penumbraColor = GrColorPackRGBA(0, 0, fAmbientAlpha*255.9999f, 0); - SkAmbientShadowTessellator tess(SkMatrix::I(), path, radius, umbraColor, penumbraColor, + GrAmbientShadowTessellator tess(SkMatrix::I(), path, radius, umbraColor, penumbraColor, SkToBool(fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag)); sk_sp<ShadowEdgeFP> edgeFP(new ShadowEdgeFP); diff --git a/src/effects/shadows/SkShadowTessellator.cpp b/src/effects/shadows/SkShadowTessellator.cpp deleted file mode 100755 index 0a320ceba9..0000000000 --- a/src/effects/shadows/SkShadowTessellator.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright 2017 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkShadowTessellator.h" -#include "SkGeometry.h" - -#if SK_SUPPORT_GPU -#include "GrPathUtils.h" - -static bool compute_normal(const SkPoint& p0, const SkPoint& p1, SkScalar radius, SkScalar dir, - SkVector* newNormal) { - SkVector normal; - // compute perpendicular - normal.fX = p0.fY - p1.fY; - normal.fY = p1.fX - p0.fX; - if (!normal.normalize()) { - return false; - } - normal *= radius*dir; - *newNormal = normal; - return true; -} - -static void compute_radial_steps(const SkVector& v1, const SkVector& v2, SkScalar r, - SkScalar* rotSin, SkScalar* rotCos, int* n) { - const SkScalar kRecipPixelsPerArcSegment = 0.25f; - - SkScalar rCos = v1.dot(v2); - SkScalar rSin = v1.cross(v2); - SkScalar theta = SkScalarATan2(rSin, rCos); - - SkScalar steps = r*theta*kRecipPixelsPerArcSegment; - - SkScalar dTheta = theta / steps; - *rotSin = SkScalarSinCos(dTheta, rotCos); - *n = SkScalarFloorToInt(steps); -} - -SkAmbientShadowTessellator::SkAmbientShadowTessellator(const SkMatrix& viewMatrix, - const SkPath& path, - SkScalar radius, - GrColor umbraColor, - GrColor penumbraColor, - bool transparent) - : fRadius(radius) - , fUmbraColor(umbraColor) - , fPenumbraColor(penumbraColor) - , fTransparent(transparent) - , fPrevInnerIndex(-1) { - - // Outer ring: 3*numPts - // Middle ring: numPts - fPositions.setReserve(4 * path.countPoints()); - fColors.setReserve(4 * path.countPoints()); - // Outer ring: 12*numPts - // Middle ring: 0 - fIndices.setReserve(12 * path.countPoints()); - - fInitPoints.setReserve(3); - - // walk around the path, tessellate and generate outer ring - // if original path is transparent, will accumulate sum of points for centroid - SkPath::Iter iter(path, true); - SkPoint pts[4]; - SkPath::Verb verb; - if (fTransparent) { - *fPositions.push() = SkPoint::Make(0, 0); - *fColors.push() = umbraColor; - fCentroidCount = 0; - } - while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { - switch (verb) { - case SkPath::kLine_Verb: - this->handleLine(viewMatrix, pts[1]); - break; - case SkPath::kQuad_Verb: - this->handleQuad(viewMatrix, pts); - break; - case SkPath::kCubic_Verb: - this->handleCubic(viewMatrix, pts); - break; - case SkPath::kConic_Verb: - this->handleConic(viewMatrix, pts, iter.conicWeight()); - break; - case SkPath::kMove_Verb: - case SkPath::kClose_Verb: - case SkPath::kDone_Verb: - break; - } - } - - SkVector normal; - if (compute_normal(fPositions[fPrevInnerIndex], fPositions[fFirstVertex], fRadius, fDirection, - &normal)) { - this->addArc(normal); - - // close out previous arc - *fPositions.push() = fPositions[fPrevInnerIndex] + normal; - *fColors.push() = fPenumbraColor; - *fIndices.push() = fPrevInnerIndex; - *fIndices.push() = fPositions.count() - 2; - *fIndices.push() = fPositions.count() - 1; - - // add final edge - *fPositions.push() = fPositions[fFirstVertex] + normal; - *fColors.push() = fPenumbraColor; - - *fIndices.push() = fPrevInnerIndex; - *fIndices.push() = fPositions.count() - 2; - *fIndices.push() = fFirstVertex; - - *fIndices.push() = fPositions.count() - 2; - *fIndices.push() = fPositions.count() - 1; - *fIndices.push() = fFirstVertex; - } - - // finalize centroid - if (fTransparent) { - fPositions[0] *= SkScalarFastInvert(fCentroidCount); - - *fIndices.push() = 0; - *fIndices.push() = fPrevInnerIndex; - *fIndices.push() = fFirstVertex; - } - - // final fan - if (fPositions.count() >= 3) { - fPrevInnerIndex = fFirstVertex; - fPrevNormal = normal; - this->addArc(fFirstNormal); - - *fIndices.push() = fFirstVertex; - *fIndices.push() = fPositions.count() - 1; - *fIndices.push() = fFirstVertex + 1; - } -} - -// tesselation tolerance values, in device space pixels -static const SkScalar kQuadTolerance = 0.2f; -static const SkScalar kCubicTolerance = 0.2f; -static const SkScalar kConicTolerance = 0.5f; - -void SkAmbientShadowTessellator::handleLine(const SkPoint& p) { - if (fInitPoints.count() < 2) { - *fInitPoints.push() = p; - return; - } - - if (fInitPoints.count() == 2) { - // determine if cw or ccw - SkVector v0 = fInitPoints[1] - fInitPoints[0]; - SkVector v1 = p - fInitPoints[0]; - SkScalar perpDot = v0.fX*v1.fY - v0.fY*v1.fX; - if (SkScalarNearlyZero(perpDot)) { - // nearly parallel, just treat as straight line and continue - fInitPoints[1] = p; - return; - } - - // if perpDot > 0, winding is ccw - fDirection = (perpDot > 0) ? -1 : 1; - - // add first quad - if (!compute_normal(fInitPoints[0], fInitPoints[1], fRadius, fDirection, - &fFirstNormal)) { - // first two points are incident, make the third point the second and continue - fInitPoints[1] = p; - return; - } - - fFirstVertex = fPositions.count(); - fPrevNormal = fFirstNormal; - fPrevInnerIndex = fFirstVertex; - - *fPositions.push() = fInitPoints[0]; - *fColors.push() = fUmbraColor; - *fPositions.push() = fInitPoints[0] + fFirstNormal; - *fColors.push() = fPenumbraColor; - if (fTransparent) { - fPositions[0] += fInitPoints[0]; - fCentroidCount = 1; - } - this->addEdge(fInitPoints[1], fFirstNormal); - - // to ensure we skip this block next time - *fInitPoints.push() = p; - } - - SkVector normal; - if (compute_normal(fPositions[fPrevInnerIndex], p, fRadius, fDirection, &normal)) { - this->addArc(normal); - this->addEdge(p, normal); - } -} - -void SkAmbientShadowTessellator::handleLine(const SkMatrix& m, SkPoint p) { - m.mapPoints(&p, 1); - this->handleLine(p); -} - -void SkAmbientShadowTessellator::handleQuad(const SkPoint pts[3]) { - int maxCount = GrPathUtils::quadraticPointCount(pts, kQuadTolerance); - fPointBuffer.setReserve(maxCount); - SkPoint* target = fPointBuffer.begin(); - int count = GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2], - kQuadTolerance, &target, maxCount); - fPointBuffer.setCount(count); - for (int i = 0; i < count; i++) { - this->handleLine(fPointBuffer[i]); - } -} - -void SkAmbientShadowTessellator::handleQuad(const SkMatrix& m, SkPoint pts[3]) { - m.mapPoints(pts, 3); - this->handleQuad(pts); -} - -void SkAmbientShadowTessellator::handleCubic(const SkMatrix& m, SkPoint pts[4]) { - m.mapPoints(pts, 4); - int maxCount = GrPathUtils::cubicPointCount(pts, kCubicTolerance); - fPointBuffer.setReserve(maxCount); - SkPoint* target = fPointBuffer.begin(); - int count = GrPathUtils::generateCubicPoints(pts[0], pts[1], pts[2], pts[3], - kCubicTolerance, &target, maxCount); - fPointBuffer.setCount(count); - for (int i = 0; i < count; i++) { - this->handleLine(fPointBuffer[i]); - } -} - -void SkAmbientShadowTessellator::handleConic(const SkMatrix& m, SkPoint pts[3], SkScalar w) { - m.mapPoints(pts, 3); - SkAutoConicToQuads quadder; - const SkPoint* quads = quadder.computeQuads(pts, w, kConicTolerance); - SkPoint lastPoint = *(quads++); - int count = quadder.countQuads(); - for (int i = 0; i < count; ++i) { - SkPoint quadPts[3]; - quadPts[0] = lastPoint; - quadPts[1] = quads[0]; - quadPts[2] = i == count - 1 ? pts[2] : quads[1]; - this->handleQuad(quadPts); - lastPoint = quadPts[2]; - quads += 2; - } -} - -void SkAmbientShadowTessellator::addArc(const SkVector& nextNormal) { - // fill in fan from previous quad - SkScalar rotSin, rotCos; - int numSteps; - compute_radial_steps(fPrevNormal, nextNormal, fRadius, &rotSin, &rotCos, &numSteps); - SkVector prevNormal = fPrevNormal; - for (int i = 0; i < numSteps; ++i) { - SkVector nextNormal; - nextNormal.fX = prevNormal.fX*rotCos - prevNormal.fY*rotSin; - nextNormal.fY = prevNormal.fY*rotCos + prevNormal.fX*rotSin; - *fPositions.push() = fPositions[fPrevInnerIndex] + nextNormal; - *fColors.push() = fPenumbraColor; - *fIndices.push() = fPrevInnerIndex; - *fIndices.push() = fPositions.count() - 2; - *fIndices.push() = fPositions.count() - 1; - - prevNormal = nextNormal; - } -} - - -void SkAmbientShadowTessellator::finishArcAndAddEdge(const SkPoint& nextPoint, - const SkVector& nextNormal) { - // close out previous arc - *fPositions.push() = fPositions[fPrevInnerIndex] + nextNormal; - *fColors.push() = fPenumbraColor; - *fIndices.push() = fPrevInnerIndex; - *fIndices.push() = fPositions.count() - 2; - *fIndices.push() = fPositions.count() - 1; - - this->addEdge(nextPoint, nextNormal); -} - -void SkAmbientShadowTessellator::addEdge(const SkPoint& nextPoint, const SkVector& nextNormal) { - // add next quad - *fPositions.push() = nextPoint; - *fColors.push() = fUmbraColor; - *fPositions.push() = nextPoint + nextNormal; - *fColors.push() = fPenumbraColor; - - *fIndices.push() = fPrevInnerIndex; - *fIndices.push() = fPositions.count() - 3; - *fIndices.push() = fPositions.count() - 2; - - *fIndices.push() = fPositions.count() - 3; - *fIndices.push() = fPositions.count() - 1; - *fIndices.push() = fPositions.count() - 2; - - // if transparent, add point to first one in array and add to center fan - if (fTransparent) { - fPositions[0] += nextPoint; - ++fCentroidCount; - - *fIndices.push() = 0; - *fIndices.push() = fPrevInnerIndex; - *fIndices.push() = fPositions.count() - 2; - } - - fPrevInnerIndex = fPositions.count() - 2; - fPrevNormal = nextNormal; -} - -#endif diff --git a/src/effects/shadows/SkShadowTessellator.h b/src/effects/shadows/SkShadowTessellator.h deleted file mode 100755 index 91274340df..0000000000 --- a/src/effects/shadows/SkShadowTessellator.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2017 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkShadowTessellator_DEFINED -#define SkShadowTessellator_DEFINED - -#include "SkTDArray.h" -#include "SkPoint.h" - -#if SK_SUPPORT_GPU -#include "GrColor.h" - -class SkMatrix; -class SkPath; - -/** - * This class generates an ambient shadow for a path by walking the path, outsetting by the - * radius, and setting inner and outer colors to umbraColor and penumbraColor, respectively. - * If transparent is true, then the center of the ambient shadow will be filled in. - */ -class SkAmbientShadowTessellator { -public: - SkAmbientShadowTessellator(const SkMatrix& viewMatrix, const SkPath& path, SkScalar radius, - GrColor umbraColor, GrColor penumbraColor, bool transparent); - - int vertexCount() { return fPositions.count(); } - SkPoint* positions() { return fPositions.begin(); } - GrColor* colors() { return fColors.begin(); } - int indexCount() { return fIndices.count(); } - uint16_t* indices() { return fIndices.begin(); } - -private: - void handleLine(const SkPoint& p); - void handleLine(const SkMatrix& m, SkPoint p); - - void handleQuad(const SkPoint pts[3]); - void handleQuad(const SkMatrix& m, SkPoint pts[3]); - - void handleCubic(const SkMatrix& m, SkPoint pts[4]); - - void handleConic(const SkMatrix& m, SkPoint pts[3], SkScalar w); - - void addArc(const SkVector& nextNormal); - void finishArcAndAddEdge(const SkVector& nextPoint, const SkVector& nextNormal); - void addEdge(const SkVector& nextPoint, const SkVector& nextNormal); - - SkScalar fRadius; - GrColor fUmbraColor; - GrColor fPenumbraColor; - bool fTransparent; - - SkTDArray<SkPoint> fPositions; - SkTDArray<GrColor> fColors; - SkTDArray<uint16_t> fIndices; - - int fPrevInnerIndex; - SkVector fPrevNormal; - int fFirstVertex; - SkVector fFirstNormal; - SkScalar fDirection; - int fCentroidCount; - - // first three points - SkTDArray<SkPoint> fInitPoints; - // temporary buffer - SkTDArray<SkPoint> fPointBuffer; -}; - -#endif - -#endif |