Index: src/gpu/batches/GrPLSPathRenderer.cpp |
diff --git a/src/gpu/batches/GrPLSPathRenderer.cpp b/src/gpu/batches/GrPLSPathRenderer.cpp |
index ba84d73a7b1810ca41c9875f36855ca340c97d03..c373979bb58e163db0b6618480b6857ed9e7dc0f 100644 |
--- a/src/gpu/batches/GrPLSPathRenderer.cpp |
+++ b/src/gpu/batches/GrPLSPathRenderer.cpp |
@@ -787,14 +787,14 @@ bool GrPLSPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { |
class PLSPathBatch : public GrVertexBatch { |
public: |
DEFINE_BATCH_CLASS_ID |
- struct Geometry { |
- GrColor fColor; |
- SkMatrix fViewMatrix; |
- SkPath fPath; |
- }; |
- |
- static GrDrawBatch* Create(const Geometry& geometry) { |
- return new PLSPathBatch(geometry); |
+ PLSPathBatch(GrColor color, const SkPath& path, const SkMatrix& viewMatrix) |
+ : INHERITED(ClassID()) |
+ , fColor(color) |
+ , fPath(path) |
+ , fViewMatrix(viewMatrix) { |
+ // compute bounds |
+ fBounds = path.getBounds(); |
+ fViewMatrix.mapRect(&fBounds); |
} |
const char* name() const override { return "PLSBatch"; } |
@@ -803,7 +803,7 @@ public: |
GrInitInvariantOutput* coverage, |
GrBatchToXPOverrides* overrides) const override { |
// When this is called on a batch, there is only one geometry bundle |
- color->setKnownFourComponents(fGeoData[0].fColor); |
+ color->setKnownFourComponents(fColor); |
coverage->setUnknownSingleComponent(); |
overrides->fUsePLSDstRead = true; |
} |
@@ -811,166 +811,132 @@ public: |
void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
// Handle any color overrides |
if (!overrides.readsColor()) { |
- fGeoData[0].fColor = GrColor_ILLEGAL; |
+ fColor = GrColor_ILLEGAL; |
} |
- overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
+ overrides.getOverrideColorIfSet(&fColor); |
// setup batch properties |
- fBatch.fColorIgnored = !overrides.readsColor(); |
- fBatch.fColor = fGeoData[0].fColor; |
- fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); |
- fBatch.fCoverageIgnored = !overrides.readsCoverage(); |
- fBatch.fCanTweakAlphaForCoverage = overrides.canTweakAlphaForCoverage(); |
+ fUsesLocalCoords = overrides.readsLocalCoords(); |
} |
void onPrepareDraws(Target* target) const override { |
- int instanceCount = fGeoData.count(); |
SkMatrix invert; |
- if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { |
+ if (fUsesLocalCoords && !fViewMatrix.invert(&invert)) { |
SkDebugf("Could not invert viewmatrix\n"); |
return; |
} |
// Setup GrGeometryProcessors |
SkAutoTUnref<GrPLSGeometryProcessor> triangleProcessor( |
- PLSAATriangleEffect::Create(invert, this->usesLocalCoords())); |
+ PLSAATriangleEffect::Create(invert, fUsesLocalCoords)); |
SkAutoTUnref<GrPLSGeometryProcessor> quadProcessor( |
- PLSQuadEdgeEffect::Create(invert, this->usesLocalCoords())); |
+ PLSQuadEdgeEffect::Create(invert, fUsesLocalCoords)); |
GrResourceProvider* rp = target->resourceProvider(); |
- for (int i = 0; i < instanceCount; ++i) { |
- const Geometry& args = fGeoData[i]; |
- SkRect bounds = args.fPath.getBounds(); |
- args.fViewMatrix.mapRect(&bounds); |
- bounds.fLeft = SkScalarFloorToScalar(bounds.fLeft); |
- bounds.fTop = SkScalarFloorToScalar(bounds.fTop); |
- bounds.fRight = SkScalarCeilToScalar(bounds.fRight); |
- bounds.fBottom = SkScalarCeilToScalar(bounds.fBottom); |
- triangleProcessor->setBounds(bounds); |
- quadProcessor->setBounds(bounds); |
- |
- // We use the fact that SkPath::transform path does subdivision based on |
- // perspective. Otherwise, we apply the view matrix when copying to the |
- // segment representation. |
- const SkMatrix* viewMatrix = &args.fViewMatrix; |
- |
- // We avoid initializing the path unless we have to |
- const SkPath* pathPtr = &args.fPath; |
- SkTLazy<SkPath> tmpPath; |
- if (viewMatrix->hasPerspective()) { |
- SkPath* tmpPathPtr = tmpPath.init(*pathPtr); |
- tmpPathPtr->setIsVolatile(true); |
- tmpPathPtr->transform(*viewMatrix); |
- viewMatrix = &SkMatrix::I(); |
- pathPtr = tmpPathPtr; |
- } |
+ SkRect bounds; |
+ this->bounds().roundOut(&bounds); |
+ triangleProcessor->setBounds(bounds); |
+ quadProcessor->setBounds(bounds); |
+ |
+ // We use the fact that SkPath::transform path does subdivision based on |
+ // perspective. Otherwise, we apply the view matrix when copying to the |
+ // segment representation. |
+ const SkMatrix* viewMatrix = &fViewMatrix; |
+ |
+ // We avoid initializing the path unless we have to |
+ const SkPath* pathPtr = &fPath; |
+ SkTLazy<SkPath> tmpPath; |
+ if (viewMatrix->hasPerspective()) { |
+ SkPath* tmpPathPtr = tmpPath.init(*pathPtr); |
+ tmpPathPtr->setIsVolatile(true); |
+ tmpPathPtr->transform(*viewMatrix); |
+ viewMatrix = &SkMatrix::I(); |
+ pathPtr = tmpPathPtr; |
+ } |
- GrMesh mesh; |
+ GrMesh mesh; |
- PLSVertices triVertices; |
- PLSVertices quadVertices; |
- if (!get_geometry(*pathPtr, *viewMatrix, triVertices, quadVertices, rp, bounds)) { |
- continue; |
- } |
+ PLSVertices triVertices; |
+ PLSVertices quadVertices; |
+ if (!get_geometry(*pathPtr, *viewMatrix, triVertices, quadVertices, rp, bounds)) { |
+ return; |
+ } |
- if (triVertices.count()) { |
- const GrBuffer* triVertexBuffer; |
- int firstTriVertex; |
- size_t triStride = triangleProcessor->getVertexStride(); |
- PLSVertex* triVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace( |
- triStride, triVertices.count(), &triVertexBuffer, &firstTriVertex)); |
- if (!triVerts) { |
- SkDebugf("Could not allocate vertices\n"); |
- return; |
- } |
- for (int i = 0; i < triVertices.count(); ++i) { |
- triVerts[i] = triVertices[i]; |
- } |
- mesh.init(kTriangles_GrPrimitiveType, triVertexBuffer, firstTriVertex, |
- triVertices.count()); |
- target->draw(triangleProcessor, mesh); |
+ if (triVertices.count()) { |
+ const GrBuffer* triVertexBuffer; |
+ int firstTriVertex; |
+ size_t triStride = triangleProcessor->getVertexStride(); |
+ PLSVertex* triVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace( |
+ triStride, triVertices.count(), &triVertexBuffer, &firstTriVertex)); |
+ if (!triVerts) { |
+ SkDebugf("Could not allocate vertices\n"); |
+ return; |
} |
- |
- if (quadVertices.count()) { |
- const GrBuffer* quadVertexBuffer; |
- int firstQuadVertex; |
- size_t quadStride = quadProcessor->getVertexStride(); |
- PLSVertex* quadVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace( |
- quadStride, quadVertices.count(), &quadVertexBuffer, &firstQuadVertex)); |
- if (!quadVerts) { |
- SkDebugf("Could not allocate vertices\n"); |
- return; |
- } |
- for (int i = 0; i < quadVertices.count(); ++i) { |
- quadVerts[i] = quadVertices[i]; |
- } |
- mesh.init(kTriangles_GrPrimitiveType, quadVertexBuffer, firstQuadVertex, |
- quadVertices.count()); |
- target->draw(quadProcessor, mesh); |
+ for (int i = 0; i < triVertices.count(); ++i) { |
+ triVerts[i] = triVertices[i]; |
} |
+ mesh.init(kTriangles_GrPrimitiveType, triVertexBuffer, firstTriVertex, |
+ triVertices.count()); |
+ target->draw(triangleProcessor, mesh); |
+ } |
- SkAutoTUnref<GrGeometryProcessor> finishProcessor( |
- PLSFinishEffect::Create(this->color(), |
- pathPtr->getFillType() == |
- SkPath::FillType::kEvenOdd_FillType, |
- invert, |
- this->usesLocalCoords())); |
- const GrBuffer* rectVertexBuffer; |
- size_t finishStride = finishProcessor->getVertexStride(); |
- int firstRectVertex; |
- static const int kRectVertexCount = 6; |
- SkPoint* rectVerts = reinterpret_cast<SkPoint*>(target->makeVertexSpace( |
- finishStride, kRectVertexCount, &rectVertexBuffer, &firstRectVertex)); |
- if (!rectVerts) { |
+ if (quadVertices.count()) { |
+ const GrBuffer* quadVertexBuffer; |
+ int firstQuadVertex; |
+ size_t quadStride = quadProcessor->getVertexStride(); |
+ PLSVertex* quadVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace( |
+ quadStride, quadVertices.count(), &quadVertexBuffer, &firstQuadVertex)); |
+ if (!quadVerts) { |
SkDebugf("Could not allocate vertices\n"); |
return; |
} |
- rectVerts[0] = { bounds.fLeft, bounds.fTop }; |
- rectVerts[1] = { bounds.fLeft, bounds.fBottom }; |
- rectVerts[2] = { bounds.fRight, bounds.fBottom }; |
- rectVerts[3] = { bounds.fLeft, bounds.fTop }; |
- rectVerts[4] = { bounds.fRight, bounds.fTop }; |
- rectVerts[5] = { bounds.fRight, bounds.fBottom }; |
- |
- mesh.init(kTriangles_GrPrimitiveType, rectVertexBuffer, firstRectVertex, |
- kRectVertexCount); |
- target->draw(finishProcessor, mesh); |
+ for (int i = 0; i < quadVertices.count(); ++i) { |
+ quadVerts[i] = quadVertices[i]; |
+ } |
+ mesh.init(kTriangles_GrPrimitiveType, quadVertexBuffer, firstQuadVertex, |
+ quadVertices.count()); |
+ target->draw(quadProcessor, mesh); |
} |
- } |
- |
- SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
-private: |
- PLSPathBatch(const Geometry& geometry) : INHERITED(ClassID()) { |
- fGeoData.push_back(geometry); |
- |
- // compute bounds |
- fBounds = geometry.fPath.getBounds(); |
- geometry.fViewMatrix.mapRect(&fBounds); |
+ SkAutoTUnref<GrGeometryProcessor> finishProcessor( |
+ PLSFinishEffect::Create(fColor, |
+ pathPtr->getFillType() == |
+ SkPath::FillType::kEvenOdd_FillType, |
+ invert, |
+ fUsesLocalCoords)); |
+ const GrBuffer* rectVertexBuffer; |
+ size_t finishStride = finishProcessor->getVertexStride(); |
+ int firstRectVertex; |
+ static const int kRectVertexCount = 6; |
+ SkPoint* rectVerts = reinterpret_cast<SkPoint*>(target->makeVertexSpace( |
+ finishStride, kRectVertexCount, &rectVertexBuffer, &firstRectVertex)); |
+ if (!rectVerts) { |
+ SkDebugf("Could not allocate vertices\n"); |
+ return; |
+ } |
+ rectVerts[0] = { bounds.fLeft, bounds.fTop }; |
+ rectVerts[1] = { bounds.fLeft, bounds.fBottom }; |
+ rectVerts[2] = { bounds.fRight, bounds.fBottom }; |
+ rectVerts[3] = { bounds.fLeft, bounds.fTop }; |
+ rectVerts[4] = { bounds.fRight, bounds.fTop }; |
+ rectVerts[5] = { bounds.fRight, bounds.fBottom }; |
+ |
+ mesh.init(kTriangles_GrPrimitiveType, rectVertexBuffer, firstRectVertex, |
+ kRectVertexCount); |
+ target->draw(finishProcessor, mesh); |
} |
+private: |
bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
return false; |
} |
- GrColor color() const { return fBatch.fColor; } |
- bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
- bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; } |
- const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
- bool coverageIgnored() const { return fBatch.fCoverageIgnored; } |
- |
- struct BatchTracker { |
- GrColor fColor; |
- bool fUsesLocalCoords; |
- bool fColorIgnored; |
- bool fCoverageIgnored; |
- bool fCanTweakAlphaForCoverage; |
- }; |
- |
- BatchTracker fBatch; |
- SkSTArray<1, Geometry, true> fGeoData; |
+ bool fUsesLocalCoords; |
+ GrColor fColor; |
+ SkPath fPath; |
+ SkMatrix fViewMatrix; |
typedef GrVertexBatch INHERITED; |
}; |
@@ -979,12 +945,10 @@ bool GrPLSPathRenderer::onDrawPath(const DrawPathArgs& args) { |
SkASSERT(!args.fShape->isEmpty()) |
SkASSERT(!inPLSDraw); |
SkDEBUGCODE(inPLSDraw = true;) |
- PLSPathBatch::Geometry geometry; |
- geometry.fColor = args.fColor; |
- geometry.fViewMatrix = *args.fViewMatrix; |
- args.fShape->asPath(&geometry.fPath); |
+ SkPath path; |
+ args.fShape->asPath(&path); |
- SkAutoTUnref<GrDrawBatch> batch(PLSPathBatch::Create(geometry)); |
+ SkAutoTUnref<GrDrawBatch> batch(new PLSPathBatch(args.fColor, path, *args.fViewMatrix)); |
GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHWAA(*args.fPaint)); |
pipelineBuilder.setUserStencil(args.fUserStencilSettings); |
@@ -1001,12 +965,11 @@ bool GrPLSPathRenderer::onDrawPath(const DrawPathArgs& args) { |
#ifdef GR_TEST_UTILS |
DRAW_BATCH_TEST_DEFINE(PLSPathBatch) { |
- PLSPathBatch::Geometry geometry; |
- geometry.fColor = GrRandomColor(random); |
- geometry.fViewMatrix = GrTest::TestMatrixInvertible(random); |
- geometry.fPath = GrTest::TestPathConvex(random); |
+ GrColor color = GrRandomColor(random); |
+ SkMatrix vm = GrTest::TestMatrixInvertible(random); |
+ SkPath path = GrTest::TestPathConvex(random); |
- return PLSPathBatch::Create(geometry); |
+ return new PLSPathBatch(color, path, vm); |
} |
#endif |