aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/gpu/mock/GrMockTypes.h7
-rw-r--r--src/gpu/GrDrawingManager.cpp23
-rw-r--r--src/gpu/ccpr/GrCoverageCountingPathRenderer.h10
-rw-r--r--src/gpu/mock/GrMockGpu.cpp7
-rw-r--r--src/gpu/mock/GrMockGpu.h2
-rw-r--r--tests/GrCCPRTest.cpp9
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));