Rewrite tessellation atlases as normal render tasks

Rewrites tessellation atlases as normal render tasks instead of
"onFlush" tasks. These tasks get inserted into the DAG upfront, lay
out their atlases as dependent tasks get built and reference them, and
finally add their ops to render themselves during onMakeClosed. Doing it
this way allows us to pause the flush and re-render the atlas whenever
it runs out of room.

Bug: b/188794626
Bug: chromium:928984
Change-Id: Id59a5527924c63d5ff7c5bce46a88368e79fc3ef
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/420556
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Adlai Holler <adlai@google.com>
diff --git a/src/gpu/GrDynamicAtlas.cpp b/src/gpu/GrDynamicAtlas.cpp
index ea44c8c..1b4cf24 100644
--- a/src/gpu/GrDynamicAtlas.cpp
+++ b/src/gpu/GrDynamicAtlas.cpp
@@ -91,8 +91,8 @@
             [this](GrResourceProvider* resourceProvider, const LazyAtlasDesc& desc) {
                 if (!fBackingTexture) {
                     fBackingTexture = resourceProvider->createTexture(
-                            {fWidth, fHeight}, desc.fFormat, desc.fRenderable, desc.fSampleCnt,
-                            desc.fMipmapped, desc.fBudgeted, desc.fProtected);
+                            fTextureProxy->backingStoreDimensions(), desc.fFormat, desc.fRenderable,
+                            desc.fSampleCnt, desc.fMipmapped, desc.fBudgeted, desc.fProtected);
                 }
                 return GrSurfaceProxy::LazyCallbackResult(fBackingTexture);
             },
@@ -109,11 +109,16 @@
     return fNodeAllocator.make<Node>(previous, rectanizer, l, t);
 }
 
-GrSurfaceProxyView GrDynamicAtlas::surfaceProxyView(const GrCaps& caps) const {
+GrSurfaceProxyView GrDynamicAtlas::readView(const GrCaps& caps) const {
     return {fTextureProxy, kTextureOrigin,
             caps.getReadSwizzle(fTextureProxy->backendFormat(), fColorType)};
 }
 
+GrSurfaceProxyView GrDynamicAtlas::writeView(const GrCaps& caps) const {
+    return {fTextureProxy, kTextureOrigin,
+            caps.getWriteSwizzle(fTextureProxy->backendFormat(), fColorType)};
+}
+
 bool GrDynamicAtlas::addRect(int width, int height, SkIPoint16* location) {
     // This can't be called anymore once instantiate() has been called.
     SkASSERT(!this->isInstantiated());
@@ -171,17 +176,20 @@
     return true;
 }
 
-std::unique_ptr<GrSurfaceDrawContext> GrDynamicAtlas::instantiate(
-        GrOnFlushResourceProvider* onFlushRP, sk_sp<GrTexture> backingTexture) {
+void GrDynamicAtlas::instantiate(GrOnFlushResourceProvider* onFlushRP,
+                                 sk_sp<GrTexture> backingTexture) {
     SkASSERT(!this->isInstantiated());  // This method should only be called once.
     // Caller should have cropped any paths to the destination render target instead of asking for
     // an atlas larger than maxRenderTargetSize.
     SkASSERT(std::max(fHeight, fWidth) <= fMaxAtlasSize);
     SkASSERT(fMaxAtlasSize <= onFlushRP->caps()->maxRenderTargetSize());
 
-    // Finalize the content size of our proxy. The GPU can potentially make optimizations if it
-    // knows we only intend to write out a smaller sub-rectangle of the backing texture.
-    fTextureProxy->priv().setLazyDimensions(fDrawBounds);
+    if (fTextureProxy->isFullyLazy()) {
+        // Finalize the content size of our proxy. The GPU can potentially make optimizations if it
+        // knows we only intend to write out a smaller sub-rectangle of the backing texture.
+        fTextureProxy->priv().setLazyDimensions(fDrawBounds);
+    }
+    SkASSERT(fTextureProxy->dimensions() == fDrawBounds);
 
     if (backingTexture) {
 #ifdef SK_DEBUG
@@ -189,21 +197,9 @@
         SkASSERT(backingRT);
         SkASSERT(backingRT->backendFormat() == fTextureProxy->backendFormat());
         SkASSERT(backingRT->numSamples() == fTextureProxy->asRenderTargetProxy()->numSamples());
-        SkASSERT(backingRT->width() == fWidth);
-        SkASSERT(backingRT->height() == fHeight);
+        SkASSERT(backingRT->dimensions() == fTextureProxy->backingStoreDimensions());
 #endif
         fBackingTexture = std::move(backingTexture);
     }
-    auto sdc = onFlushRP->makeSurfaceDrawContext(fTextureProxy, kTextureOrigin, fColorType,
-                                                 nullptr, SkSurfaceProps());
-    if (!sdc) {
-        onFlushRP->printWarningMessage(SkStringPrintf(
-                "WARNING: failed to allocate a %ix%i atlas. Some masks will not be drawn.\n",
-                fWidth, fHeight).c_str());
-        return nullptr;
-    }
-
-    SkIRect clearRect = SkIRect::MakeSize(fDrawBounds);
-    sdc->clearAtLeast(clearRect, SK_PMColor4fTRANSPARENT);
-    return sdc;
+    onFlushRP->instatiateProxy(fTextureProxy.get());
 }