adding preabandon flag to DM
authorjoshualitt <joshualitt@chromium.org>
Wed, 25 Feb 2015 22:09:45 +0000 (14:09 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 25 Feb 2015 22:09:46 +0000 (14:09 -0800)
BUG=skia:

Review URL: https://codereview.chromium.org/929243004

13 files changed:
dm/DMSrcSink.cpp
src/core/SkCanvas.cpp
src/effects/SkBlurImageFilter.cpp
src/effects/SkBlurMaskFilter.cpp
src/effects/gradients/SkGradientShader.cpp
src/gpu/GrContext.cpp
src/gpu/GrTextContext.cpp
src/gpu/SkGpuDevice.cpp
src/gpu/SkGpuDevice.h
src/gpu/SkGr.cpp
src/gpu/effects/GrTextureStripAtlas.cpp
tools/flags/SkCommonFlags.cpp
tools/flags/SkCommonFlags.h

index b44f1d7..e67d435 100644 (file)
@@ -2,6 +2,7 @@
 #include "SamplePipeControllers.h"
 #include "SkCommonFlags.h"
 #include "SkDocument.h"
+#include "SkError.h"
 #include "SkMultiPictureDraw.h"
 #include "SkNullCanvas.h"
 #include "SkOSFile.h"
@@ -157,6 +158,8 @@ int GPUSink::enclave() const {
     return fThreaded ? kAnyThread_Enclave : kGPU_Enclave;
 }
 
+void PreAbandonGpuContextErrorHandler(SkError, void*) {}
+
 Error GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) const {
     GrContextFactory factory;
     const SkISize size = src.size();
@@ -167,6 +170,10 @@ Error GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) co
     if (!surface) {
         return "Could not create a surface.";
     }
+    if (FLAGS_preAbandonGpuContext) {
+        SkSetErrorCallback(&PreAbandonGpuContextErrorHandler, NULL);
+        factory.abandonContexts();
+    }
     SkCanvas* canvas = surface->getCanvas();
     Error err = src.draw(canvas);
     if (!err.isEmpty()) {
@@ -178,7 +185,7 @@ Error GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) co
         canvas->getGrContext()->dumpGpuStats(log);
     }
     dst->allocPixels(info);
-    canvas->readPixels(dst, 0,0);
+    canvas->readPixels(dst, 0, 0);
     if (FLAGS_abandonGpuContext) {
         factory.abandonContexts();
     }
index 221ed93..c10d390 100644 (file)
@@ -13,6 +13,7 @@
 #include "SkDrawable.h"
 #include "SkDrawFilter.h"
 #include "SkDrawLooper.h"
+#include "SkErrorInternals.h"
 #include "SkImage.h"
 #include "SkMetaData.h"
 #include "SkPathOps.h"
@@ -947,7 +948,8 @@ void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav
     device = device->onCreateCompatibleDevice(SkBaseDevice::CreateInfo(info, usage,
                                                                        fProps.pixelGeometry()));
     if (NULL == device) {
-        SkDebugf("Unable to create device for layer.");
+        SkErrorInternals::SetError( kInternalError_SkError,
+                                    "Unable to create device for layer.");
         return;
     }
 
index 32609b8..4dcc05e 100644 (file)
@@ -280,6 +280,9 @@ bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const
                                                              true,
                                                              sigma.x(),
                                                              sigma.y()));
+    if (!tex) {
+        return false;
+    }
     WrapTexture(tex, rect.width(), rect.height(), result);
     return true;
 #else
index d7c874c..491f598 100644 (file)
@@ -965,6 +965,9 @@ GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma,
         texDesc.fConfig = kAlpha_8_GrPixelConfig;
 
         blurNinePatchTexture = context->createTexture(texDesc, true, blurred_mask.fImage, 0);
+        if (!blurNinePatchTexture) {
+            return NULL;
+        }
         context->addResourceToCache(key, blurNinePatchTexture);
 
         SkMask::FreeImage(blurred_mask.fImage);
index d2b8bc3..0f6599d 100644 (file)
@@ -1130,6 +1130,9 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx,
             fTextureAccess.reset(fAtlas->getTexture(), params);
         } else {
             SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(ctx, bitmap, &params));
+            if (!texture) {
+                return;
+            }
             fCoordTransform.reset(kCoordSet, matrix, texture, params.filterMode());
             fTextureAccess.reset(texture, params);
             fYCoord = SK_ScalarHalf;
index b574614..85ea9ca 100755 (executable)
@@ -52,6 +52,9 @@ static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11;
 static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4;
 
 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
+#define RETURN_IF_ABANDONED if (!fDrawBuffer) { return; }
+#define RETURN_FALSE_IF_ABANDONED if (!fDrawBuffer) { return false; }
+#define RETURN_NULL_IF_ABANDONED if (!fDrawBuffer) { return NULL; }
 
 class GrContext::AutoCheckFlush {
 public:
@@ -240,6 +243,7 @@ bool GrContext::npotTextureTileSupport() const {
 
 GrTexture* GrContext::createTexture(const GrSurfaceDesc& desc, bool budgeted, const void* srcData,
                                     size_t rowBytes) {
+    RETURN_NULL_IF_ABANDONED
     if ((desc.fFlags & kRenderTarget_GrSurfaceFlag) &&
         !this->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
         return NULL;
@@ -263,6 +267,7 @@ GrTexture* GrContext::createTexture(const GrSurfaceDesc& desc, bool budgeted, co
 
 GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMatch match,
                                         bool calledDuringFlush) {
+    RETURN_NULL_IF_ABANDONED
     // Currently we don't recycle compressed textures as scratch.
     if (GrPixelConfigIsCompressed(desc.fConfig)) {
         return NULL;
@@ -344,10 +349,12 @@ int GrContext::getMaxSampleCount() const {
 ///////////////////////////////////////////////////////////////////////////////
 
 GrTexture* GrContext::wrapBackendTexture(const GrBackendTextureDesc& desc) {
+    RETURN_NULL_IF_ABANDONED
     return fGpu->wrapBackendTexture(desc);
 }
 
 GrRenderTarget* GrContext::wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) {
+    RETURN_NULL_IF_ABANDONED
     return fGpu->wrapBackendRenderTarget(desc);
 }
 
@@ -357,6 +364,7 @@ void GrContext::clear(const SkIRect* rect,
                       const GrColor color,
                       bool canIgnoreRect,
                       GrRenderTarget* renderTarget) {
+    RETURN_IF_ABANDONED
     ASSERT_OWNED_RESOURCE(renderTarget);
     SkASSERT(renderTarget);
 
@@ -373,6 +381,7 @@ void GrContext::drawPaint(GrRenderTarget* rt,
                           const GrClip& clip,
                           const GrPaint& origPaint,
                           const SkMatrix& viewMatrix) {
+    RETURN_IF_ABANDONED
     // set rect to be big enough to fill the space, but not super-huge, so we
     // don't overflow fixed-point implementations
     SkRect r;
@@ -507,6 +516,7 @@ void GrContext::drawRect(GrRenderTarget* rt,
                          const SkMatrix& viewMatrix,
                          const SkRect& rect,
                          const GrStrokeInfo* strokeInfo) {
+    RETURN_IF_ABANDONED
     if (strokeInfo && strokeInfo->isDashed()) {
         SkPath path;
         path.addRect(rect);
@@ -641,6 +651,7 @@ void GrContext::drawNonAARectToRect(GrRenderTarget* rt,
                                     const SkRect& rectToDraw,
                                     const SkRect& localRect,
                                     const SkMatrix* localMatrix) {
+    RETURN_IF_ABANDONED
     AutoCheckFlush acf(this);
     GrPipelineBuilder pipelineBuilder;
     GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
@@ -693,6 +704,7 @@ void GrContext::drawVertices(GrRenderTarget* rt,
                              const GrColor colors[],
                              const uint16_t indices[],
                              int indexCount) {
+    RETURN_IF_ABANDONED
     AutoCheckFlush acf(this);
     GrPipelineBuilder pipelineBuilder;
     GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope
@@ -751,6 +763,7 @@ void GrContext::drawRRect(GrRenderTarget*rt,
                           const SkMatrix& viewMatrix,
                           const SkRRect& rrect,
                           const GrStrokeInfo& strokeInfo) {
+    RETURN_IF_ABANDONED
     if (rrect.isEmpty()) {
        return;
     }
@@ -796,6 +809,7 @@ void GrContext::drawDRRect(GrRenderTarget* rt,
                            const SkMatrix& viewMatrix,
                            const SkRRect& outer,
                            const SkRRect& inner) {
+    RETURN_IF_ABANDONED
     if (outer.isEmpty()) {
        return;
     }
@@ -833,6 +847,7 @@ void GrContext::drawOval(GrRenderTarget* rt,
                          const SkMatrix& viewMatrix,
                          const SkRect& oval,
                          const GrStrokeInfo& strokeInfo) {
+    RETURN_IF_ABANDONED
     if (oval.isEmpty()) {
        return;
     }
@@ -929,7 +944,7 @@ void GrContext::drawPath(GrRenderTarget* rt,
                          const SkMatrix& viewMatrix,
                          const SkPath& path,
                          const GrStrokeInfo& strokeInfo) {
-
+    RETURN_IF_ABANDONED
     if (path.isEmpty()) {
        if (path.isInverseFillType()) {
            this->drawPaint(rt, clip, paint, viewMatrix);
@@ -1020,6 +1035,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target,
                                  bool useAA,
                                  const SkPath& path,
                                  const GrStrokeInfo& strokeInfo) {
+    RETURN_IF_ABANDONED
     SkASSERT(!path.isEmpty());
 
     GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target);
@@ -1110,7 +1126,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
                                    int left, int top, int width, int height,
                                    GrPixelConfig srcConfig, const void* buffer, size_t rowBytes,
                                    uint32_t pixelOpsFlags) {
-
+    RETURN_FALSE_IF_ABANDONED
     {
         GrTexture* texture = NULL;
         if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asTexture()) &&
@@ -1240,6 +1256,7 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target,
                                        int left, int top, int width, int height,
                                        GrPixelConfig dstConfig, void* buffer, size_t rowBytes,
                                        uint32_t flags) {
+    RETURN_FALSE_IF_ABANDONED
     ASSERT_OWNED_RESOURCE(target);
     SkASSERT(target);
 
@@ -1378,6 +1395,7 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target,
 }
 
 void GrContext::prepareSurfaceForExternalRead(GrSurface* surface) {
+    RETURN_IF_ABANDONED
     SkASSERT(surface);
     ASSERT_OWNED_RESOURCE(surface);
     if (surface->surfacePriv().hasPendingIO()) {
@@ -1390,6 +1408,7 @@ void GrContext::prepareSurfaceForExternalRead(GrSurface* surface) {
 }
 
 void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) {
+    RETURN_IF_ABANDONED
     SkASSERT(renderTarget);
     ASSERT_OWNED_RESOURCE(renderTarget);
     AutoCheckFlush acf(this);
@@ -1402,6 +1421,7 @@ void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) {
 
 void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
                             const SkIPoint& dstPoint, uint32_t pixelOpsFlags) {
+    RETURN_IF_ABANDONED
     if (NULL == src || NULL == dst) {
         return;
     }
@@ -1423,6 +1443,7 @@ void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe
 }
 
 void GrContext::flushSurfaceWrites(GrSurface* surface) {
+    RETURN_IF_ABANDONED
     if (surface->surfacePriv().hasPendingWrite()) {
         this->flush();
     }
@@ -1433,7 +1454,7 @@ GrDrawTarget* GrContext::prepareToDraw(GrPipelineBuilder* pipelineBuilder,
                                        const GrClip& clip,
                                        const GrPaint* paint,
                                        const AutoCheckFlush* acf) {
-    if (NULL == fGpu) {
+    if (NULL == fGpu || NULL == fDrawBuffer) {
         return NULL;
     }
 
index cef99c6..ad5e7c0 100644 (file)
@@ -40,6 +40,9 @@ bool GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPai
                              const SkPaint& skPaint, const SkMatrix& viewMatrix,
                              const char text[], size_t byteLength,
                              SkScalar x, SkScalar y) {
+    if (!fContext->getTextTarget()) {
+        return false;
+    }
 
     GrTextContext* textContext = this;
     do {
@@ -58,6 +61,9 @@ bool GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const Gr
                                 const char text[], size_t byteLength,
                                 const SkScalar pos[], int scalarsPerPosition,
                                 const SkPoint& offset) {
+    if (!fContext->getTextTarget()) {
+        return false;
+    }
 
     GrTextContext* textContext = this;
     do {
index edbb82e..fb5fa7c 100644 (file)
@@ -1494,6 +1494,9 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
     GrTexture* texture;
     // draw sprite uses the default texture params
     AutoBitmapTexture abt(fContext, bitmap, NULL, &texture);
+    if (!texture) {
+        return;
+    }
 
     SkImageFilter* filter = paint.getImageFilter();
     // This bitmap will own the filtered result as a texture.
@@ -1882,8 +1885,9 @@ SkBaseDevice* SkGpuDevice::onCreateCompatibleDevice(const CreateInfo& cinfo) {
         SkSurfaceProps props(fSurfaceProps.flags(), cinfo.fPixelGeometry);
         return SkGpuDevice::Create(texture->asRenderTarget(), &props, flags);
     } else {
-        SkDebugf("---- failed to create compatible device texture [%d %d]\n",
-                 cinfo.fInfo.width(), cinfo.fInfo.height());
+        SkErrorInternals::SetError( kInternalError_SkError,
+                                    "---- failed to create compatible device texture [%d %d]\n",
+                                    cinfo.fInfo.width(), cinfo.fInfo.height());
         return NULL;
     }
 }
index 8dafcfc..6b520e7 100644 (file)
@@ -57,7 +57,7 @@ public:
         return static_cast<SkGpuDevice*>(dev);
     }
 
-    GrContext* context() const { return fRenderTarget->getContext(); }
+    GrContext* context() const { return fContext; }
 
     // set all pixels to 0
     void clearAll();
index b0814af..401a50e 100644 (file)
@@ -11,6 +11,7 @@
 #include "SkColorFilter.h"
 #include "SkConfig8888.h"
 #include "SkData.h"
+#include "SkErrorInternals.h"
 #include "SkMessageBus.h"
 #include "SkPixelRef.h"
 #include "SkResourceCache.h"
@@ -560,8 +561,9 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
         return result;
     }
 
-    SkDebugf("---- failed to create texture for cache [%d %d]\n",
-                bitmap.width(), bitmap.height());
+    SkErrorInternals::SetError( kInternalError_SkError,
+                                "---- failed to create texture for cache [%d %d]\n",
+                                bitmap.width(), bitmap.height());
 
     return NULL;
 }
index 51aaf53..65096bf 100644 (file)
@@ -92,6 +92,9 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& data) {
     VALIDATE;
     if (0 == fLockedRows) {
         this->lockTexture();
+        if (!fTexture) {
+            return -1;
+        }
     }
 
     int key = data.getGenerationID();
@@ -204,6 +207,9 @@ void GrTextureStripAtlas::lockTexture() {
     fTexture = fDesc.fContext->findAndRefCachedTexture(key);
     if (NULL == fTexture) {
         fTexture = fDesc.fContext->createTexture(texDesc, true, NULL, 0);
+        if (!fTexture) {
+            return;
+        }
         fDesc.fContext->addResourceToCache(key, fTexture);
         // This is a new texture, so all of our cache info is now invalid
         this->initLRU();
index fa54a18..d05f764 100644 (file)
@@ -39,6 +39,8 @@ DEFINE_string2(match, m, NULL,
 
 DEFINE_bool2(quiet, q, false, "if true, don't print status updates.");
 
+DEFINE_bool(preAbandonGpuContext, false, "Abandons the GrContext before running the test.");
+
 DEFINE_bool(abandonGpuContext, false, "Abandon the GrContext after running each test.");
 
 DEFINE_string(skps, "skps", "Directory to read skps from.");
index 69b8358..6a5ff58 100644 (file)
@@ -20,6 +20,7 @@ DECLARE_bool(leaks);
 DECLARE_string(match);
 DECLARE_bool(quiet);
 DECLARE_bool(resetGpuContext);
+DECLARE_bool(preAbandonGpuContext);
 DECLARE_bool(abandonGpuContext);
 DECLARE_string(skps);
 DECLARE_int32(threads);