Guard against instantiate & accessRenderTarget failures

Chrome's fuzzer have reminded me that, since we are deferring allocation, instantiate and accessRenderTarget can now fail further down the call stack.

This should probably be cherry picked back to M56.

BUG=665681,665500,665621

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4929

Change-Id: I44d81ff29586dfe75ddda30b5ed8ca76354542d6
Reviewed-on: https://skia-review.googlesource.com/4929
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/include/gpu/GrRenderTargetContext.h b/include/gpu/GrRenderTargetContext.h
index a3869a3..d1896db 100644
--- a/include/gpu/GrRenderTargetContext.h
+++ b/include/gpu/GrRenderTargetContext.h
@@ -354,6 +354,10 @@
     GrTextureProxy* asDeferredTexture();
 
     sk_sp<GrTexture> asTexture() {
+        if (!this->accessRenderTarget()) {
+            return nullptr;
+        }
+
         // TODO: usage of this entry point needs to be reduced and potentially eliminated
         // since it ends the deferral of the GrRenderTarget's allocation
         // It's usage should migrate to asDeferredTexture
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index f188781..c97eb01 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -390,6 +390,9 @@
 
         // TODO: add GrTextureProxy-backed SkImage_Gpus
         GrSurface* surf = fSurfaceProxy->instantiate(fContext->textureProvider());
+        if (!surf) {
+            return;
+        }
 
         // TODO: In this instance we know we're going to draw a sub-portion of the backing
         // texture into the canvas so it is okay to wrap it in an SkImage. This poses
@@ -411,7 +414,9 @@
     // This entry point should go away in favor of asTextureProxy
     sk_sp<GrTexture> onAsTextureRef(GrContext* context) const override {
         GrSurface* surf = fSurfaceProxy->instantiate(context->textureProvider());
-
+        if (!surf) {
+            return nullptr;
+        }
         return sk_ref_sp(surf->asTexture());
     }
 
@@ -436,6 +441,9 @@
 
         // Reading back to an SkBitmap ends deferral
         GrSurface* surface = fSurfaceProxy->instantiate(fContext->textureProvider());
+        if (!surface) {
+            return false;
+        }
 
         if (!surface->readPixels(0, 0, dst->width(), dst->height(), kSkia8888_GrPixelConfig,
                                  dst->getPixels(), dst->rowBytes())) {
@@ -477,6 +485,9 @@
     sk_sp<SkImage> onMakeTightSubset(const SkIRect& subset) const override {
         // TODO: add GrTextureProxy-backed SkImage_Gpus
         GrSurface* surf = fSurfaceProxy->instantiate(fContext->textureProvider());
+        if (!surf) {
+            return nullptr;
+        }
 
         if (0 == subset.fLeft && 0 == subset.fTop &&
             fSurfaceProxy->width() == subset.width() &&
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 6e581cc..ead87d5 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -399,10 +399,11 @@
                                   Gr1DKernelEffect::Direction direction) {
     GrPaint paint;
     paint.setGammaCorrect(renderTargetContext->isGammaCorrect());
-    paint.addColorFragmentProcessor(GrMorphologyEffect::Make(textureProxy->instantiate(provider),
-                                                             direction,
-                                                             radius,
-                                                             morphType,
+    GrTexture* tex = textureProxy->instantiate(provider);
+    if (!tex) {
+        return;
+    }
+    paint.addColorFragmentProcessor(GrMorphologyEffect::Make(tex, direction, radius, morphType,
                                                              bounds));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
     renderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect),
@@ -420,9 +421,11 @@
                                             Gr1DKernelEffect::Direction direction) {
     GrPaint paint;
     paint.setGammaCorrect(renderTargetContext->isGammaCorrect());
-    paint.addColorFragmentProcessor(GrMorphologyEffect::Make(textureProxy->instantiate(provider),
-                                                             direction, radius,
-                                                             morphType));
+    GrTexture* tex = textureProxy->instantiate(provider);
+    if (!tex) {
+        return;
+    }
+    paint.addColorFragmentProcessor(GrMorphologyEffect::Make(tex, direction, radius, morphType));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
     renderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect),
                                         SkRect::Make(srcRect));
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 133c4f7..072f41c 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -356,6 +356,9 @@
     }
 
     GrRenderTarget* rt = renderTargetContext->accessRenderTarget();
+    if (!rt) {
+        return true;
+    }
 
     // use the stencil clip if we can't represent the clip as a rectangle.
     if (!context->resourceProvider()->attachStencilAttachment(rt)) {
@@ -413,7 +416,10 @@
     }
 
     sk_sp<GrTexture> texture(rtc->asTexture());
-    SkASSERT(texture);
+    if (!texture) {
+        return nullptr;
+    }
+
     texture->resourcePriv().setUniqueKey(key);
     return texture;
 }
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index f16f861..5267df3 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -235,6 +235,9 @@
         rtp->isStencilBufferMultisampled()) {
         // TODO: defer stencil buffer attachment for PathRenderingDrawContext
         sk_sp<GrRenderTarget> rt(sk_ref_sp(rtp->instantiate(fContext->textureProvider())));
+        if (!rt) {
+            return nullptr;
+        }
         GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt.get());
         if (sb) {
             return sk_sp<GrRenderTargetContext>(new GrPathRenderingRenderTargetContext(
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index 872a7f5..c0170eb 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -23,7 +23,10 @@
     const GrPipelineBuilder& builder = *args.fPipelineBuilder;
     const GrUserStencilSettings* userStencil = builder.getUserStencil();
     GrRenderTarget* rt = args.fRenderTargetContext->accessRenderTarget();
-
+    if (!rt) {
+        return nullptr;
+    }
+    
     GrPipeline* pipeline = new (memory) GrPipeline;
     pipeline->fRenderTarget.reset(rt);
     SkASSERT(pipeline->fRenderTarget);
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 3bc6ad3..e311c3d 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -146,6 +146,9 @@
     // TODO: this needs to be fixed up since it ends the deferrable of the GrRenderTarget
     sk_sp<GrRenderTarget> rt(
                         sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
+    if (!rt) {
+        return false;
+    }
 
     return this->getOpList()->copySurface(rt.get(), src, srcRect, dstPoint);
 }
@@ -208,6 +211,9 @@
     // TODO: this needs to be fixed up since it ends the deferrable of the GrRenderTarget
     sk_sp<GrRenderTarget> rt(
                         sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
+    if (!rt) {
+        return;
+    }
 
     this->getOpList()->discard(rt.get());
 }
@@ -264,8 +270,13 @@
 
         this->drawRect(clip, paint, SkMatrix::I(), clearRect);
     } else if (isFull) {
-        this->getOpList()->fullClear(this->accessRenderTarget(), color);
+        if (this->accessRenderTarget()) {
+            this->getOpList()->fullClear(this->accessRenderTarget(), color);
+        }
     } else {
+        if (!this->accessRenderTarget()) {
+            return;
+        }
         sk_sp<GrBatch> batch(GrClearBatch::Make(clip, color, this->accessRenderTarget()));
         if (!batch) {
             return;
@@ -592,6 +603,9 @@
                               "GrRenderTargetContextPriv::clearStencilClip");
 
     AutoCheckFlush acf(fRenderTargetContext->fDrawingManager);
+    if (!fRenderTargetContext->accessRenderTarget()) {
+        return;
+    }
     fRenderTargetContext->getOpList()->clearStencilClip(clip, insideStencilMask,
                                                         fRenderTargetContext->accessRenderTarget());
 }
@@ -1144,6 +1158,9 @@
     // Deferral of the VRAM resources must end in this instance anyway
     sk_sp<GrRenderTarget> rt(
                         sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
+    if (!rt) {
+        return;
+    }
 
     ASSERT_OWNED_RESOURCE(rt);
 
@@ -1185,6 +1202,9 @@
     // Deferral of the VRAM resources must end in this instance anyway
     sk_sp<GrRenderTarget> rt(
                         sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
+    if (!rt) {
+        return false;
+    }
 
     return rt->readPixels(x, y, dstInfo.width(), dstInfo.height(),
                           config, dstBuffer, dstRowBytes, flags);
@@ -1205,6 +1225,9 @@
     // Deferral of the VRAM resources must end in this instance anyway
     sk_sp<GrRenderTarget> rt(
                         sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
+    if (!rt) {
+        return false;
+    }
 
     return rt->writePixels(x, y, srcInfo.width(), srcInfo.height(),
                            config, srcBuffer, srcRowBytes, flags);
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index 72a29ab..aab71f9 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -301,6 +301,10 @@
     }
 
     if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()) {
+        if (!renderTargetContext->accessRenderTarget()) {
+            return;
+        }
+
         if (!fResourceProvider->attachStencilAttachment(
                 renderTargetContext->accessRenderTarget())) {
             SkDebugf("ERROR creating stencil attachment. Draw skipped.\n");
@@ -341,6 +345,10 @@
     args.fScissor = &appliedClip.scissorState();
     args.fWindowRectsState = &appliedClip.windowRectsState();
     args.fHasStencilClip = appliedClip.hasStencilClip();
+    if (!renderTargetContext->accessRenderTarget()) {
+        return;
+    }
+
     if (!this->setupDstReadIfNecessary(pipelineBuilder, renderTargetContext->accessRenderTarget(),
                                        clip, args.fOpts,
                                        &args.fDstTexture, batch->bounds())) {
@@ -382,6 +390,9 @@
     // attempt this in a situation that would require coverage AA.
     SkASSERT(!appliedClip.clipCoverageFragmentProcessor());
 
+    if (!renderTargetContext->accessRenderTarget()) {
+        return;
+    }
     GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAttachment(
                                                 renderTargetContext->accessRenderTarget());
     if (!stencilAttachment) {
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index a006e14..c75e36b 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -270,6 +270,10 @@
     const SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
 
     renderTargetContext->drawRect(GrNoClip(), paint, SkMatrix::I(), rect);
+
+    if (!renderTargetContext->accessRenderTarget()) {
+        return nullptr;
+    }
     ctx->flushSurfaceWrites(renderTargetContext->accessRenderTarget());
     return sk_make_sp<SkImage_Gpu>(width, height, kNeedNewImageUniqueID,
                                    kOpaque_SkAlphaType, renderTargetContext->asTexture(),
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 13bbd4f..abd8332 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -77,7 +77,10 @@
 
 sk_sp<SkImage> SkSurface_Gpu::onNewImageSnapshot(SkBudgeted budgeted, SkCopyPixelsMode cpm) {
     GrRenderTarget* rt = fDevice->accessRenderTargetContext()->accessRenderTarget();
-    SkASSERT(rt);
+    if (!rt) {
+        return nullptr;
+    }
+
     GrTexture* tex = rt->asTexture();
     sk_sp<GrTexture> copy;
     // If the original render target is a buffer originally created by the client, then we don't
@@ -111,6 +114,9 @@
 // doesn't force an OpenGL flush.
 void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) {
     GrRenderTarget* rt = fDevice->accessRenderTargetContext()->accessRenderTarget();
+    if (!rt) {
+        return;
+    }
     // are we sharing our render target with the image? Note this call should never create a new
     // image because onCopyOnWrite is only called when there is a cached image.
     sk_sp<SkImage> image(this->refCachedImage(SkBudgeted::kNo, kNo_ForceUnique));