diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrGpuResource.cpp | 34 | ||||
-rw-r--r-- | src/gpu/GrGpuResourceCacheAccess.h | 20 | ||||
-rw-r--r-- | src/gpu/GrResourceCache2.cpp | 38 | ||||
-rw-r--r-- | src/gpu/GrResourceCache2.h | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLIndexBuffer.h | 1 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPath.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPath.h | 1 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathRange.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathRange.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLRenderTarget.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLStencilBuffer.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLStencilBuffer.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLTexture.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLTextureRenderTarget.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLVertexBuffer.h | 1 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 31 |
16 files changed, 69 insertions, 83 deletions
diff --git a/src/gpu/GrGpuResource.cpp b/src/gpu/GrGpuResource.cpp index be8ea0daf0..fcc5f4de50 100644 --- a/src/gpu/GrGpuResource.cpp +++ b/src/gpu/GrGpuResource.cpp @@ -36,26 +36,24 @@ void GrGpuResource::registerWithCache() { } GrGpuResource::~GrGpuResource() { - // subclass should have released this. + // The cache should have released or destroyed this resource. SkASSERT(this->wasDestroyed()); } void GrGpuResource::release() { - if (fGpu) { - this->onRelease(); - get_resource_cache2(fGpu)->resourceAccess().removeResource(this); - fGpu = NULL; - fGpuMemorySize = 0; - } + SkASSERT(fGpu); + this->onRelease(); + get_resource_cache2(fGpu)->resourceAccess().removeResource(this); + fGpu = NULL; + fGpuMemorySize = 0; } void GrGpuResource::abandon() { - if (fGpu) { - this->onAbandon(); - get_resource_cache2(fGpu)->resourceAccess().removeResource(this); - fGpu = NULL; - fGpuMemorySize = 0; - } + SkASSERT(fGpu); + this->onAbandon(); + get_resource_cache2(fGpu)->resourceAccess().removeResource(this); + fGpu = NULL; + fGpuMemorySize = 0; } const GrContext* GrGpuResource::getContext() const { @@ -90,7 +88,7 @@ bool GrGpuResource::setContentKey(const GrResourceKey& contentKey) { SkASSERT(!contentKey.isScratch()); SkASSERT(this->internalHasRef()); - if (fContentKeySet) { + if (fContentKeySet || this->wasDestroyed()) { return false; } @@ -105,8 +103,12 @@ bool GrGpuResource::setContentKey(const GrResourceKey& contentKey) { } void GrGpuResource::notifyIsPurgable() const { - if (!this->wasDestroyed()) { - get_resource_cache2(fGpu)->resourceAccess().notifyPurgable(this); + if (this->wasDestroyed()) { + // We've already been removed from the cache. Goodbye cruel world! + SkDELETE(this); + } else { + GrGpuResource* mutableThis = const_cast<GrGpuResource*>(this); + get_resource_cache2(fGpu)->resourceAccess().notifyPurgable(mutableThis); } } diff --git a/src/gpu/GrGpuResourceCacheAccess.h b/src/gpu/GrGpuResourceCacheAccess.h index 7417a55a71..3c3786d053 100644 --- a/src/gpu/GrGpuResourceCacheAccess.h +++ b/src/gpu/GrGpuResourceCacheAccess.h @@ -54,6 +54,26 @@ public: return NULL; } + /** + * Called by the cache to delete the resource under normal circumstances. + */ + void release() { + fResource->release(); + if (fResource->isPurgable()) { + SkDELETE(fResource); + } + } + + /** + * Called by the cache to delete the resource when the backend 3D context is no longer valid. + */ + void abandon() { + fResource->abandon(); + if (fResource->isPurgable()) { + SkDELETE(fResource); + } + } + private: CacheAccess(GrGpuResource* resource) : fResource(resource) { } CacheAccess(const CacheAccess& that) : fResource(that.fResource) { } diff --git a/src/gpu/GrResourceCache2.cpp b/src/gpu/GrResourceCache2.cpp index 53e7f88112..3f7498c325 100644 --- a/src/gpu/GrResourceCache2.cpp +++ b/src/gpu/GrResourceCache2.cpp @@ -93,7 +93,6 @@ void GrResourceCache2::insertResource(GrGpuResource* resource) { SkASSERT(!this->isInCache(resource)); SkASSERT(!fPurging); fResources.addToHead(resource); - resource->ref(); ++fCount; SkDEBUGCODE(fHighWaterCount = SkTMax(fCount, fHighWaterCount)); @@ -129,8 +128,7 @@ void GrResourceCache2::abandonAll() { SkASSERT(!fPurging); while (GrGpuResource* head = fResources.head()) { SkASSERT(!head->wasDestroyed()); - head->abandon(); - head->unref(); + head->cacheAccess().abandon(); // abandon should have already removed this from the list. SkASSERT(head != fResources.head()); } @@ -145,8 +143,7 @@ void GrResourceCache2::releaseAll() { SkASSERT(!fPurging); while (GrGpuResource* head = fResources.head()) { SkASSERT(!head->wasDestroyed()); - head->release(); - head->unref(); + head->cacheAccess().release(); // release should have already removed this from the list. SkASSERT(head != fResources.head()); } @@ -159,7 +156,7 @@ public: AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendingIO) { } bool operator()(const GrGpuResource* resource) const { - if (!resource->reffedOnlyByCache() || !resource->cacheAccess().isScratch()) { + if (resource->internalHasRef() || !resource->cacheAccess().isScratch()) { return false; } @@ -224,7 +221,7 @@ void GrResourceCache2::makeResourceMRU(GrGpuResource* resource) { fResources.addToHead(resource); } -void GrResourceCache2::notifyPurgable(const GrGpuResource* resource) { +void GrResourceCache2::notifyPurgable(GrGpuResource* resource) { SkASSERT(resource); SkASSERT(this->isInCache(resource)); SkASSERT(resource->isPurgable()); @@ -239,25 +236,14 @@ void GrResourceCache2::notifyPurgable(const GrGpuResource* resource) { // Purge the resource if we're over budget bool overBudget = fCount > fMaxCount || fBytes > fMaxBytes; - // We should not be over budget here unless all resources are unpuragble. -#ifdef SK_DEBUG - if (overBudget) { - ResourceList::Iter iter; - GrGpuResource* r = iter.init(fResources, ResourceList::Iter::kHead_IterStart); - for ( ; r; r = iter.next()) { - SkASSERT(r == resource || !r->isPurgable()); - } - } -#endif - // Also purge if the resource has neither a valid scratch key nor a content key. bool noKey = !resource->cacheAccess().isScratch() && (NULL == resource->cacheAccess().getContentKey()); if (overBudget || noKey) { SkDEBUGCODE(int beforeCount = fCount;) - resource->unref(); - // We should at least have freed resource. It may have in turn freed other resources. + resource->cacheAccess().release(); + // We should at least free this resource, perhaps dependent resources as well. SkASSERT(fCount < beforeCount); } @@ -295,7 +281,7 @@ void GrResourceCache2::internalPurgeAsNeeded() { while (resource) { GrGpuResource* prev = resourceIter.prev(); if (resource->isPurgable()) { - resource->unref(); + resource->cacheAccess().release(); } resource = prev; if (fCount <= fMaxCount && fBytes <= fMaxBytes) { @@ -331,8 +317,8 @@ void GrResourceCache2::purgeAllUnlocked() { while (resource) { GrGpuResource* prev = resourceIter.prev(); if (resource->isPurgable()) { - resource->unref(); - } + resource->cacheAccess().release(); + } resource = prev; } @@ -387,8 +373,10 @@ void GrResourceCache2::validate() const { SkASSERT(content == fContentHash.count()); SkASSERT(scratch + couldBeScratch == fScratchMap.count()); - bool overBudget = bytes > fMaxBytes || count > fMaxCount; - SkASSERT(!overBudget || locked == count || fPurging); + // This assertion is not currently valid because we can be in recursive notifyIsPurgable() + // calls. This will be fixed when subresource registration is explicit. + // bool overBudget = bytes > fMaxBytes || count > fMaxCount; + // SkASSERT(!overBudget || locked == count || fPurging); } #endif diff --git a/src/gpu/GrResourceCache2.h b/src/gpu/GrResourceCache2.h index 8b4d1d0e67..805d359eb4 100644 --- a/src/gpu/GrResourceCache2.h +++ b/src/gpu/GrResourceCache2.h @@ -148,7 +148,7 @@ private: //// void insertResource(GrGpuResource*); void removeResource(GrGpuResource*); - void notifyPurgable(const GrGpuResource*); + void notifyPurgable(GrGpuResource*); void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize); bool didSetContentKey(GrGpuResource*); void makeResourceMRU(GrGpuResource*); @@ -241,7 +241,7 @@ private: /** * Called by GrGpuResources when they detects that they are newly purgable. */ - void notifyPurgable(const GrGpuResource* resource) { fCache->notifyPurgable(resource); } + void notifyPurgable(GrGpuResource* resource) { fCache->notifyPurgable(resource); } /** * Called by GrGpuResources when their sizes change. diff --git a/src/gpu/gl/GrGLIndexBuffer.h b/src/gpu/gl/GrGLIndexBuffer.h index 5d5de43eee..a62bba1d51 100644 --- a/src/gpu/gl/GrGLIndexBuffer.h +++ b/src/gpu/gl/GrGLIndexBuffer.h @@ -20,7 +20,6 @@ public: typedef GrGLBufferImpl::Desc Desc; GrGLIndexBuffer(GrGpuGL* gpu, const Desc& desc); - virtual ~GrGLIndexBuffer() { this->release(); } GrGLuint bufferID() const { return fImpl.bufferID(); } size_t baseOffset() const { return fImpl.baseOffset(); } diff --git a/src/gpu/gl/GrGLPath.cpp b/src/gpu/gl/GrGLPath.cpp index 6097f469db..fc5688114d 100644 --- a/src/gpu/gl/GrGLPath.cpp +++ b/src/gpu/gl/GrGLPath.cpp @@ -143,10 +143,6 @@ GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke) this->registerWithCache(); } -GrGLPath::~GrGLPath() { - this->release(); -} - void GrGLPath::onRelease() { if (0 != fPathID && !this->isWrapped()) { static_cast<GrGpuGL*>(this->getGpu())->glPathRendering()->deletePaths(fPathID, 1); diff --git a/src/gpu/gl/GrGLPath.h b/src/gpu/gl/GrGLPath.h index b8bd8ad1a4..a7640d526a 100644 --- a/src/gpu/gl/GrGLPath.h +++ b/src/gpu/gl/GrGLPath.h @@ -28,7 +28,6 @@ public: const SkStrokeRec&); GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke); - virtual ~GrGLPath(); GrGLuint pathID() const { return fPathID; } protected: diff --git a/src/gpu/gl/GrGLPathRange.cpp b/src/gpu/gl/GrGLPathRange.cpp index 12c96c6a3f..5ff64f85af 100644 --- a/src/gpu/gl/GrGLPathRange.cpp +++ b/src/gpu/gl/GrGLPathRange.cpp @@ -29,10 +29,6 @@ GrGLPathRange::GrGLPathRange(GrGpuGL* gpu, this->registerWithCache(); } -GrGLPathRange::~GrGLPathRange() { - this->release(); -} - void GrGLPathRange::onInitPath(int index, const SkPath& skPath) const { GrGpuGL* gpu = static_cast<GrGpuGL*>(this->getGpu()); if (NULL == gpu) { diff --git a/src/gpu/gl/GrGLPathRange.h b/src/gpu/gl/GrGLPathRange.h index 440ffbc0c9..8fde666e7e 100644 --- a/src/gpu/gl/GrGLPathRange.h +++ b/src/gpu/gl/GrGLPathRange.h @@ -39,8 +39,6 @@ public: size_t gpuMemorySize, const SkStrokeRec&); - virtual ~GrGLPathRange(); - GrGLuint basePathID() const { return fBasePathID; } protected: diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h index b81bbed4b2..fd149b1185 100644 --- a/src/gpu/gl/GrGLRenderTarget.h +++ b/src/gpu/gl/GrGLRenderTarget.h @@ -30,8 +30,6 @@ public: GrGLRenderTarget(GrGpuGL*, const GrSurfaceDesc&, const IDDesc&); - virtual ~GrGLRenderTarget() { this->release(); } - void setViewport(const GrGLIRect& rect) { fViewport = rect; } const GrGLIRect& getViewport() const { return fViewport; } diff --git a/src/gpu/gl/GrGLStencilBuffer.cpp b/src/gpu/gl/GrGLStencilBuffer.cpp index fd14ea01f2..2ec06d438c 100644 --- a/src/gpu/gl/GrGLStencilBuffer.cpp +++ b/src/gpu/gl/GrGLStencilBuffer.cpp @@ -9,10 +9,6 @@ #include "GrGLStencilBuffer.h" #include "GrGpuGL.h" -GrGLStencilBuffer::~GrGLStencilBuffer() { - this->release(); -} - size_t GrGLStencilBuffer::onGpuMemorySize() const { uint64_t size = this->width(); size *= this->height(); diff --git a/src/gpu/gl/GrGLStencilBuffer.h b/src/gpu/gl/GrGLStencilBuffer.h index 53777e40c7..ff0d5cb4d0 100644 --- a/src/gpu/gl/GrGLStencilBuffer.h +++ b/src/gpu/gl/GrGLStencilBuffer.h @@ -35,8 +35,6 @@ public: this->registerWithCache(); } - virtual ~GrGLStencilBuffer(); - GrGLuint renderbufferID() const { return fRenderbufferID; } diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h index f23adae0d2..268fe9239e 100644 --- a/src/gpu/gl/GrGLTexture.h +++ b/src/gpu/gl/GrGLTexture.h @@ -33,8 +33,6 @@ public: GrGLTexture(GrGpuGL*, const GrSurfaceDesc&, const IDDesc&); - virtual ~GrGLTexture() { this->release(); } - virtual GrBackendObject getTextureHandle() const SK_OVERRIDE; virtual void textureParamsModified() SK_OVERRIDE { fTexParams.invalidate(); } diff --git a/src/gpu/gl/GrGLTextureRenderTarget.h b/src/gpu/gl/GrGLTextureRenderTarget.h index 06080a8a36..11577b8dcf 100644 --- a/src/gpu/gl/GrGLTextureRenderTarget.h +++ b/src/gpu/gl/GrGLTextureRenderTarget.h @@ -34,8 +34,6 @@ public: this->registerWithCache(); } - virtual ~GrGLTextureRenderTarget() { this->release(); } - protected: virtual void onAbandon() SK_OVERRIDE { GrGLRenderTarget::onAbandon(); diff --git a/src/gpu/gl/GrGLVertexBuffer.h b/src/gpu/gl/GrGLVertexBuffer.h index db413ac990..40f4af9091 100644 --- a/src/gpu/gl/GrGLVertexBuffer.h +++ b/src/gpu/gl/GrGLVertexBuffer.h @@ -20,7 +20,6 @@ public: typedef GrGLBufferImpl::Desc Desc; GrGLVertexBuffer(GrGpuGL* gpu, const Desc& desc); - virtual ~GrGLVertexBuffer() { this->release(); } GrGLuint bufferID() const { return fImpl.bufferID(); } size_t baseOffset() const { return fImpl.baseOffset(); } diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 877c21fc7e..89f26efe22 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -1131,21 +1131,22 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt, SkASSERT(height >= rt->height()); int samples = rt->numSamples(); - GrGLuint sbID; - GL_CALL(GenRenderbuffers(1, &sbID)); - if (!sbID) { - return false; - } + GrGLuint sbID = 0; int stencilFmtCnt = this->glCaps().stencilFormats().count(); for (int i = 0; i < stencilFmtCnt; ++i) { + if (!sbID) { + GL_CALL(GenRenderbuffers(1, &sbID)); + } + if (!sbID) { + return false; + } GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbID)); // we start with the last stencil format that succeeded in hopes // that we won't go through this loop more than once after the // first (painful) stencil creation. int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt; - const GrGLCaps::StencilFormat& sFmt = - this->glCaps().stencilFormats()[sIdx]; + const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[sIdx]; CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); // we do this "if" so that we don't call the multisample // version on a GL that doesn't have an MSAA extension. @@ -1156,12 +1157,10 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt, sFmt.fInternalFormat, width, height); } else { - GL_ALLOC_CALL(this->glInterface(), - RenderbufferStorage(GR_GL_RENDERBUFFER, - sFmt.fInternalFormat, - width, height)); - created = - (GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glInterface())); + GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER, + sFmt.fInternalFormat, + width, height)); + created = (GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glInterface())); } if (created) { // After sized formats we attempt an unsized format and take @@ -1172,13 +1171,15 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt, SkAutoTUnref<GrStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer, (this, kIsWrapped, sbID, width, height, samples, format))); + // If we fail we have to create a new render buffer ID since we gave this one to the + // GrGLStencilBuffer object. + sbID = 0; if (this->attachStencilBufferToRenderTarget(sb, rt)) { fLastSuccessfulStencilFmtIdx = sIdx; sb->transferToCache(); rt->setStencilBuffer(sb); return true; - } - sb->abandon(); // otherwise we lose sbID + } } } GL_CALL(DeleteRenderbuffers(1, &sbID)); |