Chromium Code Reviews| Index: src/gpu/batches/GrPLSPathRenderer.cpp |
| diff --git a/src/gpu/batches/GrPLSPathRenderer.cpp b/src/gpu/batches/GrPLSPathRenderer.cpp |
| index ba84d73a7b1810ca41c9875f36855ca340c97d03..7cafe020e09aab6858f81c77925e63384d211827 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,135 @@ 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(); |
|
robertphillips
2016/06/30 16:58:27
SkRect bounds;
this->bounds()->roundOut(&bounds);
bsalomon
2016/06/30 17:33:58
Done.
|
| - 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(); |
| + 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 = &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 +948,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 +968,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 |