summaryrefslogtreecommitdiffstats
path: root/gfx/skia
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/skia')
-rw-r--r--gfx/skia/skia/include/core/SkPath.h2
-rw-r--r--gfx/skia/skia/src/core/SkGeometry.cpp32
-rw-r--r--gfx/skia/skia/src/core/SkPath.cpp41
-rw-r--r--gfx/skia/skia/src/core/SkRRect.cpp18
-rw-r--r--gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp11
5 files changed, 76 insertions, 28 deletions
diff --git a/gfx/skia/skia/include/core/SkPath.h b/gfx/skia/skia/include/core/SkPath.h
index d1af4f31b..bde07c498 100644
--- a/gfx/skia/skia/include/core/SkPath.h
+++ b/gfx/skia/skia/include/core/SkPath.h
@@ -373,7 +373,7 @@ public:
@param extraPtCount The number of extra points the path should
preallocate for.
*/
- void incReserve(unsigned extraPtCount);
+ void incReserve(int extraPtCount);
/** Set the beginning of the next contour to the point (x,y).
diff --git a/gfx/skia/skia/src/core/SkGeometry.cpp b/gfx/skia/skia/src/core/SkGeometry.cpp
index 58b45140e..9af6eb774 100644
--- a/gfx/skia/skia/src/core/SkGeometry.cpp
+++ b/gfx/skia/skia/src/core/SkGeometry.cpp
@@ -62,6 +62,15 @@ static int valid_unit_divide(SkScalar numer, SkScalar denom, SkScalar* ratio) {
return 1;
}
+// Just returns its argument, but makes it easy to set a break-point to know when
+// SkFindUnitQuadRoots is going to return 0 (an error).
+static int return_check_zero(int value) {
+ if (value == 0) {
+ return 0;
+ }
+ return value;
+}
+
/** From Numerical Recipes in C.
Q = -1/2 (B + sign(B) sqrt[B*B - 4*A*C])
@@ -72,22 +81,21 @@ int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]) {
SkASSERT(roots);
if (A == 0) {
- return valid_unit_divide(-C, B, roots);
+ return return_check_zero(valid_unit_divide(-C, B, roots));
}
SkScalar* r = roots;
- SkScalar R = B*B - 4*A*C;
- if (R < 0 || !SkScalarIsFinite(R)) { // complex roots
- // if R is infinite, it's possible that it may still produce
- // useful results if the operation was repeated in doubles
- // the flipside is determining if the more precise answer
- // isn't useful because surrounding machinery (e.g., subtracting
- // the axis offset from C) already discards the extra precision
- // more investigation and unit tests required...
- return 0;
+ // use doubles so we don't overflow temporarily trying to compute R
+ double dr = (double)B * B - 4 * (double)A * C;
+ if (dr < 0) {
+ return return_check_zero(0);
+ }
+ dr = sqrt(dr);
+ SkScalar R = SkDoubleToScalar(dr);
+ if (!SkScalarIsFinite(R)) {
+ return return_check_zero(0);
}
- R = SkScalarSqrt(R);
SkScalar Q = (B < 0) ? -(B-R)/2 : -(B+R)/2;
r += valid_unit_divide(Q, A, r);
@@ -98,7 +106,7 @@ int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]) {
else if (roots[0] == roots[1]) // nearly-equal?
r -= 1; // skip the double root
}
- return (int)(r - roots);
+ return return_check_zero((int)(r - roots));
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/gfx/skia/skia/src/core/SkPath.cpp b/gfx/skia/skia/src/core/SkPath.cpp
index a2ef54620..fc3db3ee5 100644
--- a/gfx/skia/skia/src/core/SkPath.cpp
+++ b/gfx/skia/skia/src/core/SkPath.cpp
@@ -14,6 +14,7 @@
#include "SkPathPriv.h"
#include "SkPathRef.h"
#include "SkRRect.h"
+#include "SkTLazy.h"
////////////////////////////////////////////////////////////////////////////
@@ -715,9 +716,11 @@ void SkPath::setConvexity(Convexity c) {
fFirstDirection = SkPathPriv::kUnknown_FirstDirection; \
} while (0)
-void SkPath::incReserve(U16CPU inc) {
+void SkPath::incReserve(int inc) {
SkDEBUGCODE(this->validate();)
- SkPathRef::Editor(&fPathRef, inc, inc);
+ if (inc > 0) {
+ SkPathRef::Editor(&fPathRef, inc, inc);
+ }
SkDEBUGCODE(this->validate();)
}
@@ -1491,10 +1494,17 @@ void SkPath::addPath(const SkPath& path, SkScalar dx, SkScalar dy, AddPathMode m
this->addPath(path, matrix, mode);
}
-void SkPath::addPath(const SkPath& path, const SkMatrix& matrix, AddPathMode mode) {
- SkPathRef::Editor(&fPathRef, path.countVerbs(), path.countPoints());
+void SkPath::addPath(const SkPath& srcPath, const SkMatrix& matrix, AddPathMode mode) {
+ // Detect if we're trying to add ourself
+ const SkPath* src = &srcPath;
+ SkTLazy<SkPath> tmp;
+ if (this == src) {
+ src = tmp.set(srcPath);
+ }
+
+ SkPathRef::Editor(&fPathRef, src->countVerbs(), src->countPoints());
- RawIter iter(path);
+ RawIter iter(*src);
SkPoint pts[4];
Verb verb;
@@ -1602,14 +1612,21 @@ void SkPath::reversePathTo(const SkPath& path) {
}
}
-void SkPath::reverseAddPath(const SkPath& src) {
- SkPathRef::Editor ed(&fPathRef, src.fPathRef->countPoints(), src.fPathRef->countVerbs());
+void SkPath::reverseAddPath(const SkPath& srcPath) {
+ // Detect if we're trying to add ourself
+ const SkPath* src = &srcPath;
+ SkTLazy<SkPath> tmp;
+ if (this == src) {
+ src = tmp.set(srcPath);
+ }
+
+ SkPathRef::Editor ed(&fPathRef, src->fPathRef->countPoints(), src->fPathRef->countVerbs());
- const SkPoint* pts = src.fPathRef->pointsEnd();
+ const SkPoint* pts = src->fPathRef->pointsEnd();
// we will iterator through src's verbs backwards
- const uint8_t* verbs = src.fPathRef->verbsMemBegin(); // points at the last verb
- const uint8_t* verbsEnd = src.fPathRef->verbs(); // points just past the first verb
- const SkScalar* conicWeights = src.fPathRef->conicWeightsEnd();
+ const uint8_t* verbs = src->fPathRef->verbsMemBegin(); // points at the last verb
+ const uint8_t* verbsEnd = src->fPathRef->verbs(); // points just past the first verb
+ const SkScalar* conicWeights = src->fPathRef->conicWeightsEnd();
bool needMove = true;
bool needClose = false;
@@ -1727,7 +1744,7 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const {
if (this != dst) {
dst->fFillType = fFillType;
- dst->fConvexity = fConvexity;
+ dst->fConvexity = kUnknown_Convexity;
dst->fIsVolatile = fIsVolatile;
}
diff --git a/gfx/skia/skia/src/core/SkRRect.cpp b/gfx/skia/skia/src/core/SkRRect.cpp
index 1188989cd..f4308debe 100644
--- a/gfx/skia/skia/src/core/SkRRect.cpp
+++ b/gfx/skia/skia/src/core/SkRRect.cpp
@@ -161,6 +161,19 @@ void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) {
this->scaleRadii();
}
+// If we can't distinguish one of the radii relative to the other, force it to zero so it
+// doesn't confuse us later. See crbug.com/850350
+//
+static void flush_to_zero(SkScalar& a, SkScalar& b) {
+ SkASSERT(a >= 0);
+ SkASSERT(b >= 0);
+ if (a + b == a) {
+ b = 0;
+ } else if (a + b == b) {
+ a = 0;
+ }
+}
+
void SkRRect::scaleRadii() {
// Proportionally scale down all radii to fit. Find the minimum ratio
@@ -183,6 +196,11 @@ void SkRRect::scaleRadii() {
scale = compute_min_scale(fRadii[2].fX, fRadii[3].fX, width, scale);
scale = compute_min_scale(fRadii[3].fY, fRadii[0].fY, height, scale);
+ flush_to_zero(fRadii[0].fX, fRadii[1].fX);
+ flush_to_zero(fRadii[1].fY, fRadii[2].fY);
+ flush_to_zero(fRadii[2].fX, fRadii[3].fX);
+ flush_to_zero(fRadii[3].fY, fRadii[0].fY);
+
if (scale < 1.0) {
SkScaleToSides::AdjustRadii(width, scale, &fRadii[0].fX, &fRadii[1].fX);
SkScaleToSides::AdjustRadii(height, scale, &fRadii[1].fY, &fRadii[2].fY);
diff --git a/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp b/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp
index 993e1c59d..c6097b03b 100644
--- a/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp
+++ b/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp
@@ -152,13 +152,18 @@ void* GrBufferAllocPool::makeSpace(size_t size,
BufferBlock& back = fBlocks.back();
size_t usedBytes = back.fBuffer->gpuMemorySize() - back.fBytesFree;
size_t pad = GrSizeAlignUpPad(usedBytes, alignment);
- if ((size + pad) <= back.fBytesFree) {
+ SkSafeMath safeMath;
+ size_t alignedSize = safeMath.add(pad, size);
+ if (!safeMath.ok()) {
+ return nullptr;
+ }
+ if (alignedSize <= back.fBytesFree) {
memset((void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes), 0, pad);
usedBytes += pad;
*offset = usedBytes;
*buffer = back.fBuffer;
- back.fBytesFree -= size + pad;
- fBytesInUse += size + pad;
+ back.fBytesFree -= alignedSize;
+ fBytesInUse += alignedSize;
VALIDATE();
return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
}