Add some additional checks for shadow generation
Change-Id: I4dae4173ad879827e4e1fa3ad12aa0447d1df252 Reviewed-on: https://skia-review.googlesource.com/110360 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
1693d43f37
commit
a947e29bfd
@ -107,6 +107,24 @@ struct SK_API SkPoint3 {
|
||||
fZ -= v.fZ;
|
||||
}
|
||||
|
||||
/** Returns true if fX, fY, and fZ are measurable values.
|
||||
|
||||
@return true for values other than infinities and NaN
|
||||
*/
|
||||
bool isFinite() const {
|
||||
SkScalar accum = 0;
|
||||
accum *= fX;
|
||||
accum *= fY;
|
||||
accum *= fZ;
|
||||
|
||||
// accum is either NaN or it is finite (zero).
|
||||
SkASSERT(0 == accum || SkScalarIsNaN(accum));
|
||||
|
||||
// value==value will be true iff value is not NaN
|
||||
// TODO: is it faster to say !accum or accum==accum?
|
||||
return !SkScalarIsNaN(accum);
|
||||
}
|
||||
|
||||
/** Returns the dot product of a and b, treating them as 3D vectors
|
||||
*/
|
||||
static SkScalar DotProduct(const SkPoint3& a, const SkPoint3& b) {
|
||||
|
@ -177,6 +177,12 @@ void SkBaseShadowTessellator::handleLine(const SkMatrix& m, SkPoint* p) {
|
||||
|
||||
void SkBaseShadowTessellator::handleQuad(const SkPoint pts[3]) {
|
||||
#if SK_SUPPORT_GPU
|
||||
// check for degeneracy
|
||||
SkVector v0 = pts[1] - pts[0];
|
||||
SkVector v1 = pts[2] - pts[0];
|
||||
if (SkScalarNearlyZero(v0.cross(v1))) {
|
||||
return;
|
||||
}
|
||||
// TODO: Pull PathUtils out of Ganesh?
|
||||
int maxCount = GrPathUtils::quadraticPointCount(pts, kQuadTolerance);
|
||||
fPointBuffer.setReserve(maxCount);
|
||||
@ -277,7 +283,7 @@ bool SkBaseShadowTessellator::setTransformedHeightFunc(const SkMatrix& ctm) {
|
||||
};
|
||||
} else {
|
||||
SkMatrix ctmInverse;
|
||||
if (!ctm.invert(&ctmInverse)) {
|
||||
if (!ctm.invert(&ctmInverse) || !ctmInverse.isFinite()) {
|
||||
return false;
|
||||
}
|
||||
// multiply by transpose
|
||||
|
@ -535,6 +535,11 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
|
||||
canvas->private_draw_shadow_rec(path, rec);
|
||||
}
|
||||
|
||||
static bool validate_rec(const SkDrawShadowRec& rec) {
|
||||
return rec.fLightPos.isFinite() && rec.fZPlaneParams.isFinite() &&
|
||||
SkScalarIsFinite(rec.fLightRadius);
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
|
||||
auto drawVertsProc = [this](const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint,
|
||||
SkScalar tx, SkScalar ty) {
|
||||
@ -543,6 +548,10 @@ void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
|
||||
this->drawVertices(vertices, mode, paint);
|
||||
};
|
||||
|
||||
if (!validate_rec(rec)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkMatrix viewMatrix = this->ctm();
|
||||
SkAutoDeviceCTMRestore adr(this, SkMatrix::I());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user