ccpr: Prefer atlas sizes under 4k on ARM

Bug: skia:
Change-Id: Ib5afb84647efe2e64a3ec2f9da422b39228431e9
Reviewed-on: https://skia-review.googlesource.com/108871
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp
index 97b28fb..ce5cddb 100644
--- a/src/gpu/ccpr/GrCCAtlas.cpp
+++ b/src/gpu/ccpr/GrCCAtlas.cpp
@@ -18,6 +18,9 @@
 #include "ccpr/GrCCPathParser.h"
 #include "ops/GrDrawOp.h"
 
+static constexpr int kAtlasMinSize = 1024;
+static constexpr int kPadding = 1;
+
 class GrCCAtlas::Node {
 public:
     Node(std::unique_ptr<Node> previous, int l, int t, int r, int b)
@@ -25,10 +28,15 @@
 
     Node* previous() const { return fPrevious.get(); }
 
-    bool addRect(int w, int h, SkIPoint16* loc) {
-        static constexpr int kPad = 1;
-
-        if (!fRectanizer.addRect(w + kPad, h + kPad, loc)) {
+    bool addRect(int w, int h, SkIPoint16* loc, int maxAtlasSize) {
+        // Pad all paths except those that are expected to take up an entire physical texture.
+        if (w < maxAtlasSize) {
+            w = SkTMin(w + kPadding, maxAtlasSize);
+        }
+        if (h < maxAtlasSize) {
+            h = SkTMin(h + kPadding, maxAtlasSize);
+        }
+        if (!fRectanizer.addRect(w, h, loc)) {
             return false;
         }
         loc->fX += fX;
@@ -76,18 +84,20 @@
     typedef GrDrawOp INHERITED;
 };
 
-GrCCAtlas::GrCCAtlas(const GrCaps& caps, int minWidth, int minHeight)
-        : fMaxAtlasSize(caps.maxRenderTargetSize()), fDrawBounds{0, 0} {
-    SkASSERT(fMaxAtlasSize <= caps.maxTextureSize());
-    SkASSERT(SkTMax(minWidth, minHeight) <= fMaxAtlasSize);
-    int initialSize = GrNextPow2(SkTMax(minWidth, minHeight));
-    initialSize = SkTMax(int(kMinSize), initialSize);
+GrCCAtlas::GrCCAtlas(const GrCaps& caps, int minSize)
+        : fMaxAtlasSize(SkTMax(minSize, caps.maxPreferredRenderTargetSize())) {
+    // Caller should have cropped any paths to the destination render target instead of asking for
+    // an atlas larger than maxRenderTargetSize.
+    SkASSERT(fMaxAtlasSize <= caps.maxRenderTargetSize());
+    int initialSize = GrNextPow2(minSize + kPadding);
+    initialSize = SkTMax(kAtlasMinSize, initialSize);
     initialSize = SkTMin(initialSize, fMaxAtlasSize);
     fHeight = fWidth = initialSize;
-    fTopNode = skstd::make_unique<Node>(nullptr, 0, 0, initialSize, initialSize);
+    fTopNode = skstd::make_unique<Node>(nullptr, 0, 0, fWidth, fHeight);
 }
 
-GrCCAtlas::~GrCCAtlas() {}
+GrCCAtlas::~GrCCAtlas() {
+}
 
 bool GrCCAtlas::addRect(int w, int h, SkIPoint16* loc) {
     // This can't be called anymore once setCoverageCountBatchID() has been called.
@@ -104,17 +114,14 @@
 }
 
 bool GrCCAtlas::internalPlaceRect(int w, int h, SkIPoint16* loc) {
-    SkASSERT(SkTMax(w, h) < fMaxAtlasSize);
-
     for (Node* node = fTopNode.get(); node; node = node->previous()) {
-        if (node->addRect(w, h, loc)) {
+        if (node->addRect(w, h, loc, fMaxAtlasSize)) {
             return true;
         }
     }
 
     // The rect didn't fit. Grow the atlas and try again.
     do {
-        SkASSERT(SkTMax(fWidth, fHeight) <= fMaxAtlasSize);
         if (fWidth == fMaxAtlasSize && fHeight == fMaxAtlasSize) {
             return false;
         }
@@ -127,7 +134,7 @@
             fWidth = SkTMin(fWidth * 2, fMaxAtlasSize);
             fTopNode = skstd::make_unique<Node>(std::move(fTopNode), left, 0, fWidth, fHeight);
         }
-    } while (!fTopNode->addRect(w, h, loc));
+    } while (!fTopNode->addRect(w, h, loc, fMaxAtlasSize));
 
     return true;
 }