Bump the max atlas path size to 256 for non-MSAA

When we don't have MSAA to fall back on (e.g., for clipping), we
benefit from allowing larger paths in the atlas.

Bug: skia:12258
Change-Id: I6decb7c5dd092b5e350e9f5701e05df5680a52f0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/432076
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/gpu/ops/GrAtlasPathRenderer.cpp b/src/gpu/ops/GrAtlasPathRenderer.cpp
index 4620bf3..42b7483 100644
--- a/src/gpu/ops/GrAtlasPathRenderer.cpp
+++ b/src/gpu/ops/GrAtlasPathRenderer.cpp
@@ -31,8 +31,12 @@
 // height, which lends very well to efficient pow2 atlas packing.
 constexpr static auto kAtlasAlgorithm = GrDynamicAtlas::RectanizerAlgorithm::kPow2;
 
-// Ensure every path in the atlas falls in or below the 128px high rectanizer band.
-constexpr static int kAtlasMaxPathHeight = 128;
+// Ensure every path in the atlas falls in or below the 256px high rectanizer band.
+constexpr static int kAtlasMaxPathHeight = 256;
+
+// If we have MSAA to fall back on, paths are already fast enough that we really only benefit from
+// atlasing when they are very small.
+constexpr static int kAtlasMaxPathHeightWithMSAAFallback = 128;
 
 bool GrAtlasPathRenderer::IsSupported(GrRecordingContext* rContext) {
     const GrCaps& caps = *rContext->priv().caps();
@@ -68,15 +72,20 @@
     return {skvx::floor(float2::Load(&r.fLeft)), skvx::ceil(float2::Load(&r.fRight))};
 }
 
-bool GrAtlasPathRenderer::pathFitsInAtlas(const SkRect& pathDevBounds) const {
+bool GrAtlasPathRenderer::pathFitsInAtlas(const SkRect& pathDevBounds,
+                                          GrAAType fallbackAAType) const {
+    SkASSERT(fallbackAAType != GrAAType::kNone);  // The atlas doesn't support non-AA.
+    float atlasMaxPathHeight_pow2 = (fallbackAAType == GrAAType::kMSAA)
+            ? kAtlasMaxPathHeightWithMSAAFallback * kAtlasMaxPathHeightWithMSAAFallback
+            : kAtlasMaxPathHeight * kAtlasMaxPathHeight;
     auto [topLeftFloor, botRightCeil] = round_out(pathDevBounds);
     float2 size = botRightCeil - topLeftFloor;
     return // Ensure the path's largest dimension fits in the atlas.
            skvx::all(size <= fAtlasMaxSize) &&
-           // Since we will transpose tall skinny paths, limiting to kAtlasMaxPathHeight^2 pixels
-           // guarantees heightInAtlas <= kAtlasMaxPathHeight, while also allowing paths that are
+           // Since we will transpose tall skinny paths, limiting to atlasMaxPathHeight^2 pixels
+           // guarantees heightInAtlas <= atlasMaxPathHeight, while also allowing paths that are
            // very wide and short.
-           size[0] * size[1] <= kAtlasMaxPathHeight * kAtlasMaxPathHeight;
+           size[0] * size[1] <= atlasMaxPathHeight_pow2;
 }
 
 void GrAtlasPathRenderer::AtlasPathKey::set(const SkMatrix& m, const SkPath& path) {
@@ -130,6 +139,7 @@
     if (*transposedInAtlas) {
         std::swap(heightInAtlas, widthInAtlas);
     }
+    // pathFitsInAtlas() should have guaranteed these constraints on the path size.
     SkASSERT(widthInAtlas <= (int)fAtlasMaxSize);
     SkASSERT(heightInAtlas <= kAtlasMaxPathHeight);
 
@@ -209,7 +219,8 @@
                        args.fAAType == GrAAType::kMSAA &&
                        !args.fShape->style().hasPathEffect() &&
                        !args.fViewMatrix->hasPerspective() &&
-                       this->pathFitsInAtlas(args.fViewMatrix->mapRect(args.fShape->bounds()));
+                       this->pathFitsInAtlas(args.fViewMatrix->mapRect(args.fShape->bounds()),
+                                             args.fAAType);
     return canDrawPath ? CanDrawPath::kYes : CanDrawPath::kNo;
 }
 
@@ -232,7 +243,7 @@
     args.fShape->asPath(&path);
 
     const SkRect pathDevBounds = args.fViewMatrix->mapRect(args.fShape->bounds());
-    SkASSERT(this->pathFitsInAtlas(pathDevBounds));
+    SkASSERT(this->pathFitsInAtlas(pathDevBounds, args.fAAType));
 
     if (!is_visible(pathDevBounds, args.fClip->getConservativeBounds())) {
         // The path is empty or outside the clip. No mask is needed.
@@ -267,7 +278,7 @@
     return true;
 }
 
-GrFPResult GrAtlasPathRenderer::makeAtlasClipEffect(GrRecordingContext* rContext,
+GrFPResult GrAtlasPathRenderer::makeAtlasClipEffect(const GrSurfaceDrawContext* sdc,
                                                     const GrOp* opBeingClipped,
                                                     std::unique_ptr<GrFragmentProcessor> inputFP,
                                                     const SkIRect& drawBounds,
@@ -284,7 +295,9 @@
                                         : GrFPFailure(std::move(inputFP));
     }
 
-    if (!this->pathFitsInAtlas(pathDevBounds)) {
+    auto fallbackAAType = (sdc->numSamples() > 1 || sdc->canUseDynamicMSAA()) ? GrAAType::kMSAA
+                                                                              : GrAAType::kCoverage;
+    if (!this->pathFitsInAtlas(pathDevBounds, fallbackAAType)) {
         // The path is too big.
         return GrFPFailure(std::move(inputFP));
     }
@@ -299,7 +312,7 @@
                refs_atlas(inputFP.get(), atlasProxy);
     };
     // addPathToAtlas() ignores inverseness of the fill. See GrAtlasRenderTask::getAtlasUberPath().
-    if (!this->addPathToAtlas(rContext, viewMatrix, path, pathDevBounds, &devIBounds,
+    if (!this->addPathToAtlas(sdc->recordingContext(), viewMatrix, path, pathDevBounds, &devIBounds,
                               &locationInAtlas, &transposedInAtlas, drawRefsAtlasCallback)) {
         // The atlas ran out of room and we were unable to start a new one.
         return GrFPFailure(std::move(inputFP));
@@ -325,7 +338,7 @@
         // ever changes.
         SkASSERT(path.isInverseFillType());
     }
-    GrSurfaceProxyView atlasView = fAtlasRenderTasks.back()->readView(*rContext->priv().caps());
+    GrSurfaceProxyView atlasView = fAtlasRenderTasks.back()->readView(*sdc->caps());
     return GrFPSuccess(std::make_unique<GrModulateAtlasCoverageEffect>(flags, std::move(inputFP),
                                                                        std::move(atlasView),
                                                                        atlasMatrix, devIBounds));