aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-05-01 13:12:20 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-03 16:59:37 +0000
commita91e0b7cc2537dc57ccf67914638e13b4612ffd1 (patch)
tree858fb3b4d98cb07461468f9b9ea1935f7950392e
parent7eb86981a954c500fa4a4d8425496a5beb789e5d (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.cpp4
-rw-r--r--src/gpu/GrGpuCommandBuffer.cpp4
-rw-r--r--src/gpu/GrGpuResourceRef.cpp14
-rw-r--r--src/gpu/GrPipeline.cpp9
-rw-r--r--src/gpu/GrPipeline.h4
-rw-r--r--src/gpu/GrProcessor.cpp24
-rw-r--r--src/gpu/GrProcessor.h9
-rw-r--r--src/gpu/effects/GrBitmapTextGeoProc.cpp7
-rw-r--r--src/gpu/effects/GrDistanceFieldGeoProc.cpp14
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp2
-rw-r--r--tests/ProcessorTest.cpp4
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;