Guard default path renderer against buffer allocation failure
Apparently the guarantee of buffer space has been refactored out from
underneath this class.
Bug: 1223365
Change-Id: I9beb9566a641933322bd946a5067eeafb9c4c013
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/422636
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp
index f9ced05..a1c122a 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.cpp
+++ b/src/gpu/ops/GrDefaultPathRenderer.cpp
@@ -88,7 +88,9 @@
* Path verbs
*/
void moveTo(const SkPoint& p) {
- this->needSpace(1);
+ if (!this->ensureSpace(1)) {
+ return;
+ }
if (!this->isHairline()) {
fSubpathIndexStart = this->currentIndex();
@@ -98,7 +100,9 @@
}
void addLine(const SkPoint pts[]) {
- this->needSpace(1, this->indexScale(), &pts[0]);
+ if (!this->ensureSpace(1, this->indexScale(), &pts[0])) {
+ return;
+ }
if (this->isIndexed()) {
uint16_t prevIdx = this->currentIndex() - 1;
@@ -108,9 +112,11 @@
}
void addQuad(const SkPoint pts[], SkScalar srcSpaceTolSqd, SkScalar srcSpaceTol) {
- this->needSpace(GrPathUtils::kMaxPointsPerCurve,
- GrPathUtils::kMaxPointsPerCurve * this->indexScale(),
- &pts[0]);
+ if (!this->ensureSpace(GrPathUtils::kMaxPointsPerCurve,
+ GrPathUtils::kMaxPointsPerCurve * this->indexScale(),
+ &pts[0])) {
+ return;
+ }
// First pt of quad is the pt we ended on in previous step
uint16_t firstQPtIdx = this->currentIndex() - 1;
@@ -134,9 +140,11 @@
}
void addCubic(const SkPoint pts[], SkScalar srcSpaceTolSqd, SkScalar srcSpaceTol) {
- this->needSpace(GrPathUtils::kMaxPointsPerCurve,
- GrPathUtils::kMaxPointsPerCurve * this->indexScale(),
- &pts[0]);
+ if (!this->ensureSpace(GrPathUtils::kMaxPointsPerCurve,
+ GrPathUtils::kMaxPointsPerCurve * this->indexScale(),
+ &pts[0])) {
+ return;
+ }
// First pt of cubic is the pt we ended on in previous step
uint16_t firstCPtIdx = this->currentIndex() - 1;
@@ -227,6 +235,8 @@
// Allocate vertex and (possibly) index buffers
void allocNewBuffers() {
+ SkASSERT(fValid);
+
// Ensure that we always get enough verts for a worst-case quad/cubic, plus leftover points
// from previous mesh piece (up to two verts to continue fanning). If we can't get that
// many, ask for a much larger number. This needs to be fairly big to handle quads/cubics,
@@ -240,6 +250,14 @@
&fVertexBuffer,
&fFirstVertex,
&fVerticesInChunk));
+ if (!fVertices) {
+ SkDebugf("WARNING: Failed to allocate vertex buffer for GrDefaultPathRenderer.\n");
+ fCurVert = nullptr;
+ fCurIdx = fIndices = nullptr;
+ fSubpathIndexStart = 0;
+ fValid = false;
+ return;
+ }
if (this->isIndexed()) {
// Similar to above: Ensure we get enough indices for one worst-case quad/cubic.
@@ -251,6 +269,11 @@
fIndices = fTarget->makeIndexSpaceAtLeast(kMinIndicesPerChunk, kFallbackIndicesPerChunk,
&fIndexBuffer, &fFirstIndex,
&fIndicesInChunk);
+ if (!fIndices) {
+ SkDebugf("WARNING: Failed to allocate index buffer for GrDefaultPathRenderer.\n");
+ fVertices = nullptr;
+ fValid = false;
+ }
}
fCurVert = fVertices;
@@ -259,6 +282,8 @@
}
void appendCountourEdgeIndices(uint16_t edgeV0Idx) {
+ SkASSERT(fCurIdx);
+
// When drawing lines we're appending line segments along the countour. When applying the
// other fill rules we're drawing triangle fans around the start of the current (sub)path.
if (!this->isHairline()) {
@@ -270,6 +295,10 @@
// Emits a single draw with all accumulated vertex/index data
void createMeshAndPutBackReserve() {
+ if (!fValid) {
+ return;
+ }
+
int vertexCount = fCurVert - fVertices;
int indexCount = fCurIdx - fIndices;
SkASSERT(vertexCount <= fVerticesInChunk);
@@ -295,7 +324,11 @@
}
}
- void needSpace(int vertsNeeded, int indicesNeeded = 0, const SkPoint* lastPoint = nullptr) {
+ bool ensureSpace(int vertsNeeded, int indicesNeeded = 0, const SkPoint* lastPoint = nullptr) {
+ if (!fValid) {
+ return false;
+ }
+
if (fCurVert + vertsNeeded > fVertices + fVerticesInChunk ||
fCurIdx + indicesNeeded > fIndices + fIndicesInChunk) {
// We are about to run out of space (possibly)
@@ -320,6 +353,9 @@
// Get new buffers
this->allocNewBuffers();
+ if (!fValid) {
+ return false;
+ }
// On moves we don't need to copy over any points to the new buffer and we pass in a
// null lastPoint.
@@ -331,6 +367,8 @@
*(fCurVert++) = *lastPoint;
}
}
+
+ return true;
}
GrPrimitiveType fPrimitiveType;
@@ -351,6 +389,7 @@
uint16_t fSubpathIndexStart;
SkPoint fSubpathStartPoint;
+ bool fValid = true;
SkTDArray<GrSimpleMesh*>* fMeshes;
};