Add deferred count to GrResource.

This will be used to determine whether a resource can either be deleted or reinserted in the cache when its ref count reaches zero.
Review URL: https://codereview.appspot.com/7202046

git-svn-id: http://skia.googlecode.com/svn/trunk@7355 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2013-01-23 21:37:01 +00:00
parent 1f0f1a3b5e
commit 838f6e18fb
4 changed files with 47 additions and 27 deletions

View File

@ -148,10 +148,23 @@ public:
void* operator new(size_t size);
void operator delete(void* target);
/** These use non-standard names because GrEffects should only be ref'ed an unref'ed deep in
the bowels. Rendering code should use GrEffectRef. */
void addRef() const { this->ref(); }
void subRef() const { this->unref(); }
/** These functions are used when recording effects into a deferred drawing queue. The inc call
keeps the effect alive outside of GrEffectRef while allowing any resources owned by the
effect to be returned to the cache for reuse. The dec call must balance the inc call. */
void incDeferredRefCounts() const {
this->ref();
int count = fTextureAccesses.count();
for (int t = 0; t < count; ++t) {
fTextureAccesses[t]->getTexture()->incDeferredRefCount();
}
}
void decDeferredRefCounts() const {
int count = fTextureAccesses.count();
for (int t = 0; t < count; ++t) {
fTextureAccesses[t]->getTexture()->decDeferredRefCount();
}
this->unref();
}
protected:
/**
@ -191,7 +204,7 @@ protected:
class AutoEffectUnref {
public:
AutoEffectUnref(GrEffect* effect) : fEffect(effect) { }
~AutoEffectUnref() { fEffect->subRef(); }
~AutoEffectUnref() { fEffect->unref(); }
operator GrEffect*() { return fEffect; }
private:
GrEffect* fEffect;
@ -228,9 +241,10 @@ private:
void EffectRefDestroyed() { fEffectRef = NULL; }
friend class GrEffectRef; // to call GrEffectRef destroyed
friend class GrEffectRef; // to call EffectRefDestroyed()
friend class GrEffectStage; // to rewrap GrEffect in GrEffectRef when restoring an effect-stage
// from deferred state. And to call isEqual on naked GrEffects.
// from deferred state, to call isEqual on naked GrEffects, and
// to inc/dec deferred ref counts.
SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses;
GrEffectRef* fEffectRef;

View File

@ -104,10 +104,16 @@ public:
SkDEBUGCODE(fInitialized = false;)
}
~DeferredStage() {
if (NULL != fEffect) {
fEffect->decDeferredRefCounts();
}
}
void saveFrom(const GrEffectStage& stage) {
GrAssert(!fInitialized);
if (NULL != stage.fEffectRef) {
stage.fEffectRef->get()->addRef();
stage.fEffectRef->get()->incDeferredRefCounts();
fEffect = stage.fEffectRef->get();
fCoordChangeMatrix = stage.fCoordChangeMatrix;
}
@ -140,11 +146,6 @@ public:
return fCoordChangeMatrix == stage.fCoordChangeMatrix;
}
~DeferredStage() {
if (NULL != fEffect) {
fEffect->subRef();
}
}
private:
const GrEffect* fEffect;
SkMatrix fCoordChangeMatrix;

View File

@ -57,18 +57,21 @@ public:
*/
virtual size_t sizeInBytes() const = 0;
/**
* Retrieves the context that owns the resource. Note that it is possible
* for this to return NULL. When resources have been release()ed or
* abandon()ed they no longer have an owning context. Destroying a
* GrContext automatically releases all its resources.
*/
/**
* Retrieves the context that owns the resource. Note that it is possible
* for this to return NULL. When resources have been release()ed or
* abandon()ed they no longer have an owning context. Destroying a
* GrContext automatically releases all its resources.
*/
const GrContext* getContext() const;
GrContext* getContext();
void setCacheEntry(GrResourceEntry* cacheEntry) { fCacheEntry = cacheEntry; }
GrResourceEntry* getCacheEntry() { return fCacheEntry; }
void incDeferredRefCount() const { GrAssert(fDeferredRefCount >= 0); ++fDeferredRefCount; }
void decDeferredRefCount() const { GrAssert(fDeferredRefCount > 0); --fDeferredRefCount; }
protected:
/**
* isWrapped indicates we have wrapped a client-created backend resource in a GrResource. If it
@ -93,15 +96,15 @@ private:
friend class GrGpu; // for assert in GrGpu to access getGpu
#endif
GrGpu* fGpu; // not reffed. The GrGpu can be deleted while there
// are still live GrResources. It will call
// release() on all such resources in its
// destructor.
// We're in an internal doubly linked list
SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResource);
GrResourceEntry* fCacheEntry; // NULL if not in cache
GrGpu* fGpu; // not reffed. The GrGpu can be deleted while there
// are still live GrResources. It will call
// release() on all such resources in its
// destructor.
GrResourceEntry* fCacheEntry; // NULL if not in cache
mutable int fDeferredRefCount; // How many references in deferred drawing buffers.
enum Flags {
kWrapped_Flag = 0x1,

View File

@ -13,8 +13,9 @@
SK_DEFINE_INST_COUNT(GrResource)
GrResource::GrResource(GrGpu* gpu, bool isWrapped) {
fGpu = gpu;
fCacheEntry = NULL;
fGpu = gpu;
fCacheEntry = NULL;
fDeferredRefCount = 0;
if (isWrapped) {
fFlags = kWrapped_Flag;
} else {
@ -25,6 +26,7 @@ GrResource::GrResource(GrGpu* gpu, bool isWrapped) {
GrResource::~GrResource() {
// subclass should have released this.
GrAssert(0 == fDeferredRefCount);
GrAssert(!this->isValid());
}