aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-08-28 12:34:17 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-08-28 12:34:17 +0000
commita292112154f803feb9f5cc002bbfab559f7cb633 (patch)
treead0e10be899398b34764f8f7c0d63df4172a483d /src/gpu
parent97af1a64ae6bdddd346d8babfd9f188279dd6644 (diff)
Remove SkGpuDevice::fTexture, use new pixel ref class name
Review URL: https://codereview.appspot.com/6474068/ git-svn-id: http://skia.googlecode.com/svn/trunk@5307 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrContext.cpp4
-rw-r--r--src/gpu/GrResourceCache.cpp96
-rw-r--r--src/gpu/GrResourceCache.h14
-rw-r--r--src/gpu/GrStencilBuffer.cpp4
-rw-r--r--src/gpu/SkGpuDevice.cpp48
5 files changed, 88 insertions, 78 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 2b5014d6a9..a13394cd60 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -136,7 +136,7 @@ void GrContext::contextDestroyed() {
fAARectRenderer->reset();
- fTextureCache->removeAll();
+ fTextureCache->purgeAllUnlocked();
fFontCache->freeAll();
fGpu->markContextDirty();
}
@@ -152,7 +152,7 @@ void GrContext::freeGpuResources() {
fAARectRenderer->reset();
- fTextureCache->removeAll();
+ fTextureCache->purgeAllUnlocked();
fFontCache->freeAll();
// a path renderer may be holding onto resources
GrSafeSetNull(fPathRendererChain);
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
index 60e20a77c5..777470b00d 100644
--- a/src/gpu/GrResourceCache.cpp
+++ b/src/gpu/GrResourceCache.cpp
@@ -35,6 +35,36 @@ void GrResourceEntry::validate() const {
///////////////////////////////////////////////////////////////////////////////
+class GrResourceCache::Key {
+ typedef GrResourceEntry T;
+
+ const GrResourceKey& fKey;
+public:
+ Key(const GrResourceKey& key) : fKey(key) {}
+
+ uint32_t getHash() const { return fKey.hashIndex(); }
+
+ static bool LT(const T& entry, const Key& key) {
+ return entry.key() < key.fKey;
+ }
+ static bool EQ(const T& entry, const Key& key) {
+ return entry.key() == key.fKey;
+ }
+#if GR_DEBUG
+ static uint32_t GetHash(const T& entry) {
+ return entry.key().hashIndex();
+ }
+ static bool LT(const T& a, const T& b) {
+ return a.key() < b.key();
+ }
+ static bool EQ(const T& a, const T& b) {
+ return a.key() == b.key();
+ }
+#endif
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
GrResourceCache::GrResourceCache(int maxCount, size_t maxBytes) :
fMaxCount(maxCount),
fMaxBytes(maxBytes) {
@@ -58,7 +88,20 @@ GrResourceCache::GrResourceCache(int maxCount, size_t maxBytes) :
GrResourceCache::~GrResourceCache() {
GrAutoResourceCacheValidate atcv(this);
- this->removeAll();
+ EntryList::Iter iter;
+
+ // Unlike the removeAll, here we really remove everything, including locked resources.
+ while (GrResourceEntry* entry = fList.head()) {
+ GrAutoResourceCacheValidate atcv(this);
+
+ // remove from our cache
+ fCache.remove(entry->fKey, entry);
+
+ // remove from our llist
+ this->internalDetach(entry, false);
+
+ delete entry;
+ }
}
void GrResourceCache::getLimits(int* maxResources, size_t* maxResourceBytes) const{
@@ -141,34 +184,6 @@ void GrResourceCache::attachToHead(GrResourceEntry* entry,
}
}
-class GrResourceCache::Key {
- typedef GrResourceEntry T;
-
- const GrResourceKey& fKey;
-public:
- Key(const GrResourceKey& key) : fKey(key) {}
-
- uint32_t getHash() const { return fKey.hashIndex(); }
-
- static bool LT(const T& entry, const Key& key) {
- return entry.key() < key.fKey;
- }
- static bool EQ(const T& entry, const Key& key) {
- return entry.key() == key.fKey;
- }
-#if GR_DEBUG
- static uint32_t GetHash(const T& entry) {
- return entry.key().hashIndex();
- }
- static bool LT(const T& a, const T& b) {
- return a.key() < b.key();
- }
- static bool EQ(const T& a, const T& b) {
- return a.key() == b.key();
- }
-#endif
-};
-
GrResource* GrResourceCache::findAndLock(const GrResourceKey& key,
LockType type) {
GrAutoResourceCacheValidate atcv(this);
@@ -310,14 +325,13 @@ void GrResourceCache::purgeAsNeeded() {
fPurging = true;
bool withinBudget = false;
do {
- SkTDLinkedList<GrResourceEntry>::Iter iter;
+ EntryList::Iter iter;
// Note: the following code relies on the fact that the
// doubly linked list doesn't invalidate its data/pointers
// outside of the specific area where a deletion occurs (e.g.,
// in internalDetach)
- GrResourceEntry* entry = iter.init(fList,
- SkTDLinkedList<GrResourceEntry>::Iter::kTail_IterStart);
+ GrResourceEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterStart);
while (entry && fUnlockedEntryCount) {
GrAutoResourceCacheValidate atcv(this);
@@ -350,7 +364,7 @@ void GrResourceCache::purgeAsNeeded() {
}
}
-void GrResourceCache::removeAll() {
+void GrResourceCache::purgeAllUnlocked() {
GrAutoResourceCacheValidate atcv(this);
// we can have one GrResource holding a lock on another
@@ -384,14 +398,13 @@ void GrResourceCache::removeAll() {
///////////////////////////////////////////////////////////////////////////////
#if GR_DEBUG
-size_t GrResourceCache::countBytes(const SkTDLinkedList<GrResourceEntry>& list) {
+size_t GrResourceCache::countBytes(const EntryList& list) {
size_t bytes = 0;
- SkTDLinkedList<GrResourceEntry>::Iter iter;
+ EntryList::Iter iter;
- const GrResourceEntry* entry = iter.init(
- const_cast<SkTDLinkedList<GrResourceEntry>&>(list),
- SkTDLinkedList<GrResourceEntry>::Iter::kTail_IterStart);
+ const GrResourceEntry* entry = iter.init(const_cast<EntryList&>(list),
+ EntryList::Iter::kTail_IterStart);
for ( ; NULL != entry; entry = iter.prev()) {
bytes += entry->resource()->sizeInBytes();
@@ -417,11 +430,10 @@ void GrResourceCache::validate() const {
int count = 0;
int unlockCount = 0;
- SkTDLinkedList<GrResourceEntry>::Iter iter;
+ EntryList::Iter iter;
- const GrResourceEntry* entry = iter.init(
- const_cast<SkTDLinkedList<GrResourceEntry>&>(fList),
- SkTDLinkedList<GrResourceEntry>::Iter::kHead_IterStart);
+ const GrResourceEntry* entry = iter.init(const_cast<EntryList&>(fList),
+ EntryList::Iter::kHead_IterStart);
for ( ; NULL != entry; entry = iter.next()) {
entry->validate();
diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h
index 162e1ef04a..5741e47dc9 100644
--- a/src/gpu/GrResourceCache.h
+++ b/src/gpu/GrResourceCache.h
@@ -264,12 +264,15 @@ public:
void makeNonExclusive(GrResourceEntry* entry);
/**
- * When done with an entry, call unlock(entry) on it, which returns it to
- * a purgable state.
+ * When done with an entry, call unlock(entry) on it, which returns it to
+ * a purgable state.
*/
void unlock(GrResourceEntry*);
- void removeAll();
+ /**
+ * Removes every resource in the cache that isn't locked.
+ */
+ void purgeAllUnlocked();
#if GR_DEBUG
void validate() const;
@@ -289,11 +292,12 @@ private:
GrTHashTable<GrResourceEntry, Key, 8> fCache;
// manage the dlink list
- SkTDLinkedList<GrResourceEntry> fList;
+ typedef SkTDLinkedList<GrResourceEntry> EntryList;
+ EntryList fList;
#if GR_DEBUG
// These objects cannot be returned by a search
- SkTDLinkedList<GrResourceEntry> fExclusiveList;
+ EntryList fExclusiveList;
#endif
// our budget, used in purgeAsNeeded()
diff --git a/src/gpu/GrStencilBuffer.cpp b/src/gpu/GrStencilBuffer.cpp
index bf14f4864e..7bd6f3228d 100644
--- a/src/gpu/GrStencilBuffer.cpp
+++ b/src/gpu/GrStencilBuffer.cpp
@@ -41,7 +41,6 @@ void GrStencilBuffer::onRelease() {
this->unlockInCache();
// we shouldn't be deleted here because some RT still has a ref on us.
}
- fHoldingLock = false;
}
void GrStencilBuffer::onAbandon() {
@@ -50,12 +49,13 @@ void GrStencilBuffer::onAbandon() {
}
void GrStencilBuffer::unlockInCache() {
- if (fHoldingLock) {
+ if (fHoldingLock && this->isInCache()) {
GrGpu* gpu = this->getGpu();
if (NULL != gpu) {
GrAssert(NULL != gpu->getContext());
gpu->getContext()->unlockStencilBuffer(this);
}
+ fHoldingLock = false;
}
}
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 556608659b..8d43f704e1 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -189,28 +189,23 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context,
fContext->ref();
fCached = false;
- fTexture = NULL;
fRenderTarget = NULL;
fNeedClear = false;
GrAssert(NULL != renderTarget);
fRenderTarget = renderTarget;
fRenderTarget->ref();
- // if this RT is also a texture, hold a ref on it
- fTexture = fRenderTarget->asTexture();
- SkSafeRef(fTexture);
-
- // Create a pixel ref for the underlying SkBitmap. We prefer a texture pixel
- // ref to a render target pixel reft. The pixel ref may get ref'ed outside
- // the device via accessBitmap. This external ref may outlive the device.
- // Since textures own their render targets (but not vice-versa) we
- // are ensuring that both objects will live as long as the pixel ref.
- SkPixelRef* pr;
- if (fTexture) {
- pr = SkNEW_ARGS(SkGrTexturePixelRef, (fTexture));
- } else {
- pr = SkNEW_ARGS(SkGrRenderTargetPixelRef, (fRenderTarget));
+
+ // Hold onto to the texture in the pixel ref (if there is one) because the texture holds a ref
+ // on the RT but not vice-versa.
+ // TODO: Remove this trickery once we figure out how to make SkGrPixelRef do this without
+ // busting chrome (for a currently unknown reason).
+ GrSurface* surface = fRenderTarget->asTexture();
+ if (NULL == surface) {
+ surface = fRenderTarget;
}
+ SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (surface));
+
this->setPixelRef(pr, 0)->unref();
}
@@ -227,7 +222,6 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
fContext->ref();
fCached = false;
- fTexture = NULL;
fRenderTarget = NULL;
fNeedClear = false;
@@ -243,16 +237,16 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
desc.fHeight = height;
desc.fConfig = SkBitmapConfig2GrPixelConfig(bm.config());
- fTexture = fContext->createUncachedTexture(desc, NULL, 0);
+ SkAutoTUnref<GrTexture> texture(fContext->createUncachedTexture(desc, NULL, 0));
- if (NULL != fTexture) {
- fRenderTarget = fTexture->asRenderTarget();
+ if (NULL != texture) {
+ fRenderTarget = texture->asRenderTarget();
fRenderTarget->ref();
GrAssert(NULL != fRenderTarget);
// wrap the bitmap with a pixelref to expose our texture
- SkGrTexturePixelRef* pr = SkNEW_ARGS(SkGrTexturePixelRef, (fTexture));
+ SkGrPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (texture));
this->setPixelRef(pr, 0)->unref();
} else {
GrPrintf("--- failed to create gpu-offscreen [%d %d]\n",
@@ -270,12 +264,11 @@ SkGpuDevice::~SkGpuDevice() {
// This call gives the context a chance to relinquish it
fContext->setRenderTarget(NULL);
- SkSafeUnref(fTexture);
- SkSafeUnref(fRenderTarget);
- if (NULL != fTexture && fCached) {
- GrAssert(fRenderTarget == fTexture->asRenderTarget());
- fContext->unlockTexture(fTexture);
+ GrTexture* texture = fRenderTarget->asTexture();
+ if (NULL != texture && fCached) {
+ fContext->unlockTexture(texture);
}
+ SkSafeUnref(fRenderTarget);
fContext->unref();
}
@@ -485,9 +478,10 @@ SkGpuRenderTarget* SkGpuDevice::accessRenderTarget() {
}
bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) {
- if (NULL != fTexture) {
+ GrTexture* texture = fRenderTarget->asTexture();
+ if (NULL != texture) {
paint->textureSampler(kBitmapTextureIdx)->setCustomStage(
- SkNEW_ARGS(GrSingleTextureEffect, (fTexture)))->unref();
+ SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref();
return true;
}
return false;