adding preabandon flag to DM

BUG=skia:

Review URL: https://codereview.chromium.org/929243004
This commit is contained in:
joshualitt 2015-02-25 14:09:45 -08:00 committed by Commit bot
parent 570d2f81a6
commit 5f5a8d7599
13 changed files with 70 additions and 10 deletions

View File

@ -2,6 +2,7 @@
#include "SamplePipeControllers.h" #include "SamplePipeControllers.h"
#include "SkCommonFlags.h" #include "SkCommonFlags.h"
#include "SkDocument.h" #include "SkDocument.h"
#include "SkError.h"
#include "SkMultiPictureDraw.h" #include "SkMultiPictureDraw.h"
#include "SkNullCanvas.h" #include "SkNullCanvas.h"
#include "SkOSFile.h" #include "SkOSFile.h"
@ -157,6 +158,8 @@ int GPUSink::enclave() const {
return fThreaded ? kAnyThread_Enclave : kGPU_Enclave; return fThreaded ? kAnyThread_Enclave : kGPU_Enclave;
} }
void PreAbandonGpuContextErrorHandler(SkError, void*) {}
Error GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) const { Error GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) const {
GrContextFactory factory; GrContextFactory factory;
const SkISize size = src.size(); const SkISize size = src.size();
@ -167,6 +170,10 @@ Error GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) co
if (!surface) { if (!surface) {
return "Could not create a surface."; return "Could not create a surface.";
} }
if (FLAGS_preAbandonGpuContext) {
SkSetErrorCallback(&PreAbandonGpuContextErrorHandler, NULL);
factory.abandonContexts();
}
SkCanvas* canvas = surface->getCanvas(); SkCanvas* canvas = surface->getCanvas();
Error err = src.draw(canvas); Error err = src.draw(canvas);
if (!err.isEmpty()) { if (!err.isEmpty()) {
@ -178,7 +185,7 @@ Error GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) co
canvas->getGrContext()->dumpGpuStats(log); canvas->getGrContext()->dumpGpuStats(log);
} }
dst->allocPixels(info); dst->allocPixels(info);
canvas->readPixels(dst, 0,0); canvas->readPixels(dst, 0, 0);
if (FLAGS_abandonGpuContext) { if (FLAGS_abandonGpuContext) {
factory.abandonContexts(); factory.abandonContexts();
} }

View File

@ -13,6 +13,7 @@
#include "SkDrawable.h" #include "SkDrawable.h"
#include "SkDrawFilter.h" #include "SkDrawFilter.h"
#include "SkDrawLooper.h" #include "SkDrawLooper.h"
#include "SkErrorInternals.h"
#include "SkImage.h" #include "SkImage.h"
#include "SkMetaData.h" #include "SkMetaData.h"
#include "SkPathOps.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, device = device->onCreateCompatibleDevice(SkBaseDevice::CreateInfo(info, usage,
fProps.pixelGeometry())); fProps.pixelGeometry()));
if (NULL == device) { if (NULL == device) {
SkDebugf("Unable to create device for layer."); SkErrorInternals::SetError( kInternalError_SkError,
"Unable to create device for layer.");
return; return;
} }

View File

@ -280,6 +280,9 @@ bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const
true, true,
sigma.x(), sigma.x(),
sigma.y())); sigma.y()));
if (!tex) {
return false;
}
WrapTexture(tex, rect.width(), rect.height(), result); WrapTexture(tex, rect.width(), rect.height(), result);
return true; return true;
#else #else

View File

@ -965,6 +965,9 @@ GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma,
texDesc.fConfig = kAlpha_8_GrPixelConfig; texDesc.fConfig = kAlpha_8_GrPixelConfig;
blurNinePatchTexture = context->createTexture(texDesc, true, blurred_mask.fImage, 0); blurNinePatchTexture = context->createTexture(texDesc, true, blurred_mask.fImage, 0);
if (!blurNinePatchTexture) {
return NULL;
}
context->addResourceToCache(key, blurNinePatchTexture); context->addResourceToCache(key, blurNinePatchTexture);
SkMask::FreeImage(blurred_mask.fImage); SkMask::FreeImage(blurred_mask.fImage);

View File

@ -1130,6 +1130,9 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx,
fTextureAccess.reset(fAtlas->getTexture(), params); fTextureAccess.reset(fAtlas->getTexture(), params);
} else { } else {
SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(ctx, bitmap, &params)); SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(ctx, bitmap, &params));
if (!texture) {
return;
}
fCoordTransform.reset(kCoordSet, matrix, texture, params.filterMode()); fCoordTransform.reset(kCoordSet, matrix, texture, params.filterMode());
fTextureAccess.reset(texture, params); fTextureAccess.reset(texture, params);
fYCoord = SK_ScalarHalf; fYCoord = SK_ScalarHalf;

View File

@ -52,6 +52,9 @@ static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11;
static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4; static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4;
#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) #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 { class GrContext::AutoCheckFlush {
public: public:
@ -240,6 +243,7 @@ bool GrContext::npotTextureTileSupport() const {
GrTexture* GrContext::createTexture(const GrSurfaceDesc& desc, bool budgeted, const void* srcData, GrTexture* GrContext::createTexture(const GrSurfaceDesc& desc, bool budgeted, const void* srcData,
size_t rowBytes) { size_t rowBytes) {
RETURN_NULL_IF_ABANDONED
if ((desc.fFlags & kRenderTarget_GrSurfaceFlag) && if ((desc.fFlags & kRenderTarget_GrSurfaceFlag) &&
!this->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) { !this->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
return NULL; return NULL;
@ -263,6 +267,7 @@ GrTexture* GrContext::createTexture(const GrSurfaceDesc& desc, bool budgeted, co
GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMatch match, GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMatch match,
bool calledDuringFlush) { bool calledDuringFlush) {
RETURN_NULL_IF_ABANDONED
// Currently we don't recycle compressed textures as scratch. // Currently we don't recycle compressed textures as scratch.
if (GrPixelConfigIsCompressed(desc.fConfig)) { if (GrPixelConfigIsCompressed(desc.fConfig)) {
return NULL; return NULL;
@ -344,10 +349,12 @@ int GrContext::getMaxSampleCount() const {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
GrTexture* GrContext::wrapBackendTexture(const GrBackendTextureDesc& desc) { GrTexture* GrContext::wrapBackendTexture(const GrBackendTextureDesc& desc) {
RETURN_NULL_IF_ABANDONED
return fGpu->wrapBackendTexture(desc); return fGpu->wrapBackendTexture(desc);
} }
GrRenderTarget* GrContext::wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) { GrRenderTarget* GrContext::wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) {
RETURN_NULL_IF_ABANDONED
return fGpu->wrapBackendRenderTarget(desc); return fGpu->wrapBackendRenderTarget(desc);
} }
@ -357,6 +364,7 @@ void GrContext::clear(const SkIRect* rect,
const GrColor color, const GrColor color,
bool canIgnoreRect, bool canIgnoreRect,
GrRenderTarget* renderTarget) { GrRenderTarget* renderTarget) {
RETURN_IF_ABANDONED
ASSERT_OWNED_RESOURCE(renderTarget); ASSERT_OWNED_RESOURCE(renderTarget);
SkASSERT(renderTarget); SkASSERT(renderTarget);
@ -373,6 +381,7 @@ void GrContext::drawPaint(GrRenderTarget* rt,
const GrClip& clip, const GrClip& clip,
const GrPaint& origPaint, const GrPaint& origPaint,
const SkMatrix& viewMatrix) { const SkMatrix& viewMatrix) {
RETURN_IF_ABANDONED
// set rect to be big enough to fill the space, but not super-huge, so we // set rect to be big enough to fill the space, but not super-huge, so we
// don't overflow fixed-point implementations // don't overflow fixed-point implementations
SkRect r; SkRect r;
@ -507,6 +516,7 @@ void GrContext::drawRect(GrRenderTarget* rt,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const SkRect& rect, const SkRect& rect,
const GrStrokeInfo* strokeInfo) { const GrStrokeInfo* strokeInfo) {
RETURN_IF_ABANDONED
if (strokeInfo && strokeInfo->isDashed()) { if (strokeInfo && strokeInfo->isDashed()) {
SkPath path; SkPath path;
path.addRect(rect); path.addRect(rect);
@ -641,6 +651,7 @@ void GrContext::drawNonAARectToRect(GrRenderTarget* rt,
const SkRect& rectToDraw, const SkRect& rectToDraw,
const SkRect& localRect, const SkRect& localRect,
const SkMatrix* localMatrix) { const SkMatrix* localMatrix) {
RETURN_IF_ABANDONED
AutoCheckFlush acf(this); AutoCheckFlush acf(this);
GrPipelineBuilder pipelineBuilder; GrPipelineBuilder pipelineBuilder;
GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
@ -693,6 +704,7 @@ void GrContext::drawVertices(GrRenderTarget* rt,
const GrColor colors[], const GrColor colors[],
const uint16_t indices[], const uint16_t indices[],
int indexCount) { int indexCount) {
RETURN_IF_ABANDONED
AutoCheckFlush acf(this); AutoCheckFlush acf(this);
GrPipelineBuilder pipelineBuilder; GrPipelineBuilder pipelineBuilder;
GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope
@ -751,6 +763,7 @@ void GrContext::drawRRect(GrRenderTarget*rt,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const SkRRect& rrect, const SkRRect& rrect,
const GrStrokeInfo& strokeInfo) { const GrStrokeInfo& strokeInfo) {
RETURN_IF_ABANDONED
if (rrect.isEmpty()) { if (rrect.isEmpty()) {
return; return;
} }
@ -796,6 +809,7 @@ void GrContext::drawDRRect(GrRenderTarget* rt,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const SkRRect& outer, const SkRRect& outer,
const SkRRect& inner) { const SkRRect& inner) {
RETURN_IF_ABANDONED
if (outer.isEmpty()) { if (outer.isEmpty()) {
return; return;
} }
@ -833,6 +847,7 @@ void GrContext::drawOval(GrRenderTarget* rt,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const SkRect& oval, const SkRect& oval,
const GrStrokeInfo& strokeInfo) { const GrStrokeInfo& strokeInfo) {
RETURN_IF_ABANDONED
if (oval.isEmpty()) { if (oval.isEmpty()) {
return; return;
} }
@ -929,7 +944,7 @@ void GrContext::drawPath(GrRenderTarget* rt,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const SkPath& path, const SkPath& path,
const GrStrokeInfo& strokeInfo) { const GrStrokeInfo& strokeInfo) {
RETURN_IF_ABANDONED
if (path.isEmpty()) { if (path.isEmpty()) {
if (path.isInverseFillType()) { if (path.isInverseFillType()) {
this->drawPaint(rt, clip, paint, viewMatrix); this->drawPaint(rt, clip, paint, viewMatrix);
@ -1020,6 +1035,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target,
bool useAA, bool useAA,
const SkPath& path, const SkPath& path,
const GrStrokeInfo& strokeInfo) { const GrStrokeInfo& strokeInfo) {
RETURN_IF_ABANDONED
SkASSERT(!path.isEmpty()); SkASSERT(!path.isEmpty());
GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target);
@ -1110,7 +1126,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
int left, int top, int width, int height, int left, int top, int width, int height,
GrPixelConfig srcConfig, const void* buffer, size_t rowBytes, GrPixelConfig srcConfig, const void* buffer, size_t rowBytes,
uint32_t pixelOpsFlags) { uint32_t pixelOpsFlags) {
RETURN_FALSE_IF_ABANDONED
{ {
GrTexture* texture = NULL; GrTexture* texture = NULL;
if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asTexture()) && if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asTexture()) &&
@ -1240,6 +1256,7 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target,
int left, int top, int width, int height, int left, int top, int width, int height,
GrPixelConfig dstConfig, void* buffer, size_t rowBytes, GrPixelConfig dstConfig, void* buffer, size_t rowBytes,
uint32_t flags) { uint32_t flags) {
RETURN_FALSE_IF_ABANDONED
ASSERT_OWNED_RESOURCE(target); ASSERT_OWNED_RESOURCE(target);
SkASSERT(target); SkASSERT(target);
@ -1378,6 +1395,7 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target,
} }
void GrContext::prepareSurfaceForExternalRead(GrSurface* surface) { void GrContext::prepareSurfaceForExternalRead(GrSurface* surface) {
RETURN_IF_ABANDONED
SkASSERT(surface); SkASSERT(surface);
ASSERT_OWNED_RESOURCE(surface); ASSERT_OWNED_RESOURCE(surface);
if (surface->surfacePriv().hasPendingIO()) { if (surface->surfacePriv().hasPendingIO()) {
@ -1390,6 +1408,7 @@ void GrContext::prepareSurfaceForExternalRead(GrSurface* surface) {
} }
void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) { void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) {
RETURN_IF_ABANDONED
SkASSERT(renderTarget); SkASSERT(renderTarget);
ASSERT_OWNED_RESOURCE(renderTarget); ASSERT_OWNED_RESOURCE(renderTarget);
AutoCheckFlush acf(this); AutoCheckFlush acf(this);
@ -1402,6 +1421,7 @@ void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) {
void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint, uint32_t pixelOpsFlags) { const SkIPoint& dstPoint, uint32_t pixelOpsFlags) {
RETURN_IF_ABANDONED
if (NULL == src || NULL == dst) { if (NULL == src || NULL == dst) {
return; return;
} }
@ -1423,6 +1443,7 @@ void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe
} }
void GrContext::flushSurfaceWrites(GrSurface* surface) { void GrContext::flushSurfaceWrites(GrSurface* surface) {
RETURN_IF_ABANDONED
if (surface->surfacePriv().hasPendingWrite()) { if (surface->surfacePriv().hasPendingWrite()) {
this->flush(); this->flush();
} }
@ -1433,7 +1454,7 @@ GrDrawTarget* GrContext::prepareToDraw(GrPipelineBuilder* pipelineBuilder,
const GrClip& clip, const GrClip& clip,
const GrPaint* paint, const GrPaint* paint,
const AutoCheckFlush* acf) { const AutoCheckFlush* acf) {
if (NULL == fGpu) { if (NULL == fGpu || NULL == fDrawBuffer) {
return NULL; return NULL;
} }

View File

@ -40,6 +40,9 @@ bool GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPai
const SkPaint& skPaint, const SkMatrix& viewMatrix, const SkPaint& skPaint, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const char text[], size_t byteLength,
SkScalar x, SkScalar y) { SkScalar x, SkScalar y) {
if (!fContext->getTextTarget()) {
return false;
}
GrTextContext* textContext = this; GrTextContext* textContext = this;
do { do {
@ -58,6 +61,9 @@ bool GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const Gr
const char text[], size_t byteLength, const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition, const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset) { const SkPoint& offset) {
if (!fContext->getTextTarget()) {
return false;
}
GrTextContext* textContext = this; GrTextContext* textContext = this;
do { do {

View File

@ -1494,6 +1494,9 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
GrTexture* texture; GrTexture* texture;
// draw sprite uses the default texture params // draw sprite uses the default texture params
AutoBitmapTexture abt(fContext, bitmap, NULL, &texture); AutoBitmapTexture abt(fContext, bitmap, NULL, &texture);
if (!texture) {
return;
}
SkImageFilter* filter = paint.getImageFilter(); SkImageFilter* filter = paint.getImageFilter();
// This bitmap will own the filtered result as a texture. // This bitmap will own the filtered result as a texture.
@ -1882,7 +1885,8 @@ SkBaseDevice* SkGpuDevice::onCreateCompatibleDevice(const CreateInfo& cinfo) {
SkSurfaceProps props(fSurfaceProps.flags(), cinfo.fPixelGeometry); SkSurfaceProps props(fSurfaceProps.flags(), cinfo.fPixelGeometry);
return SkGpuDevice::Create(texture->asRenderTarget(), &props, flags); return SkGpuDevice::Create(texture->asRenderTarget(), &props, flags);
} else { } else {
SkDebugf("---- failed to create compatible device texture [%d %d]\n", SkErrorInternals::SetError( kInternalError_SkError,
"---- failed to create compatible device texture [%d %d]\n",
cinfo.fInfo.width(), cinfo.fInfo.height()); cinfo.fInfo.width(), cinfo.fInfo.height());
return NULL; return NULL;
} }

View File

@ -57,7 +57,7 @@ public:
return static_cast<SkGpuDevice*>(dev); return static_cast<SkGpuDevice*>(dev);
} }
GrContext* context() const { return fRenderTarget->getContext(); } GrContext* context() const { return fContext; }
// set all pixels to 0 // set all pixels to 0
void clearAll(); void clearAll();

View File

@ -11,6 +11,7 @@
#include "SkColorFilter.h" #include "SkColorFilter.h"
#include "SkConfig8888.h" #include "SkConfig8888.h"
#include "SkData.h" #include "SkData.h"
#include "SkErrorInternals.h"
#include "SkMessageBus.h" #include "SkMessageBus.h"
#include "SkPixelRef.h" #include "SkPixelRef.h"
#include "SkResourceCache.h" #include "SkResourceCache.h"
@ -560,7 +561,8 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
return result; return result;
} }
SkDebugf("---- failed to create texture for cache [%d %d]\n", SkErrorInternals::SetError( kInternalError_SkError,
"---- failed to create texture for cache [%d %d]\n",
bitmap.width(), bitmap.height()); bitmap.width(), bitmap.height());
return NULL; return NULL;

View File

@ -92,6 +92,9 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& data) {
VALIDATE; VALIDATE;
if (0 == fLockedRows) { if (0 == fLockedRows) {
this->lockTexture(); this->lockTexture();
if (!fTexture) {
return -1;
}
} }
int key = data.getGenerationID(); int key = data.getGenerationID();
@ -204,6 +207,9 @@ void GrTextureStripAtlas::lockTexture() {
fTexture = fDesc.fContext->findAndRefCachedTexture(key); fTexture = fDesc.fContext->findAndRefCachedTexture(key);
if (NULL == fTexture) { if (NULL == fTexture) {
fTexture = fDesc.fContext->createTexture(texDesc, true, NULL, 0); fTexture = fDesc.fContext->createTexture(texDesc, true, NULL, 0);
if (!fTexture) {
return;
}
fDesc.fContext->addResourceToCache(key, fTexture); fDesc.fContext->addResourceToCache(key, fTexture);
// This is a new texture, so all of our cache info is now invalid // This is a new texture, so all of our cache info is now invalid
this->initLRU(); this->initLRU();

View File

@ -39,6 +39,8 @@ DEFINE_string2(match, m, NULL,
DEFINE_bool2(quiet, q, false, "if true, don't print status updates."); 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_bool(abandonGpuContext, false, "Abandon the GrContext after running each test.");
DEFINE_string(skps, "skps", "Directory to read skps from."); DEFINE_string(skps, "skps", "Directory to read skps from.");

View File

@ -20,6 +20,7 @@ DECLARE_bool(leaks);
DECLARE_string(match); DECLARE_string(match);
DECLARE_bool(quiet); DECLARE_bool(quiet);
DECLARE_bool(resetGpuContext); DECLARE_bool(resetGpuContext);
DECLARE_bool(preAbandonGpuContext);
DECLARE_bool(abandonGpuContext); DECLARE_bool(abandonGpuContext);
DECLARE_string(skps); DECLARE_string(skps);
DECLARE_int32(threads); DECLARE_int32(threads);