diff options
-rw-r--r-- | include/gpu/mock/GrMockTypes.h | 7 | ||||
-rw-r--r-- | src/gpu/GrDrawingManager.cpp | 23 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCoverageCountingPathRenderer.h | 10 | ||||
-rw-r--r-- | src/gpu/mock/GrMockGpu.cpp | 7 | ||||
-rw-r--r-- | src/gpu/mock/GrMockGpu.h | 2 | ||||
-rw-r--r-- | tests/GrCCPRTest.cpp | 9 |
6 files changed, 48 insertions, 10 deletions
diff --git a/include/gpu/mock/GrMockTypes.h b/include/gpu/mock/GrMockTypes.h index 5ca0730956..2d559a95a5 100644 --- a/include/gpu/mock/GrMockTypes.h +++ b/include/gpu/mock/GrMockTypes.h @@ -52,7 +52,7 @@ struct GrMockOptions { bool fTexturable = false; }; - // GPU options. + // GrCaps options. bool fInstanceAttribSupport = false; uint32_t fMapBufferFlags = 0; int fMaxTextureSize = 2048; @@ -60,7 +60,7 @@ struct GrMockOptions { int fMaxVertexAttributes = 16; ConfigOptions fConfigOptions[kGrPixelConfigCnt]; - // Shader options. + // GrShaderCaps options. bool fGeometryShaderSupport = false; bool fTexelBufferSupport = false; bool fIntegerSupport = false; @@ -68,6 +68,9 @@ struct GrMockOptions { int fMaxVertexSamplers = 0; int fMaxFragmentSamplers = 8; bool fShaderDerivativeSupport = true; + + // GrMockGpu options. + bool fFailTextureAllocations = false; }; #endif diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index d0e3cfea74..86fee30925 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -226,6 +226,14 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*, } } +#ifdef SK_DEBUG + for (const auto& opList : fOpLists) { + // If there are any remaining opLists at this point, make sure they will not survive the + // flush. Otherwise we need to call endFlush() on them. + // http://skbug.com/7111 + SkASSERT(!opList || opList->unique()); + } +#endif fOpLists.reset(); GrSemaphoresSubmitted result = gpu->finishFlush(numSemaphores, backendSemaphores); @@ -246,6 +254,13 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*, return result; } +static void end_oplist_flush_if_not_unique(const sk_sp<GrOpList>& opList) { + if (!opList->unique()) { + // TODO: Eventually this should be guaranteed unique: http://skbug.com/7111 + opList->endFlush(); + } +} + bool GrDrawingManager::executeOpLists(int startIndex, int stopIndex, GrOpFlushState* flushState) { SkASSERT(startIndex <= stopIndex && stopIndex <= fOpLists.count()); @@ -260,12 +275,14 @@ bool GrDrawingManager::executeOpLists(int startIndex, int stopIndex, GrOpFlushSt if (resourceProvider->explicitlyAllocateGPUResources()) { if (!fOpLists[i]->isInstantiated()) { // If the backing surface wasn't allocated drop the draw of the entire opList. + end_oplist_flush_if_not_unique(fOpLists[i]); // http://skbug.com/7111 fOpLists[i] = nullptr; continue; } } else { if (!fOpLists[i]->instantiate(resourceProvider)) { SkDebugf("OpList failed to instantiate.\n"); + end_oplist_flush_if_not_unique(fOpLists[i]); // http://skbug.com/7111 fOpLists[i] = nullptr; continue; } @@ -313,11 +330,7 @@ bool GrDrawingManager::executeOpLists(int startIndex, int stopIndex, GrOpFlushSt if (!fOpLists[i]) { continue; } - if (!fOpLists[i]->unique()) { - // TODO: Eventually this should be guaranteed unique. - // https://bugs.chromium.org/p/skia/issues/detail?id=7111 - fOpLists[i]->endFlush(); - } + end_oplist_flush_if_not_unique(fOpLists[i]); // http://skbug.com/7111 fOpLists[i] = nullptr; } diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.h b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h index 40b9d5d06e..ba214f5843 100644 --- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.h +++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h @@ -205,8 +205,14 @@ private: struct RTPendingPaths { ~RTPendingPaths() { - // Ensure all DrawPathsOps in this opList have been deleted. - SkASSERT(fDrawOps.isEmpty()); + // Ensure there are no surviving DrawPathsOps with a dangling pointer into this class. + if (!fDrawOps.isEmpty()) { + SK_ABORT("CCPR DrawPathsOp(s) not deleted during flush"); + } + // Clip lazy proxies also reference this class from their callbacks, but those callbacks + // are only invoked at flush time while we are still alive. (Unlike DrawPathsOps, that + // unregister themselves upon destruction.) So it shouldn't matter if any clip proxies + // are still around. } SkTInternalLList<DrawPathsOp> fDrawOps; diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp index 0d4cf6296b..59c04af1ad 100644 --- a/src/gpu/mock/GrMockGpu.cpp +++ b/src/gpu/mock/GrMockGpu.cpp @@ -69,12 +69,17 @@ void GrMockGpu::submitCommandBuffer(const GrMockGpuRTCommandBuffer* cmdBuffer) { GrMockGpu::GrMockGpu(GrContext* context, const GrMockOptions& options, const GrContextOptions& contextOptions) - : INHERITED(context) { + : INHERITED(context) + , fMockOptions(options) { fCaps.reset(new GrMockCaps(contextOptions, options)); } sk_sp<GrTexture> GrMockGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, const GrMipLevel texels[], int mipLevelCount) { + if (fMockOptions.fFailTextureAllocations) { + return nullptr; + } + GrMipMapsStatus mipMapsStatus = mipLevelCount > 1 ? GrMipMapsStatus::kValid : GrMipMapsStatus::kNotAllocated; GrMockTextureInfo texInfo; diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h index 73e6a4bfc5..0b3ef079cf 100644 --- a/src/gpu/mock/GrMockGpu.h +++ b/src/gpu/mock/GrMockGpu.h @@ -126,6 +126,8 @@ private: void testingOnly_flushGpuAndSync() override {} #endif + const GrMockOptions fMockOptions; + static int NextInternalTextureID(); static int NextExternalTextureID(); static int NextInternalRenderTargetID(); diff --git a/tests/GrCCPRTest.cpp b/tests/GrCCPRTest.cpp index 2a51c1b176..6f0d8852d9 100644 --- a/tests/GrCCPRTest.cpp +++ b/tests/GrCCPRTest.cpp @@ -126,6 +126,7 @@ public: mockOptions.fGeometryShaderSupport = true; mockOptions.fIntegerSupport = true; mockOptions.fFlatInterpolationSupport = true; + this->customizeMockOptions(&mockOptions); GrContextOptions ctxOptions; ctxOptions.fAllowPathMaskCaching = false; @@ -154,6 +155,7 @@ public: virtual ~CCPRTest() {} protected: + virtual void customizeMockOptions(GrMockOptions*) {} virtual void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) = 0; sk_sp<GrContext> fMockContext; @@ -192,6 +194,13 @@ class GrCCPRTest_cleanup : public CCPRTest { }; DEF_CCPR_TEST(GrCCPRTest_cleanup) +class GrCCPRTest_cleanupWithTexAllocFail : public GrCCPRTest_cleanup { + void customizeMockOptions(GrMockOptions* options) override { + options->fFailTextureAllocations = true; + } +}; +DEF_CCPR_TEST(GrCCPRTest_cleanupWithTexAllocFail) + class GrCCPRTest_unregisterCulledOps : public CCPRTest { void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) override { REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath)); |