Revert "ccpr: Implement stroking with fine triangle strips"

This reverts commit 2f2757fa6ba8134330e05694d08907f6e37abb41.

Reason for revert: issues with DDL

Original change's description:
> ccpr: Implement stroking with fine triangle strips
> 
> Implements strokes by linearizing the curve into fine triangle strips
> and interpolating a coverage ramp for edge AA. Each triangle in the
> strip emits either positive or negative coverage, depending on its
> winding direction. Joins and caps are drawn with the existing CCPR
> shaders for triangles and conics.
> 
> Conic strokes and non-rigid-body transforms are not yet supported.
> 
> Bug: skia:
> Change-Id: I45a819abd64e91c2b62e992587eb85c703e09e77
> Reviewed-on: https://skia-review.googlesource.com/148243
> Commit-Queue: Chris Dalton <csmartdalton@google.com>
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Reviewed-by: Allan MacKinnon <allanmac@google.com>

TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com,caryclark@google.com,csmartdalton@google.com,reed@google.com,allanmac@google.com

Change-Id: I1980b09976df8275817eaffb6766dbd9fd3e59c7
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/150980
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.cpp b/src/gpu/ccpr/GrCCDrawPathsOp.cpp
index 2ec8379..aed0672 100644
--- a/src/gpu/ccpr/GrCCDrawPathsOp.cpp
+++ b/src/gpu/ccpr/GrCCDrawPathsOp.cpp
@@ -28,82 +28,25 @@
     return sk_64_mul(r.height(), r.width());
 }
 
-std::unique_ptr<GrCCDrawPathsOp> GrCCDrawPathsOp::Make(
-        GrContext* context, const SkIRect& clipIBounds, const SkMatrix& m, const GrShape& shape,
-        GrPaint&& paint) {
-    static constexpr int kPathCropThreshold = GrCoverageCountingPathRenderer::kPathCropThreshold;
-
-    SkRect conservativeDevBounds;
-    m.mapRect(&conservativeDevBounds, shape.bounds());
-
-    const SkStrokeRec& stroke = shape.style().strokeRec();
-    float strokeDevWidth = 0;
-    float conservativeInflationRadius = 0;
-    if (!stroke.isFillStyle()) {
-        if (stroke.isHairlineStyle()) {
-            strokeDevWidth = 1;
-        } else {
-            SkASSERT(m.isSimilarity());  // Otherwise matrixScaleFactor = m.getMaxScale().
-            float matrixScaleFactor = SkVector::Length(m.getScaleX(), m.getSkewY());
-            strokeDevWidth = stroke.getWidth() * matrixScaleFactor;
-        }
-        // Inflate for a minimum stroke width of 1. In some cases when the stroke is less than 1px
-        // wide, we may inflate it to 1px and instead reduce the opacity.
-        conservativeInflationRadius = SkStrokeRec::GetInflationRadius(
-                stroke.getJoin(), stroke.getMiter(), stroke.getCap(), SkTMax(strokeDevWidth, 1.f));
-        conservativeDevBounds.outset(conservativeInflationRadius, conservativeInflationRadius);
-    }
-
-    std::unique_ptr<GrCCDrawPathsOp> op;
-    float conservativeSize = SkTMax(conservativeDevBounds.height(), conservativeDevBounds.width());
-    if (conservativeSize > kPathCropThreshold) {
-        // The path is too large. Crop it or analytic AA can run out of fp32 precision.
-        SkPath croppedDevPath;
-        shape.asPath(&croppedDevPath);
-        croppedDevPath.transform(m, &croppedDevPath);
-
-        SkIRect cropBox = clipIBounds;
-        GrShape croppedDevShape;
-        if (stroke.isFillStyle()) {
-            GrCoverageCountingPathRenderer::CropPath(croppedDevPath, cropBox, &croppedDevPath);
-            croppedDevShape = GrShape(croppedDevPath);
-            conservativeDevBounds = croppedDevShape.bounds();
-        } else {
-            int r = SkScalarCeilToInt(conservativeInflationRadius);
-            cropBox.outset(r, r);
-            GrCoverageCountingPathRenderer::CropPath(croppedDevPath, cropBox, &croppedDevPath);
-            SkStrokeRec devStroke = stroke;
-            devStroke.setStrokeStyle(strokeDevWidth);
-            croppedDevShape = GrShape(croppedDevPath, GrStyle(devStroke, nullptr));
-            conservativeDevBounds = croppedDevPath.getBounds();
-            conservativeDevBounds.outset(conservativeInflationRadius, conservativeInflationRadius);
-        }
-
-        // FIXME: This breaks local coords: http://skbug.com/8003
-        return InternalMake(context, clipIBounds, SkMatrix::I(), croppedDevShape, strokeDevWidth,
-                            conservativeDevBounds, std::move(paint));
-    }
-
-    return InternalMake(context, clipIBounds, m, shape, strokeDevWidth, conservativeDevBounds,
-                        std::move(paint));
-}
-
-std::unique_ptr<GrCCDrawPathsOp> GrCCDrawPathsOp::InternalMake(
-        GrContext* context, const SkIRect& clipIBounds, const SkMatrix& m, const GrShape& shape,
-        float strokeDevWidth, const SkRect& conservativeDevBounds, GrPaint&& paint) {
-    SkIRect shapeConservativeIBounds;
-    conservativeDevBounds.roundOut(&shapeConservativeIBounds);
+std::unique_ptr<GrCCDrawPathsOp> GrCCDrawPathsOp::Make(GrContext* context,
+                                                       const SkIRect& clipIBounds,
+                                                       const SkMatrix& m,
+                                                       const GrShape& shape,
+                                                       const SkRect& devBounds,
+                                                       GrPaint&& paint) {
+    SkIRect shapeDevIBounds;
+    devBounds.roundOut(&shapeDevIBounds);  // GrCCPathParser might find slightly tighter bounds.
 
     SkIRect maskDevIBounds;
     Visibility maskVisibility;
-    if (clipIBounds.contains(shapeConservativeIBounds)) {
-        maskDevIBounds = shapeConservativeIBounds;
+    if (clipIBounds.contains(shapeDevIBounds)) {
+        maskDevIBounds = shapeDevIBounds;
         maskVisibility = Visibility::kComplete;
     } else {
-        if (!maskDevIBounds.intersect(clipIBounds, shapeConservativeIBounds)) {
+        if (!maskDevIBounds.intersect(clipIBounds, shapeDevIBounds)) {
             return nullptr;
         }
-        int64_t unclippedArea = area(shapeConservativeIBounds);
+        int64_t unclippedArea = area(shapeDevIBounds);
         int64_t clippedArea = area(maskDevIBounds);
         maskVisibility = (clippedArea >= unclippedArea/2 || unclippedArea < 100*100)
                 ? Visibility::kMostlyComplete  // i.e., visible enough to justify rendering the
@@ -113,24 +56,22 @@
 
     GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
 
-    return pool->allocate<GrCCDrawPathsOp>(m, shape, strokeDevWidth, shapeConservativeIBounds,
-                                           maskDevIBounds, maskVisibility, conservativeDevBounds,
-                                           std::move(paint));
+    return pool->allocate<GrCCDrawPathsOp>(m, shape, shapeDevIBounds, maskDevIBounds,
+                                           maskVisibility, devBounds, std::move(paint));
 }
 
-GrCCDrawPathsOp::GrCCDrawPathsOp(const SkMatrix& m, const GrShape& shape, float strokeDevWidth,
-                                 const SkIRect& shapeConservativeIBounds,
-                                 const SkIRect& maskDevIBounds, Visibility maskVisibility,
-                                 const SkRect& conservativeDevBounds, GrPaint&& paint)
+GrCCDrawPathsOp::GrCCDrawPathsOp(const SkMatrix& m, const GrShape& shape,
+                                 const SkIRect& shapeDevIBounds, const SkIRect& maskDevIBounds,
+                                 Visibility maskVisibility, const SkRect& devBounds,
+                                 GrPaint&& paint)
         : GrDrawOp(ClassID())
         , fViewMatrixIfUsingLocalCoords(has_coord_transforms(paint) ? m : SkMatrix::I())
-        , fDraws(m, shape, strokeDevWidth, shapeConservativeIBounds, maskDevIBounds, maskVisibility,
-                 paint.getColor())
+        , fDraws(m, shape, shapeDevIBounds, maskDevIBounds, maskVisibility, paint.getColor())
         , fProcessors(std::move(paint)) {  // Paint must be moved after fetching its color above.
     SkDEBUGCODE(fBaseInstance = -1);
     // FIXME: intersect with clip bounds to (hopefully) improve batching.
     // (This is nontrivial due to assumptions in generating the octagon cover geometry.)
-    this->setBounds(conservativeDevBounds, GrOp::HasAABloat::kYes, GrOp::IsZeroArea::kNo);
+    this->setBounds(devBounds, GrOp::HasAABloat::kYes, GrOp::IsZeroArea::kNo);
 }
 
 GrCCDrawPathsOp::~GrCCDrawPathsOp() {
@@ -141,14 +82,12 @@
 }
 
 GrCCDrawPathsOp::SingleDraw::SingleDraw(const SkMatrix& m, const GrShape& shape,
-                                        float strokeDevWidth,
-                                        const SkIRect& shapeConservativeIBounds,
+                                        const SkIRect& shapeDevIBounds,
                                         const SkIRect& maskDevIBounds, Visibility maskVisibility,
                                         GrColor color)
         : fMatrix(m)
         , fShape(shape)
-        , fStrokeDevWidth(strokeDevWidth)
-        , fShapeConservativeIBounds(shapeConservativeIBounds)
+        , fShapeDevIBounds(shapeDevIBounds)
         , fMaskDevIBounds(maskDevIBounds)
         , fMaskVisibility(maskVisibility)
         , fColor(color) {
@@ -172,39 +111,9 @@
 GrDrawOp::RequiresDstTexture GrCCDrawPathsOp::finalize(const GrCaps& caps,
                                                        const GrAppliedClip* clip) {
     SkASSERT(1 == fNumDraws);  // There should only be one single path draw in this Op right now.
-    SingleDraw* draw = &fDraws.head();
-
-    const GrProcessorSet::Analysis& analysis = fProcessors.finalize(
-            draw->fColor, GrProcessorAnalysisCoverage::kSingleChannel, clip, false, caps,
-            &draw->fColor);
-
-    // Lines start looking jagged when they get thinner than 1px. For thin strokes it looks better
-    // if we can convert them to hairline (i.e., inflate the stroke width to 1px), and instead
-    // reduce the opacity to create the illusion of thin-ness. This strategy also helps reduce
-    // artifacts from coverage dilation when there are self intersections.
-    if (analysis.isCompatibleWithCoverageAsAlpha() &&
-            !draw->fShape.style().strokeRec().isFillStyle() && draw->fStrokeDevWidth < 1) {
-        // Modifying the shape affects its cache key. The draw can't have a cache entry yet or else
-        // our next step would invalidate it.
-        SkASSERT(!draw->fCacheEntry);
-        SkASSERT(SkStrokeRec::kStroke_Style == draw->fShape.style().strokeRec().getStyle());
-
-        SkPath path;
-        draw->fShape.asPath(&path);
-
-        // Create a hairline version of our stroke.
-        SkStrokeRec hairlineStroke = draw->fShape.style().strokeRec();
-        hairlineStroke.setStrokeStyle(0);
-
-        // How transparent does a 1px stroke have to be in order to appear as thin as the real one?
-        GrColor coverageAsAlpha = GrColorPackA4(SkScalarFloorToInt(draw->fStrokeDevWidth * 255));
-
-        draw->fShape = GrShape(path, GrStyle(hairlineStroke, nullptr));
-        draw->fStrokeDevWidth = 1;
-        // fShapeConservativeIBounds already accounted for this possibility of inflating the stroke.
-        draw->fColor = GrColorMul(draw->fColor, coverageAsAlpha);
-    }
-
+    GrProcessorSet::Analysis analysis =
+            fProcessors.finalize(fDraws.head().fColor, GrProcessorAnalysisCoverage::kSingleChannel,
+                                 clip, false, caps, &fDraws.head().fColor);
     return RequiresDstTexture(analysis.requiresDstTexture());
 }
 
@@ -271,11 +180,8 @@
                 // can copy it into a new 8-bit atlas and keep it in the resource cache.
                 if (stashedAtlasKey.isValid() && stashedAtlasKey == cacheEntry->atlasKey()) {
                     SkASSERT(!cacheEntry->hasCachedAtlas());
-                    int idx = (draw.fShape.style().strokeRec().isFillStyle())
-                            ? GrCCPerFlushResourceSpecs::kFillIdx
-                            : GrCCPerFlushResourceSpecs::kStrokeIdx;
-                    ++specs->fNumCopiedPaths[idx];
-                    specs->fCopyPathStats[idx].statPath(path);
+                    ++specs->fNumCopiedPaths;
+                    specs->fCopyPathStats.statPath(path);
                     specs->fCopyAtlasSpecs.accountForSpace(cacheEntry->width(),
                                                            cacheEntry->height());
                     continue;
@@ -285,23 +191,18 @@
                 cacheEntry->resetAtlasKeyAndInfo();
             }
 
-            if (Visibility::kMostlyComplete == draw.fMaskVisibility && cacheEntry->hitCount() > 1) {
-                int shapeSize = SkTMax(draw.fShapeConservativeIBounds.height(),
-                                       draw.fShapeConservativeIBounds.width());
-                if (shapeSize <= onFlushRP->caps()->maxRenderTargetSize()) {
-                    // We've seen this path before with a compatible matrix, and it's mostly
-                    // visible. Just render the whole mask so we can try to cache it.
-                    draw.fMaskDevIBounds = draw.fShapeConservativeIBounds;
-                    draw.fMaskVisibility = Visibility::kComplete;
-                }
+            if (Visibility::kMostlyComplete == draw.fMaskVisibility && cacheEntry->hitCount() > 1 &&
+                SkTMax(draw.fShapeDevIBounds.height(),
+                       draw.fShapeDevIBounds.width()) <= onFlushRP->caps()->maxRenderTargetSize()) {
+                // We've seen this path before with a compatible matrix, and it's mostly visible.
+                // Just render the whole mask so we can try to cache it.
+                draw.fMaskDevIBounds = draw.fShapeDevIBounds;
+                draw.fMaskVisibility = Visibility::kComplete;
             }
         }
 
-        int idx = (draw.fShape.style().strokeRec().isFillStyle())
-                ? GrCCPerFlushResourceSpecs::kFillIdx
-                : GrCCPerFlushResourceSpecs::kStrokeIdx;
-        ++specs->fNumRenderedPaths[idx];
-        specs->fRenderedPathStats[idx].statPath(path);
+        ++specs->fNumRenderedPaths;
+        specs->fRenderedPathStats.statPath(path);
         specs->fRenderedAtlasSpecs.accountForSpace(draw.fMaskDevIBounds.width(),
                                                    draw.fMaskDevIBounds.height());
     }
@@ -318,8 +219,7 @@
         SkPath path;
         draw.fShape.asPath(&path);
 
-        auto doEvenOddFill = DoEvenOddFill(draw.fShape.style().strokeRec().isFillStyle() &&
-                                           SkPath::kEvenOdd_FillType == path.getFillType());
+        auto doEvenOddFill = DoEvenOddFill(SkPath::kEvenOdd_FillType == path.getFillType());
         SkASSERT(SkPath::kEvenOdd_FillType == path.getFillType() ||
                  SkPath::kWinding_FillType == path.getFillType());
 
@@ -370,9 +270,9 @@
         SkRect devBounds, devBounds45;
         SkIRect devIBounds;
         SkIVector devToAtlasOffset;
-        if (auto atlas = resources->renderShapeInAtlas(
-                    draw.fMaskDevIBounds, draw.fMatrix, draw.fShape, draw.fStrokeDevWidth,
-                    &devBounds, &devBounds45, &devIBounds, &devToAtlasOffset)) {
+        if (auto atlas = resources->renderPathInAtlas(draw.fMaskDevIBounds, draw.fMatrix, path,
+                                                      &devBounds, &devBounds45, &devIBounds,
+                                                      &devToAtlasOffset)) {
             this->recordInstance(atlas->textureProxy(), resources->nextPathInstanceIdx());
             resources->appendDrawPathInstance().set(devBounds, devBounds45, devToAtlasOffset,
                                                     draw.fColor, doEvenOddFill);