diff options
author | Robert Phillips <robertphillips@google.com> | 2017-05-01 13:12:20 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-05-03 16:59:37 +0000 |
commit | a91e0b7cc2537dc57ccf67914638e13b4612ffd1 (patch) | |
tree | 858fb3b4d98cb07461468f9b9ea1935f7950392e | |
parent | 7eb86981a954c500fa4a4d8425496a5beb789e5d (diff) |
Allow TextureSamplers to have null GrTexture pointer
Bug: 715488
Change-Id: I69775cbb50d334d81872e236e59368fe65e698ff
Reviewed-on: https://skia-review.googlesource.com/14605
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
-rw-r--r-- | src/gpu/GrFragmentProcessor.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrGpuCommandBuffer.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrGpuResourceRef.cpp | 14 | ||||
-rw-r--r-- | src/gpu/GrPipeline.cpp | 9 | ||||
-rw-r--r-- | src/gpu/GrPipeline.h | 4 | ||||
-rw-r--r-- | src/gpu/GrProcessor.cpp | 24 | ||||
-rw-r--r-- | src/gpu/GrProcessor.h | 9 | ||||
-rw-r--r-- | src/gpu/effects/GrBitmapTextGeoProc.cpp | 7 | ||||
-rw-r--r-- | src/gpu/effects/GrDistanceFieldGeoProc.cpp | 14 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.cpp | 2 | ||||
-rw-r--r-- | tests/ProcessorTest.cpp | 4 |
11 files changed, 76 insertions, 19 deletions
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp index 462766af0c..b0a36fce6d 100644 --- a/src/gpu/GrFragmentProcessor.cpp +++ b/src/gpu/GrFragmentProcessor.cpp @@ -62,6 +62,10 @@ void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) { } int GrFragmentProcessor::registerChildProcessor(sk_sp<GrFragmentProcessor> child) { + if (child->isBad()) { + this->markAsBad(); + } + this->combineRequiredFeatures(*child); if (child->usesLocalCoords()) { diff --git a/src/gpu/GrGpuCommandBuffer.cpp b/src/gpu/GrGpuCommandBuffer.cpp index 4eb98433ef..b51d3ea22a 100644 --- a/src/gpu/GrGpuCommandBuffer.cpp +++ b/src/gpu/GrGpuCommandBuffer.cpp @@ -39,6 +39,10 @@ bool GrGpuCommandBuffer::draw(const GrPipeline& pipeline, const GrMesh* mesh, int meshCount, const SkRect& bounds) { + if (pipeline.isBad() || primProc.isBad()) { + return false; + } + SkASSERT(pipeline.isInitialized()); if (primProc.numAttribs() > this->gpu()->caps()->maxVertexAttributes()) { this->gpu()->stats()->incNumFailedDraws(); diff --git a/src/gpu/GrGpuResourceRef.cpp b/src/gpu/GrGpuResourceRef.cpp index 405679d4f1..532e0655d8 100644 --- a/src/gpu/GrGpuResourceRef.cpp +++ b/src/gpu/GrGpuResourceRef.cpp @@ -66,10 +66,13 @@ void GrGpuResourceRef::setResource(GrGpuResource* resource, GrIOType ioType) { } void GrGpuResourceRef::markPendingIO() const { + if (!fResource) { + return; + } + // This should only be called when the owning GrProgramElement gets its first // pendingExecution ref. SkASSERT(!fPendingIO); - SkASSERT(fResource); fPendingIO = true; switch (fIOType) { case kRead_GrIOType: @@ -86,6 +89,10 @@ void GrGpuResourceRef::markPendingIO() const { } void GrGpuResourceRef::pendingIOComplete() const { + if (!fResource) { + return; + } + // This should only be called when the owner's pending executions have ocurred but it is still // reffed. SkASSERT(fOwnRef); @@ -107,11 +114,14 @@ void GrGpuResourceRef::pendingIOComplete() const { } void GrGpuResourceRef::removeRef() const { + if (!fResource) { + return; + } + // This should only be called once, when the owners last ref goes away and // there is a pending execution. SkASSERT(fOwnRef); SkASSERT(fPendingIO); - SkASSERT(fResource); fResource->unref(); fOwnRef = false; } diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp index 1471b57f4f..78fb759154 100644 --- a/src/gpu/GrPipeline.cpp +++ b/src/gpu/GrPipeline.cpp @@ -64,15 +64,24 @@ void GrPipeline::init(const InitArgs& args) { for (int i = 0; i < args.fProcessors->numColorFragmentProcessors(); ++i, ++currFPIdx) { const GrFragmentProcessor* fp = args.fProcessors->colorFragmentProcessor(i); fFragmentProcessors[currFPIdx].reset(fp); + if (fp->isBad()) { + this->markAsBad(); + } } for (int i = 0; i < args.fProcessors->numCoverageFragmentProcessors(); ++i, ++currFPIdx) { const GrFragmentProcessor* fp = args.fProcessors->coverageFragmentProcessor(i); fFragmentProcessors[currFPIdx].reset(fp); + if (fp->isBad()) { + this->markAsBad(); + } } if (args.fAppliedClip) { if (const GrFragmentProcessor* fp = args.fAppliedClip->clipCoverageFragmentProcessor()) { fFragmentProcessors[currFPIdx].reset(fp); + if (fp->isBad()) { + this->markAsBad(); + } } } } diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h index 01d375ec64..3bac5f79e0 100644 --- a/src/gpu/GrPipeline.h +++ b/src/gpu/GrPipeline.h @@ -213,6 +213,7 @@ public: bool isStencilEnabled() const { return SkToBool(fFlags & kStencilEnabled_Flag); } + bool isBad() const { return SkToBool(fFlags & kIsBad_Flag); } GrXferBarrierType xferBarrierType(const GrCaps& caps) const { if (fDstTexture.get() && fDstTexture.get() == fRenderTarget.get()->asTexture()) { @@ -229,11 +230,14 @@ public: GrDrawFace getDrawFace() const { return static_cast<GrDrawFace>(fDrawFace); } private: + void markAsBad() { fFlags |= kIsBad_Flag; } + /** This is a continuation of the public "Flags" enum. */ enum PrivateFlags { kUsesDistanceVectorField_Flag = 0x10, kHasStencilClip_Flag = 0x20, kStencilEnabled_Flag = 0x40, + kIsBad_Flag = 0x80, }; using RenderTarget = GrPendingIOResource<GrRenderTarget, kWrite_GrIOType>; diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp index 4856c42a34..c5ccc3fbc9 100644 --- a/src/gpu/GrProcessor.cpp +++ b/src/gpu/GrProcessor.cpp @@ -129,6 +129,10 @@ void GrProcessor::operator delete(void* target) { /////////////////////////////////////////////////////////////////////////////// void GrResourceIOProcessor::addTextureSampler(const TextureSampler* access) { + if (access->isBad()) { + this->markAsBad(); + } + fTextureSamplers.push_back(access); } @@ -234,13 +238,17 @@ void GrResourceIOProcessor::TextureSampler::reset(GrResourceProvider* resourcePr sk_sp<GrTextureProxy> proxy, const GrSamplerParams& params, GrShaderFlags visibility) { + fParams = params; + // For now, end the deferral at this time. Once all the TextureSamplers are swapped over // to taking a GrSurfaceProxy just use the IORefs on the proxy GrTexture* texture = proxy->instantiate(resourceProvider); - SkASSERT(texture); - fTexture.set(SkRef(texture), kRead_GrIOType); - fParams = params; - fParams.setFilterMode(SkTMin(params.filterMode(), texture->texturePriv().highestFilterMode())); + if (texture) { + fTexture.set(SkRef(texture), kRead_GrIOType); + fParams.setFilterMode(SkTMin(params.filterMode(), + texture->texturePriv().highestFilterMode())); + } + fVisibility = visibility; } @@ -252,9 +260,11 @@ void GrResourceIOProcessor::TextureSampler::reset(GrResourceProvider* resourcePr // For now, end the deferral at this time. Once all the TextureSamplers are swapped over // to taking a GrSurfaceProxy just use the IORefs on the proxy GrTexture* texture = proxy->instantiate(resourceProvider); - SkASSERT(texture); - fTexture.set(SkRef(texture), kRead_GrIOType); - filterMode = SkTMin(filterMode, texture->texturePriv().highestFilterMode()); + if (texture) { + fTexture.set(SkRef(texture), kRead_GrIOType); + filterMode = SkTMin(filterMode, texture->texturePriv().highestFilterMode()); + } + fParams.reset(tileXAndY, filterMode); fVisibility = visibility; } diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h index 1816db2ea5..7011267c76 100644 --- a/src/gpu/GrProcessor.h +++ b/src/gpu/GrProcessor.h @@ -176,8 +176,10 @@ public: return *fImageStorageAccesses[index]; } + bool isBad() const { return fIsBad; } + protected: - GrResourceIOProcessor() = default; + GrResourceIOProcessor() : fIsBad(false) {} /** * Subclasses call these from their constructor to register sampler/image sources. The processor @@ -196,10 +198,13 @@ protected: void removeRefs() const; void pendingIOComplete() const; + void markAsBad() { fIsBad = true; } + private: SkSTArray<4, const TextureSampler*, true> fTextureSamplers; SkSTArray<1, const BufferAccess*, true> fBufferAccesses; SkSTArray<1, const ImageStorageAccess*, true> fImageStorageAccesses; + bool fIsBad; typedef GrProcessor INHERITED; }; @@ -252,6 +257,8 @@ public: */ const GrGpuResourceRef* programTexture() const { return &fTexture; } + bool isBad() const { return !fTexture.get(); } + private: typedef GrTGpuResourceRef<GrTexture> ProgramTexture; diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index 527d5ce276..470af46783 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -105,9 +105,10 @@ public: // Currently we hardcode numbers to convert atlas coordinates to normalized floating point SkASSERT(gp.numTextureSamplers() == 1); GrTexture* atlas = gp.textureSampler(0).texture(); - SkASSERT(atlas); - b->add32(atlas->width()); - b->add32(atlas->height()); + if (atlas) { + b->add32(atlas->width()); + b->add32(atlas->height()); + } } private: diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index 82f8880530..5ad2ef2ced 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -203,9 +203,10 @@ public: // Currently we hardcode numbers to convert atlas coordinates to normalized floating point SkASSERT(gp.numTextureSamplers() == 1); GrTexture* atlas = gp.textureSampler(0).texture(); - SkASSERT(atlas); - b->add32(atlas->width()); - b->add32(atlas->height()); + if (atlas) { + b->add32(atlas->width()); + b->add32(atlas->height()); + } } private: @@ -759,9 +760,10 @@ public: // Currently we hardcode numbers to convert atlas coordinates to normalized floating point SkASSERT(gp.numTextureSamplers() == 1); GrTexture* atlas = gp.textureSampler(0).texture(); - SkASSERT(atlas); - b->add32(atlas->width()); - b->add32(atlas->height()); + if (atlas) { + b->add32(atlas->width()); + b->add32(atlas->height()); + } } private: diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index 03518194bc..8e6901d0cc 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -33,6 +33,8 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc, GrProgramDesc* desc, GrGLGpu* gpu) { + SkASSERT(!pipeline.isBad() && !primProc.isBad()); + ATRACE_ANDROID_FRAMEWORK("Shader Compile"); GrAutoLocaleSetter als("C"); diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp index e5bbc92759..29ea29f9a2 100644 --- a/tests/ProcessorTest.cpp +++ b/tests/ProcessorTest.cpp @@ -350,6 +350,10 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(ProcessorOptimizationValidationTest, repor } for (int j = 0; j < timesToInvokeFactory; ++j) { fp = FPFactory::MakeIdx(i, &testData); + if (fp->isBad()) { + continue; + } + if (!fp->hasConstantOutputForConstantInput() && !fp->preservesOpaqueInput() && !fp->compatibleWithCoverageAsAlpha()) { continue; |