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>
This commit is contained in:
parent
207282eb5a
commit
e7e1d9d039
@ -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;
|
||||
|
@ -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()) {
|
||||
|
Loading…
Reference in New Issue
Block a user