Reland "Initiate MSAA resolves during DAG generation"

This is a reland of 804f6a0fe7f3c7df5ac69891841ee9cdf6d1121a

Original change's description:
> Initiate MSAA resolves during DAG generation
> 
> Adds an "fIsMSAADirty" flag to GrRenderTargetProxy and switches to
> resolving MSAA in GrTextureResolveRenderTask. This completes our push
> to resolve textures outside of render passes.
> 
> For the time being, we only store a dirty flag on the proxy and still
> rely on the GrRenderTarget itself to track the actual dirty rect. This
> will be followed by a CL that moves the dirty rect out of
> GrRenderTarget and into the proxy.
> 
> Bug: skia:
> Change-Id: I21219a58028bdb4590940210e565133093cd34b3
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/235672
> Commit-Queue: Chris Dalton <csmartdalton@google.com>
> Reviewed-by: Robert Phillips <robertphillips@google.com>

Bug: skia:
Change-Id: I805b3af1404eb7919ae937cff3dfa97921e32c69
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/237482
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrOpsRenderPass.cpp b/src/gpu/GrOpsRenderPass.cpp
index 3876a42..dcc53b6 100644
--- a/src/gpu/GrOpsRenderPass.cpp
+++ b/src/gpu/GrOpsRenderPass.cpp
@@ -17,6 +17,7 @@
 #include "src/gpu/GrPrimitiveProcessor.h"
 #include "src/gpu/GrRenderTarget.h"
 #include "src/gpu/GrRenderTargetPriv.h"
+#include "src/gpu/GrTexturePriv.h"
 
 void GrOpsRenderPass::clear(const GrFixedClip& clip, const SkPMColor4f& color) {
     SkASSERT(fRenderTarget);
@@ -33,6 +34,51 @@
     this->onClearStencilClip(clip, insideStencilMask);
 }
 
+#ifdef SK_DEBUG
+static void assert_msaa_and_mips_are_resolved(
+        const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
+        const GrPipeline::FixedDynamicState* fixedDynamicState,
+        const GrPipeline::DynamicStateArrays* dynamicStateArrays, int meshCount) {
+    auto assertResolved = [](GrTexture* tex, const GrSamplerState& sampler) {
+        SkASSERT(tex);
+
+        // Ensure msaa was resolved ahead of time by the DAG.
+        SkASSERT(!tex->asRenderTarget() || !tex->asRenderTarget()->needsResolve());
+
+        // Ensure mipmaps were all resolved ahead of time by the DAG.
+        if (GrSamplerState::Filter::kMipMap == sampler.filter() &&
+            (tex->width() != 1 || tex->height() != 1)) {
+            // There are some cases where we might be given a non-mipmapped texture with a mipmap
+            // filter. See skbug.com/7094.
+            SkASSERT(tex->texturePriv().mipMapped() != GrMipMapped::kYes ||
+                     !tex->texturePriv().mipMapsAreDirty());
+        }
+    };
+
+    if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
+        for (int m = 0, i = 0; m < meshCount; ++m) {
+            for (int s = 0; s < primProc.numTextureSamplers(); ++s, ++i) {
+                auto* tex = dynamicStateArrays->fPrimitiveProcessorTextures[i]->peekTexture();
+                assertResolved(tex, primProc.textureSampler(s).samplerState());
+            }
+        }
+    } else {
+        for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
+            auto* tex = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture();
+            assertResolved(tex, primProc.textureSampler(i).samplerState());
+        }
+    }
+
+    GrFragmentProcessor::Iter iter(pipeline);
+    while (const GrFragmentProcessor* fp = iter.next()) {
+        for (int i = 0; i < fp->numTextureSamplers(); ++i) {
+            const auto& textureSampler = fp->textureSampler(i);
+            assertResolved(textureSampler.peekTexture(), textureSampler.samplerState());
+        }
+    }
+}
+#endif
+
 bool GrOpsRenderPass::draw(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
                            const GrPipeline::FixedDynamicState* fixedDynamicState,
                            const GrPipeline::DynamicStateArrays* dynamicStateArrays,
@@ -45,13 +91,12 @@
         SkASSERT(primProc.hasVertexAttributes() == meshes[i].hasVertexData());
         SkASSERT(primProc.hasInstanceAttributes() == meshes[i].hasInstanceData());
     }
-#endif
+
     SkASSERT(!pipeline.isScissorEnabled() || fixedDynamicState ||
              (dynamicStateArrays && dynamicStateArrays->fScissorRects));
 
     SkASSERT(!pipeline.isBad());
 
-#ifdef SK_DEBUG
     if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
         GrTextureProxy** processorProxies = fixedDynamicState->fPrimitiveProcessorTextures;
         for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
@@ -80,6 +125,9 @@
             }
         }
     }
+
+    assert_msaa_and_mips_are_resolved(
+            primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshCount);
 #endif
 
     if (primProc.numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {