aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2016-11-17 10:22:48 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-17 17:34:13 +0000
commite60ad620fe236ce4c1e85a31bd53ed0c848da8c3 (patch)
tree99293fa57aeb9cf3887764c3ec2e8096421f6703
parent987de5b6b996ab19aac8e09fa030bbb35ed51a3b (diff)
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>
-rw-r--r--include/gpu/GrRenderTargetContext.h4
-rw-r--r--src/core/SkSpecialImage.cpp13
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp17
-rw-r--r--src/gpu/GrClipStackClip.cpp8
-rw-r--r--src/gpu/GrDrawingManager.cpp3
-rw-r--r--src/gpu/GrPipeline.cpp5
-rw-r--r--src/gpu/GrRenderTargetContext.cpp25
-rw-r--r--src/gpu/GrRenderTargetOpList.cpp11
-rw-r--r--src/image/SkImage_Gpu.cpp4
-rw-r--r--src/image/SkSurface_Gpu.cpp8
10 files changed, 86 insertions, 12 deletions
diff --git a/include/gpu/GrRenderTargetContext.h b/include/gpu/GrRenderTargetContext.h
index a3869a353a..d1896db0cb 100644
--- a/include/gpu/GrRenderTargetContext.h
+++ b/include/gpu/GrRenderTargetContext.h
@@ -354,6 +354,10 @@ public:
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 f18878175b..c97eb01257 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -390,6 +390,9 @@ public:
// 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 @@ public:
// 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 @@ public:
// 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 @@ public:
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 6e581ccea4..ead87d5e1e 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -399,10 +399,11 @@ static void apply_morphology_rect(GrTextureProvider* provider,
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 @@ static void apply_morphology_rect_no_bounds(GrTextureProvider* provider,
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 133c4f706f..072f41ce91 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -356,6 +356,9 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar
}
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> GrClipStackClip::CreateAlphaClipMask(GrContext* context,
}
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 f16f861539..5267df3626 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -235,6 +235,9 @@ sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
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 872a7f544e..c0170eb703 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -23,7 +23,10 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
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 3bc6ad369e..e311c3d0ef 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -146,6 +146,9 @@ bool GrRenderTargetContext::copySurface(GrSurface* src, const SkIRect& srcRect,
// 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 @@ void GrRenderTargetContext::discard() {
// 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 @@ void GrRenderTargetContext::internalClear(const GrFixedClip& clip,
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 @@ void GrRenderTargetContextPriv::clearStencilClip(const GrFixedClip& clip, bool i
"GrRenderTargetContextPriv::clearStencilClip");
AutoCheckFlush acf(fRenderTargetContext->fDrawingManager);
+ if (!fRenderTargetContext->accessRenderTarget()) {
+ return;
+ }
fRenderTargetContext->getOpList()->clearStencilClip(clip, insideStencilMask,
fRenderTargetContext->accessRenderTarget());
}
@@ -1144,6 +1158,9 @@ void GrRenderTargetContext::prepareForExternalIO() {
// 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 @@ bool GrRenderTargetContext::readPixels(const SkImageInfo& dstInfo, void* dstBuff
// 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 @@ bool GrRenderTargetContext::writePixels(const SkImageInfo& srcInfo, const void*
// 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 72a29ab8cd..aab71f9019 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -301,6 +301,10 @@ void GrRenderTargetOpList::drawBatch(const GrPipelineBuilder& pipelineBuilder,
}
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 @@ void GrRenderTargetOpList::drawBatch(const GrPipelineBuilder& pipelineBuilder,
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 @@ void GrRenderTargetOpList::stencilPath(GrRenderTargetContext* renderTargetContex
// 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 a006e14ecf..c75e36b9d9 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -270,6 +270,10 @@ static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac
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 13bbd4f2e8..abd8332ee0 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -77,7 +77,10 @@ sk_sp<SkSurface> SkSurface_Gpu::onNewSurface(const SkImageInfo& info) {
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 @@ sk_sp<SkImage> SkSurface_Gpu::onNewImageSnapshot(SkBudgeted budgeted, SkCopyPixe
// 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));