| 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
|
|
|