From 1de610a5287cf61d4f3a1fdc7413bd74827a8b6a Mon Sep 17 00:00:00 2001 From: joshualitt Date: Wed, 6 Jan 2016 08:26:09 -0800 Subject: Create debug only SkSingleOwner This is so Gpu code can guard against improper multithreaded usage in debug builds TBR=bsalomon@google.com BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1555953004 Review URL: https://codereview.chromium.org/1555953004 --- src/gpu/GrContext.cpp | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'src/gpu/GrContext.cpp') diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 2b20e17ae1..854ff742f3 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -23,6 +23,8 @@ #include "text/GrTextBlobCache.h" #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) +#define ASSERT_SINGLE_OWNER \ + SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fSingleOwner);) #define RETURN_IF_ABANDONED if (fDrawingManager->abandoned()) { return; } #define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->abandoned()) { return false; } #define RETURN_NULL_IF_ABANDONED if (fDrawingManager->abandoned()) { return nullptr; } @@ -66,6 +68,7 @@ GrContext::GrContext() : fUniqueID(next_id()) { bool GrContext::init(GrBackend backend, GrBackendContext backendContext, const GrContextOptions& options) { + ASSERT_SINGLE_OWNER SkASSERT(!fGpu); fGpu = GrGpu::Create(backend, backendContext, options, this); @@ -77,6 +80,8 @@ bool GrContext::init(GrBackend backend, GrBackendContext backendContext, } void GrContext::initCommon(const GrContextOptions& options) { + ASSERT_SINGLE_OWNER + fCaps = SkRef(fGpu->caps()); fResourceCache = new GrResourceCache(fCaps); fResourceCache->setOverBudgetCallback(OverBudgetCB, this); @@ -99,6 +104,8 @@ void GrContext::initCommon(const GrContextOptions& options) { } GrContext::~GrContext() { + ASSERT_SINGLE_OWNER + if (!fGpu) { SkASSERT(!fCaps); return; @@ -121,6 +128,8 @@ GrContext::~GrContext() { } void GrContext::abandonContext() { + ASSERT_SINGLE_OWNER + fResourceProvider->abandon(); // Need to abandon the drawing manager first so all the render targets @@ -139,10 +148,13 @@ void GrContext::abandonContext() { } void GrContext::resetContext(uint32_t state) { + ASSERT_SINGLE_OWNER fGpu->markContextDirty(state); } void GrContext::freeGpuResources() { + ASSERT_SINGLE_OWNER + this->flush(); fBatchFontCache->freeAll(); @@ -154,6 +166,8 @@ void GrContext::freeGpuResources() { } void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const { + ASSERT_SINGLE_OWNER + if (resourceCount) { *resourceCount = fResourceCache->getBudgetedResourceCount(); } @@ -187,6 +201,7 @@ void GrContext::TextBlobCacheOverBudgetCB(void* data) { //////////////////////////////////////////////////////////////////////////////// void GrContext::flush(int flagsBitfield) { + ASSERT_SINGLE_OWNER RETURN_IF_ABANDONED if (kDiscard_FlushBit & flagsBitfield) { @@ -221,6 +236,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) { + ASSERT_SINGLE_OWNER RETURN_FALSE_IF_ABANDONED ASSERT_OWNED_RESOURCE(surface); SkASSERT(surface); @@ -359,6 +375,7 @@ bool GrContext::readSurfacePixels(GrSurface* src, int left, int top, int width, int height, GrPixelConfig dstConfig, void* buffer, size_t rowBytes, uint32_t flags) { + ASSERT_SINGLE_OWNER RETURN_FALSE_IF_ABANDONED ASSERT_OWNED_RESOURCE(src); SkASSERT(src); @@ -486,6 +503,7 @@ bool GrContext::readSurfacePixels(GrSurface* src, } void GrContext::prepareSurfaceForExternalIO(GrSurface* surface) { + ASSERT_SINGLE_OWNER RETURN_IF_ABANDONED SkASSERT(surface); ASSERT_OWNED_RESOURCE(surface); @@ -500,6 +518,7 @@ void GrContext::prepareSurfaceForExternalIO(GrSurface* surface) { void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint, uint32_t pixelOpsFlags) { + ASSERT_SINGLE_OWNER RETURN_IF_ABANDONED if (!src || !dst) { return; @@ -526,6 +545,7 @@ void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe } void GrContext::flushSurfaceWrites(GrSurface* surface) { + ASSERT_SINGLE_OWNER RETURN_IF_ABANDONED if (surface->surfacePriv().hasPendingWrite()) { this->flush(); @@ -535,6 +555,8 @@ void GrContext::flushSurfaceWrites(GrSurface* surface) { //////////////////////////////////////////////////////////////////////////////// int GrContext::getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const { + ASSERT_SINGLE_OWNER + if (!this->caps()->isConfigRenderable(config, true)) { return 0; } @@ -552,10 +574,12 @@ int GrContext::getRecommendedSampleCount(GrPixelConfig config, GrDrawContext* GrContext::drawContext(GrRenderTarget* rt, const SkSurfaceProps* surfaceProps) { + ASSERT_SINGLE_OWNER return fDrawingManager->drawContext(rt, surfaceProps); } -bool GrContext::abandoned() const { +bool GrContext::abandoned() const { + ASSERT_SINGLE_OWNER return fDrawingManager->abandoned(); } @@ -570,6 +594,7 @@ void test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) { } void GrContext::testPMConversionsIfNecessary(uint32_t flags) { + ASSERT_SINGLE_OWNER if (SkToBool(kUnpremul_PixelOpsFlag & flags)) { SkAutoMutexAcquire ama(fTestPMConversionsMutex); if (!fDidTestPMConversions) { @@ -582,6 +607,7 @@ void GrContext::testPMConversionsIfNecessary(uint32_t flags) { const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture, bool swapRAndB, const SkMatrix& matrix) const { + ASSERT_SINGLE_OWNER // We should have already called this->testPMConversionsIfNecessary(). SkASSERT(fDidTestPMConversions); GrConfigConversionEffect::PMConversion pmToUPM = @@ -596,6 +622,7 @@ const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture, const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture, bool swapRAndB, const SkMatrix& matrix) const { + ASSERT_SINGLE_OWNER // We should have already called this->testPMConversionsIfNecessary(). SkASSERT(fDidTestPMConversions); GrConfigConversionEffect::PMConversion upmToPM = @@ -608,6 +635,7 @@ const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture, } bool GrContext::didFailPMUPMConversionTest() const { + ASSERT_SINGLE_OWNER // We should have already called this->testPMConversionsIfNecessary(). SkASSERT(fDidTestPMConversions); // The PM<->UPM tests fail or succeed together so we only need to check one. @@ -617,6 +645,7 @@ bool GrContext::didFailPMUPMConversionTest() const { ////////////////////////////////////////////////////////////////////////////// void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const { + ASSERT_SINGLE_OWNER if (maxTextures) { *maxTextures = fResourceCache->getMaxResourceCount(); } @@ -626,11 +655,13 @@ void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes } void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) { + ASSERT_SINGLE_OWNER fResourceCache->setLimits(maxTextures, maxTextureBytes); } ////////////////////////////////////////////////////////////////////////////// void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { + ASSERT_SINGLE_OWNER fResourceCache->dumpMemoryStatistics(traceMemoryDump); } -- cgit v1.2.3