diff options
author | Chris Dalton <csmartdalton@google.com> | 2018-03-08 22:41:33 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-03-09 16:23:50 +0000 |
commit | ad06544cc6ac4b403a24adda4ee36b9f35b3071f (patch) | |
tree | 8dccf3de53d2c4a06c29d87fe2395f9d4c38f864 /src/gpu | |
parent | c2ef4ab423b0cc456425de1f0161e24980652db6 (diff) |
ccpr: Fix crash on zero-length fan tessellations
Hardens the path parser to handle zero-length fan tessellations. In this
case the vertex pointer returned by the tessellator will be null, so we
need to indicate whether a tessellation exists in a different way.
Bug: skia:7642
Change-Id: If29df9d08565ff613059f2d3b49ab4eb79908495
Reviewed-on: https://skia-review.googlesource.com/113362
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/ccpr/GrCCPathParser.cpp | 15 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPathParser.h | 29 |
2 files changed, 33 insertions, 11 deletions
diff --git a/src/gpu/ccpr/GrCCPathParser.cpp b/src/gpu/ccpr/GrCCPathParser.cpp index 43f5e6be6a..fd0b71da29 100644 --- a/src/gpu/ccpr/GrCCPathParser.cpp +++ b/src/gpu/ccpr/GrCCPathParser.cpp @@ -240,8 +240,7 @@ void GrCCPathParser::saveParsedPath(ScissorMode scissorMode, const SkIRect& clip } } - fPathsInfo.back().fFanTessellation.reset(vertices); - fPathsInfo.back().fFanTessellationCount = count; + fPathsInfo.back().adoptFanTessellation(vertices, count); } fTotalPrimitiveCounts[(int)scissorMode] += fCurrPathPrimitiveCounts; @@ -408,14 +407,14 @@ bool GrCCPathParser::finalize(GrOnFlushResourceProvider* onFlushRP) { switch (verb) { case GrCCGeometry::Verb::kBeginPath: SkASSERT(currFan.empty()); - currIndices = &instanceIndices[(int)nextPathInfo->fScissorMode]; - atlasOffsetX = static_cast<float>(nextPathInfo->fAtlasOffsetX); - atlasOffsetY = static_cast<float>(nextPathInfo->fAtlasOffsetY); + currIndices = &instanceIndices[(int)nextPathInfo->scissorMode()]; + atlasOffsetX = static_cast<float>(nextPathInfo->atlasOffsetX()); + atlasOffsetY = static_cast<float>(nextPathInfo->atlasOffsetY()); atlasOffset = {atlasOffsetX, atlasOffsetY}; - currFanIsTessellated = nextPathInfo->fFanTessellation.get(); + currFanIsTessellated = nextPathInfo->hasFanTessellation(); if (currFanIsTessellated) { - emit_tessellated_fan(nextPathInfo->fFanTessellation.get(), - nextPathInfo->fFanTessellationCount, atlasOffset, + emit_tessellated_fan(nextPathInfo->fanTessellation(), + nextPathInfo->fanTessellationCount(), atlasOffset, triPointInstanceData, quadPointInstanceData, currIndices); } ++nextPathInfo; diff --git a/src/gpu/ccpr/GrCCPathParser.h b/src/gpu/ccpr/GrCCPathParser.h index d8d897f6d5..b1a1ee5906 100644 --- a/src/gpu/ccpr/GrCCPathParser.h +++ b/src/gpu/ccpr/GrCCPathParser.h @@ -76,14 +76,37 @@ private: using PrimitiveTallies = GrCCGeometry::PrimitiveTallies; // Every kBeginPath verb has a corresponding PathInfo entry. - struct PathInfo { + class PathInfo { + public: PathInfo(ScissorMode scissorMode, int16_t offsetX, int16_t offsetY) : fScissorMode(scissorMode), fAtlasOffsetX(offsetX), fAtlasOffsetY(offsetY) {} + ScissorMode scissorMode() const { return fScissorMode; } + int16_t atlasOffsetX() const { return fAtlasOffsetX; } + int16_t atlasOffsetY() const { return fAtlasOffsetY; } + + // An empty tessellation fan is also valid; we use negative count to denote not tessellated. + bool hasFanTessellation() const { return fFanTessellationCount >= 0; } + int fanTessellationCount() const { + SkASSERT(this->hasFanTessellation()); + return fFanTessellationCount; + } + const GrTessellator::WindingVertex* fanTessellation() const { + SkASSERT(this->hasFanTessellation()); + return fFanTessellation.get(); + } + + void adoptFanTessellation(const GrTessellator::WindingVertex* vertices, int count) { + SkASSERT(count >= 0); + fFanTessellation.reset(vertices); + fFanTessellationCount = count; + } + + private: ScissorMode fScissorMode; int16_t fAtlasOffsetX, fAtlasOffsetY; - std::unique_ptr<GrTessellator::WindingVertex[]> fFanTessellation; - int fFanTessellationCount = 0; + int fFanTessellationCount = -1; + std::unique_ptr<const GrTessellator::WindingVertex[]> fFanTessellation; }; // Defines a batch of CCPR primitives. Start indices are deduced by looking at the previous |