diff options
author | Jim Van Verth <jvanverth@google.com> | 2017-05-01 16:06:48 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-05-02 14:25:28 +0000 |
commit | e7e1d9d039b12a86b9a595871a2bd13fe1c28f72 (patch) | |
tree | 87c7c1eba572051079bff86416479cfecbb84d34 /src/utils | |
parent | 207282eb5ac6f009e6f736fb8e5cfcee000ee92a (diff) |
Fix up shadows in raster.
* Re-enable shadow blurs for raster circles and rrects
* Fix up the tessellation as much as possible to remove skinny triangles
Bug: skia:6425
Change-Id: I6548055084bc8596a052bcd3cec852766e084ba2
Reviewed-on: https://skia-review.googlesource.com/14943
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'src/utils')
-rwxr-xr-x | src/utils/SkShadowTessellator.cpp | 60 | ||||
-rw-r--r-- | src/utils/SkShadowUtils.cpp | 5 |
2 files changed, 42 insertions, 23 deletions
diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp index 5dee5df3e0..36df514534 100755 --- a/src/utils/SkShadowTessellator.cpp +++ b/src/utils/SkShadowTessellator.cpp @@ -54,7 +54,7 @@ protected: bool setTransformedHeightFunc(const SkMatrix& ctm); - void addArc(const SkVector& nextNormal, bool finishArc); + bool addArc(const SkVector& nextNormal, bool finishArc); SkShadowTessellator::HeightFunc fHeightFunc; std::function<SkScalar(const SkPoint&)> fTransformedHeightFunc; @@ -105,17 +105,17 @@ static bool compute_normal(const SkPoint& p0, const SkPoint& p1, SkScalar dir, static void compute_radial_steps(const SkVector& v1, const SkVector& v2, SkScalar r, SkScalar* rotSin, SkScalar* rotCos, int* n) { - const SkScalar kRecipPixelsPerArcSegment = 0.25f; + const SkScalar kRecipPixelsPerArcSegment = 0.125f; SkScalar rCos = v1.dot(v2); SkScalar rSin = v1.cross(v2); SkScalar theta = SkScalarATan2(rSin, rCos); - SkScalar steps = r*theta*kRecipPixelsPerArcSegment; + int steps = SkScalarFloorToInt(r*theta*kRecipPixelsPerArcSegment); SkScalar dTheta = theta / steps; *rotSin = SkScalarSinCos(dTheta, rotCos); - *n = SkScalarFloorToInt(steps); + *n = steps; } SkBaseShadowTessellator::SkBaseShadowTessellator(SkShadowTessellator::HeightFunc heightFunc, @@ -234,32 +234,34 @@ void SkBaseShadowTessellator::handleConic(const SkMatrix& m, SkPoint pts[3], SkS } } -void SkBaseShadowTessellator::addArc(const SkVector& nextNormal, bool finishArc) { +bool SkBaseShadowTessellator::addArc(const SkVector& nextNormal, bool finishArc) { // 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) { + for (int i = 0; i < numSteps-1; ++i) { SkVector currNormal; currNormal.fX = prevNormal.fX*rotCos - prevNormal.fY*rotSin; currNormal.fY = prevNormal.fY*rotCos + prevNormal.fX*rotSin; *fPositions.push() = fPrevPoint + currNormal; *fColors.push() = fPenumbraColor; *fIndices.push() = fPrevUmbraIndex; - *fIndices.push() = fPositions.count() - 2; *fIndices.push() = fPositions.count() - 1; + *fIndices.push() = fPositions.count() - 2; prevNormal = currNormal; } - if (finishArc) { + if (finishArc && numSteps) { *fPositions.push() = fPrevPoint + nextNormal; *fColors.push() = fPenumbraColor; *fIndices.push() = fPrevUmbraIndex; - *fIndices.push() = fPositions.count() - 2; *fIndices.push() = fPositions.count() - 1; + *fIndices.push() = fPositions.count() - 2; } fPrevNormal = nextNormal; + + return (numSteps > 0); } bool SkBaseShadowTessellator::setTransformedHeightFunc(const SkMatrix& ctm) { @@ -488,11 +490,15 @@ SkAmbientShadowTessellator::SkAmbientShadowTessellator(const SkPath& path, fPrevUmbraIndex = fFirstVertex; fPrevPoint = fFirstPoint; fRadius = this->offset(fTransformedHeightFunc(fPrevPoint)); - this->addArc(fFirstNormal, false); - - *fIndices.push() = fFirstVertex; - *fIndices.push() = fPositions.count() - 1; - *fIndices.push() = fFirstVertex + 1; + if (this->addArc(fFirstNormal, false)) { + *fIndices.push() = fFirstVertex; + *fIndices.push() = fPositions.count() - 1; + *fIndices.push() = fFirstVertex + 1; + } else { + // arc is too small, set the first penumbra point to be the same position + // as the last one + fPositions[fFirstVertex + 1] = fPositions[fPositions.count() - 1]; + } } fSucceeded = true; } @@ -858,14 +864,21 @@ SkSpotShadowTessellator::SkSpotShadowTessellator(const SkPath& path, const SkMat if (fPositions.count() >= 3) { fPrevUmbraIndex = fFirstVertex; fPrevPoint = fFirstPoint; - this->addArc(fFirstNormal, false); - - *fIndices.push() = fFirstVertex; - *fIndices.push() = fPositions.count() - 1; - if (fFirstUmbraOutside) { - *fIndices.push() = fFirstVertex + 2; + if (this->addArc(fFirstNormal, false)) { + *fIndices.push() = fFirstVertex; + *fIndices.push() = fPositions.count() - 1; + if (fFirstUmbraOutside) { + *fIndices.push() = fFirstVertex + 2; + } else { + *fIndices.push() = fFirstVertex + 1; + } } else { - *fIndices.push() = fFirstVertex + 1; + // no arc added, fix up by setting first penumbra point position to last one + if (fFirstUmbraOutside) { + fPositions[fFirstVertex + 2] = fPositions[fPositions.count() - 1]; + } else { + fPositions[fFirstVertex + 1] = fPositions[fPositions.count() - 1]; + } } } @@ -1160,9 +1173,10 @@ void SkSpotShadowTessellator::handlePolyPoint(const SkPoint& p) { fFirstVertex = fPositions.count(); fPrevNormal = fFirstNormal; fPrevPoint = fFirstPoint; - fPrevUmbraIndex = fFirstVertex; + fPrevUmbraIndex = -1; this->addInnerPoint(fFirstPoint); + fPrevUmbraIndex = fFirstVertex; if (!fTransparent) { SkPoint clipPoint; @@ -1205,7 +1219,7 @@ bool SkSpotShadowTessellator::addInnerPoint(const SkPoint& pathPoint) { fPrevPoint = pathPoint; // merge "close" points - if (fPrevUmbraIndex == fFirstVertex || + if (fPrevUmbraIndex == -1 || !duplicate_pt(umbraPoint, fPositions[fPrevUmbraIndex])) { *fPositions.push() = umbraPoint; *fColors.push() = fUmbraColor; diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp index fc0d44a277..928eb66bcb 100644 --- a/src/utils/SkShadowUtils.cpp +++ b/src/utils/SkShadowUtils.cpp @@ -458,6 +458,11 @@ static bool draw_analytic_shadows(SkCanvas* canvas, const SkPath& path, SkScalar const SkPoint3& devLightPos, SkScalar lightRadius, SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color, uint32_t flags) { + // only supported in GPU code + if (!canvas->getGrContext()) { + return false; + } + SkRect rect; SkRRect rrect; if (canvas->getTotalMatrix().isSimilarity()) { |