зеркало из https://github.com/mozilla/moz-skia.git
Simplified stencil buffer caching
https://codereview.appspot.com/6503073/ git-svn-id: http://skia.googlecode.com/svn/trunk@5400 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
73bb3bee93
Коммит
d6bbbf8a83
|
@ -762,13 +762,12 @@ public:
|
||||||
* Stencil buffers add themselves to the cache using
|
* Stencil buffers add themselves to the cache using
|
||||||
* addAndLockStencilBuffer. When a SB's RT-attachment count
|
* addAndLockStencilBuffer. When a SB's RT-attachment count
|
||||||
* reaches zero the SB unlocks itself using unlockStencilBuffer and is
|
* reaches zero the SB unlocks itself using unlockStencilBuffer and is
|
||||||
* eligible for purging. findStencilBuffer is called to check the cache for
|
* eligible for purging. findAndLockStencilBuffer is called to check the
|
||||||
* a SB that matching an RT's criteria. If a match is found that has been
|
* cache for a SB that matches an RT's criteria.
|
||||||
* unlocked (its attachment count has reached 0) then it will be relocked.
|
|
||||||
*/
|
*/
|
||||||
void addAndLockStencilBuffer(GrStencilBuffer* sb);
|
void addAndLockStencilBuffer(GrStencilBuffer* sb);
|
||||||
void unlockStencilBuffer(GrStencilBuffer* sb);
|
void unlockStencilBuffer(GrStencilBuffer* sb);
|
||||||
GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);
|
GrStencilBuffer* findAndLockStencilBuffer(int width, int height, int sampleCnt);
|
||||||
|
|
||||||
GrPathRenderer* getPathRenderer(const SkPath& path,
|
GrPathRenderer* getPathRenderer(const SkPath& path,
|
||||||
GrPathFill fill,
|
GrPathFill fill,
|
||||||
|
|
|
@ -168,6 +168,10 @@ protected:
|
||||||
fTexture = NULL;
|
fTexture = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// override of GrResource
|
||||||
|
virtual void onAbandon() SK_OVERRIDE;
|
||||||
|
virtual void onRelease() SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GrStencilBuffer* fStencilBuffer;
|
GrStencilBuffer* fStencilBuffer;
|
||||||
GrTexture* fTexture; // not ref'ed
|
GrTexture* fTexture; // not ref'ed
|
||||||
|
|
|
@ -216,8 +216,7 @@ GrTexture* GrContext::findAndLockTexture(const GrTextureDesc& desc,
|
||||||
const GrCacheData& cacheData,
|
const GrCacheData& cacheData,
|
||||||
const GrTextureParams* params) {
|
const GrTextureParams* params) {
|
||||||
GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheData, false);
|
GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheData, false);
|
||||||
GrResource* resource = fTextureCache->findAndLock(resourceKey,
|
GrResource* resource = fTextureCache->findAndLock(resourceKey);
|
||||||
GrResourceCache::kNested_LockType);
|
|
||||||
return static_cast<GrTexture*>(resource);
|
return static_cast<GrTexture*>(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,19 +236,25 @@ void GrContext::addAndLockStencilBuffer(GrStencilBuffer* sb) {
|
||||||
fTextureCache->createAndLock(resourceKey, sb);
|
fTextureCache->createAndLock(resourceKey, sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
GrStencilBuffer* GrContext::findStencilBuffer(int width, int height,
|
GrStencilBuffer* GrContext::findAndLockStencilBuffer(int width, int height,
|
||||||
int sampleCnt) {
|
int sampleCnt) {
|
||||||
GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(width,
|
GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(width,
|
||||||
height,
|
height,
|
||||||
sampleCnt);
|
sampleCnt);
|
||||||
GrResource* resource = fTextureCache->findAndLock(resourceKey,
|
GrResource* resource = fTextureCache->findAndLock(resourceKey);
|
||||||
GrResourceCache::kSingle_LockType);
|
|
||||||
return static_cast<GrStencilBuffer*>(resource);
|
return static_cast<GrStencilBuffer*>(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrContext::unlockStencilBuffer(GrStencilBuffer* sb) {
|
void GrContext::unlockStencilBuffer(GrStencilBuffer* sb) {
|
||||||
ASSERT_OWNED_RESOURCE(sb);
|
ASSERT_OWNED_RESOURCE(sb);
|
||||||
GrAssert(NULL != sb->getCacheEntry());
|
|
||||||
|
if (NULL == sb->getCacheEntry()) {
|
||||||
|
// This can happen when the GrResourceCache is being deleted. If
|
||||||
|
// a stencil buffer was evicted before its reffing render targets,
|
||||||
|
// the render targets will attempt to unlock the stencil buffer
|
||||||
|
// when they are deleted.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fTextureCache->unlock(sb->getCacheEntry());
|
fTextureCache->unlock(sb->getCacheEntry());
|
||||||
}
|
}
|
||||||
|
@ -415,8 +420,7 @@ GrTexture* GrContext::lockScratchTexture(const GrTextureDesc& inDesc,
|
||||||
|
|
||||||
do {
|
do {
|
||||||
GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL, desc, cacheData, true);
|
GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL, desc, cacheData, true);
|
||||||
resource = fTextureCache->findAndLock(key,
|
resource = fTextureCache->findAndLock(key);
|
||||||
GrResourceCache::kNested_LockType);
|
|
||||||
// if we miss, relax the fit of the flags...
|
// if we miss, relax the fit of the flags...
|
||||||
// then try doubling width... then height.
|
// then try doubling width... then height.
|
||||||
if (NULL != resource || kExact_ScratchTexMatch == match) {
|
if (NULL != resource || kExact_ScratchTexMatch == match) {
|
||||||
|
|
|
@ -144,7 +144,7 @@ GrTexture* GrGpu::createTexture(const GrTextureDesc& desc,
|
||||||
bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
||||||
GrAssert(NULL == rt->getStencilBuffer());
|
GrAssert(NULL == rt->getStencilBuffer());
|
||||||
GrStencilBuffer* sb =
|
GrStencilBuffer* sb =
|
||||||
this->getContext()->findStencilBuffer(rt->width(),
|
this->getContext()->findAndLockStencilBuffer(rt->width(),
|
||||||
rt->height(),
|
rt->height(),
|
||||||
rt->numSamples());
|
rt->numSamples());
|
||||||
if (NULL != sb) {
|
if (NULL != sb) {
|
||||||
|
@ -157,9 +157,6 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
||||||
}
|
}
|
||||||
if (this->createStencilBufferForRenderTarget(rt,
|
if (this->createStencilBufferForRenderTarget(rt,
|
||||||
rt->width(), rt->height())) {
|
rt->width(), rt->height())) {
|
||||||
rt->getStencilBuffer()->ref();
|
|
||||||
rt->getStencilBuffer()->transferToCacheAndLock();
|
|
||||||
|
|
||||||
// Right now we're clearing the stencil buffer here after it is
|
// Right now we're clearing the stencil buffer here after it is
|
||||||
// attached to an RT for the first time. When we start matching
|
// attached to an RT for the first time. When we start matching
|
||||||
// stencil buffers with smaller color targets this will no longer
|
// stencil buffers with smaller color targets this will no longer
|
||||||
|
|
|
@ -96,12 +96,24 @@ void GrRenderTarget::overrideResolveRect(const GrIRect rect) {
|
||||||
|
|
||||||
void GrRenderTarget::setStencilBuffer(GrStencilBuffer* stencilBuffer) {
|
void GrRenderTarget::setStencilBuffer(GrStencilBuffer* stencilBuffer) {
|
||||||
if (NULL != fStencilBuffer) {
|
if (NULL != fStencilBuffer) {
|
||||||
fStencilBuffer->wasDetachedFromRenderTarget(this);
|
GrContext* context = this->getContext();
|
||||||
|
if (NULL != context) {
|
||||||
|
context->unlockStencilBuffer(fStencilBuffer);
|
||||||
|
}
|
||||||
fStencilBuffer->unref();
|
fStencilBuffer->unref();
|
||||||
}
|
}
|
||||||
|
|
||||||
fStencilBuffer = stencilBuffer;
|
fStencilBuffer = stencilBuffer;
|
||||||
|
|
||||||
if (NULL != fStencilBuffer) {
|
if (NULL != fStencilBuffer) {
|
||||||
fStencilBuffer->wasAttachedToRenderTarget(this);
|
|
||||||
fStencilBuffer->ref();
|
fStencilBuffer->ref();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GrRenderTarget::onRelease() {
|
||||||
|
this->setStencilBuffer(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrRenderTarget::onAbandon() {
|
||||||
|
this->setStencilBuffer(NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -195,7 +195,7 @@ GrResource* GrResourceCache::find(const GrResourceKey& key) {
|
||||||
return entry->fResource;
|
return entry->fResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrResource* GrResourceCache::findAndLock(const GrResourceKey& key, LockType type) {
|
GrResource* GrResourceCache::findAndLock(const GrResourceKey& key) {
|
||||||
GrAutoResourceCacheValidate atcv(this);
|
GrAutoResourceCacheValidate atcv(this);
|
||||||
|
|
||||||
GrResourceEntry* entry = fCache.find(key);
|
GrResourceEntry* entry = fCache.find(key);
|
||||||
|
@ -206,9 +206,7 @@ GrResource* GrResourceCache::findAndLock(const GrResourceKey& key, LockType type
|
||||||
this->internalDetach(entry, false);
|
this->internalDetach(entry, false);
|
||||||
this->attachToHead(entry, false);
|
this->attachToHead(entry, false);
|
||||||
|
|
||||||
if (kNested_LockType == type || !entry->isLocked()) {
|
|
||||||
this->lock(entry);
|
this->lock(entry);
|
||||||
}
|
|
||||||
|
|
||||||
return entry->fResource;
|
return entry->fResource;
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,14 +231,6 @@ public:
|
||||||
*/
|
*/
|
||||||
size_t getCachedResourceBytes() const { return fEntryBytes; }
|
size_t getCachedResourceBytes() const { return fEntryBytes; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Controls whether locks should be nestable or not.
|
|
||||||
*/
|
|
||||||
enum LockType {
|
|
||||||
kNested_LockType,
|
|
||||||
kSingle_LockType,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for an entry with the same Key. If found, return it.
|
* Search for an entry with the same Key. If found, return it.
|
||||||
* If not found, return null.
|
* If not found, return null.
|
||||||
|
@ -249,7 +241,7 @@ public:
|
||||||
* Search for an entry with the same Key. If found, "lock" it and return it.
|
* Search for an entry with the same Key. If found, "lock" it and return it.
|
||||||
* If not found, return null.
|
* If not found, return null.
|
||||||
*/
|
*/
|
||||||
GrResource* findAndLock(const GrResourceKey&, LockType style);
|
GrResource* findAndLock(const GrResourceKey&);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new cache entry, based on the provided key and resource, and
|
* Create a new cache entry, based on the provided key and resource, and
|
||||||
|
|
|
@ -14,49 +14,10 @@
|
||||||
|
|
||||||
GR_DEFINE_RESOURCE_CACHE_TYPE(GrStencilBuffer)
|
GR_DEFINE_RESOURCE_CACHE_TYPE(GrStencilBuffer)
|
||||||
|
|
||||||
void GrStencilBuffer::wasDetachedFromRenderTarget(const GrRenderTarget* rt) {
|
|
||||||
GrAssert(fRTAttachmentCnt > 0);
|
|
||||||
if (0 == --fRTAttachmentCnt) {
|
|
||||||
this->unlockInCache();
|
|
||||||
// At this point we could be deleted!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrStencilBuffer::transferToCacheAndLock() {
|
void GrStencilBuffer::transferToCacheAndLock() {
|
||||||
GrAssert(NULL == this->getCacheEntry());
|
GrAssert(NULL == this->getCacheEntry());
|
||||||
GrAssert(!fHoldingLock);
|
|
||||||
|
|
||||||
this->getGpu()->getContext()->addAndLockStencilBuffer(this);
|
this->getGpu()->getContext()->addAndLockStencilBuffer(this);
|
||||||
fHoldingLock = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrStencilBuffer::onRelease() {
|
|
||||||
// When the GrGpu rips through its list of resources and releases
|
|
||||||
// them it may release an SB before it releases its attached RTs.
|
|
||||||
// In that case when GrStencilBuffer sees its last detach it no
|
|
||||||
// long has a gpu ptr (gets nulled in GrResource::release()) and can't
|
|
||||||
// access the cache to unlock itself. So if we're being released and still
|
|
||||||
// have attachments go ahead and unlock now.
|
|
||||||
if (fRTAttachmentCnt) {
|
|
||||||
this->unlockInCache();
|
|
||||||
// we shouldn't be deleted here because some RT still has a ref on us.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrStencilBuffer::onAbandon() {
|
|
||||||
// we can use the same behavior as release.
|
|
||||||
this->onRelease();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrStencilBuffer::unlockInCache() {
|
|
||||||
if (fHoldingLock && this->isInCache()) {
|
|
||||||
GrGpu* gpu = this->getGpu();
|
|
||||||
if (NULL != gpu) {
|
|
||||||
GrAssert(NULL != gpu->getContext());
|
|
||||||
gpu->getContext()->unlockStencilBuffer(this);
|
|
||||||
}
|
|
||||||
fHoldingLock = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -23,9 +23,7 @@ public:
|
||||||
GR_DECLARE_RESOURCE_CACHE_TYPE()
|
GR_DECLARE_RESOURCE_CACHE_TYPE()
|
||||||
|
|
||||||
virtual ~GrStencilBuffer() {
|
virtual ~GrStencilBuffer() {
|
||||||
// currently each rt that has attached this sb keeps a ref
|
|
||||||
// TODO: allow SB to be purged and detach itself from rts
|
// TODO: allow SB to be purged and detach itself from rts
|
||||||
GrAssert(0 == fRTAttachmentCnt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int width() const { return fWidth; }
|
int width() const { return fWidth; }
|
||||||
|
@ -65,12 +63,6 @@ public:
|
||||||
// a ref to the the cache which will unref when purged.
|
// a ref to the the cache which will unref when purged.
|
||||||
void transferToCacheAndLock();
|
void transferToCacheAndLock();
|
||||||
|
|
||||||
void wasAttachedToRenderTarget(const GrRenderTarget* rt) {
|
|
||||||
++fRTAttachmentCnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wasDetachedFromRenderTarget(const GrRenderTarget* rt);
|
|
||||||
|
|
||||||
static GrResourceKey ComputeKey(int width, int height, int sampleCnt);
|
static GrResourceKey ComputeKey(int width, int height, int sampleCnt);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -83,22 +75,11 @@ protected:
|
||||||
, fLastClipStack()
|
, fLastClipStack()
|
||||||
, fLastClipData()
|
, fLastClipData()
|
||||||
, fLastClipWidth(-1)
|
, fLastClipWidth(-1)
|
||||||
, fLastClipHeight(-1)
|
, fLastClipHeight(-1) {
|
||||||
, fHoldingLock(false)
|
|
||||||
, fRTAttachmentCnt(0) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GrResource overrides
|
|
||||||
|
|
||||||
// subclass override must call INHERITED::onRelease
|
|
||||||
virtual void onRelease();
|
|
||||||
// subclass override must call INHERITED::onAbandon
|
|
||||||
virtual void onAbandon();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void unlockInCache();
|
|
||||||
|
|
||||||
int fWidth;
|
int fWidth;
|
||||||
int fHeight;
|
int fHeight;
|
||||||
int fBits;
|
int fBits;
|
||||||
|
@ -109,9 +90,6 @@ private:
|
||||||
int fLastClipWidth;
|
int fLastClipWidth;
|
||||||
int fLastClipHeight;
|
int fLastClipHeight;
|
||||||
|
|
||||||
bool fHoldingLock;
|
|
||||||
int fRTAttachmentCnt;
|
|
||||||
|
|
||||||
typedef GrResource INHERITED;
|
typedef GrResource INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ void GrGLRenderTarget::onRelease() {
|
||||||
fMSColorRenderbufferID = 0;
|
fMSColorRenderbufferID = 0;
|
||||||
GrSafeUnref(fTexIDObj);
|
GrSafeUnref(fTexIDObj);
|
||||||
fTexIDObj = NULL;
|
fTexIDObj = NULL;
|
||||||
this->setStencilBuffer(NULL);
|
INHERITED::onRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLRenderTarget::onAbandon() {
|
void GrGLRenderTarget::onAbandon() {
|
||||||
|
@ -103,6 +103,6 @@ void GrGLRenderTarget::onAbandon() {
|
||||||
fTexIDObj->abandon();
|
fTexIDObj->abandon();
|
||||||
fTexIDObj = NULL;
|
fTexIDObj = NULL;
|
||||||
}
|
}
|
||||||
this->setStencilBuffer(NULL);
|
INHERITED::onAbandon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,8 +80,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// override of GrResource
|
// override of GrResource
|
||||||
virtual void onAbandon();
|
virtual void onAbandon() SK_OVERRIDE;
|
||||||
virtual void onRelease();
|
virtual void onRelease() SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GrGLuint fRTFBOID;
|
GrGLuint fRTFBOID;
|
||||||
|
|
|
@ -28,12 +28,10 @@ void GrGLStencilBuffer::onRelease() {
|
||||||
GR_GL_CALL(gl, DeleteRenderbuffers(1, &fRenderbufferID));
|
GR_GL_CALL(gl, DeleteRenderbuffers(1, &fRenderbufferID));
|
||||||
fRenderbufferID = 0;
|
fRenderbufferID = 0;
|
||||||
}
|
}
|
||||||
INHERITED::onRelease();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLStencilBuffer::onAbandon() {
|
void GrGLStencilBuffer::onAbandon() {
|
||||||
fRenderbufferID = 0;
|
fRenderbufferID = 0;
|
||||||
INHERITED::onAbandon();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
|
|
||||||
virtual ~GrGLStencilBuffer();
|
virtual ~GrGLStencilBuffer();
|
||||||
|
|
||||||
virtual size_t sizeInBytes() const;
|
virtual size_t sizeInBytes() const SK_OVERRIDE;
|
||||||
|
|
||||||
GrGLuint renderbufferID() const {
|
GrGLuint renderbufferID() const {
|
||||||
return fRenderbufferID;
|
return fRenderbufferID;
|
||||||
|
@ -43,9 +43,9 @@ public:
|
||||||
const Format& format() const { return fFormat; }
|
const Format& format() const { return fFormat; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void onRelease();
|
// overrides of GrResource
|
||||||
|
virtual void onRelease() SK_OVERRIDE;
|
||||||
virtual void onAbandon();
|
virtual void onAbandon() SK_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Format fFormat;
|
Format fFormat;
|
||||||
|
|
|
@ -1110,8 +1110,10 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
|
||||||
samples, format));
|
samples, format));
|
||||||
if (this->attachStencilBufferToRenderTarget(sb, rt)) {
|
if (this->attachStencilBufferToRenderTarget(sb, rt)) {
|
||||||
fLastSuccessfulStencilFmtIdx = sIdx;
|
fLastSuccessfulStencilFmtIdx = sIdx;
|
||||||
|
// This code transfers the creation ref to the
|
||||||
|
// cache and then adds a ref for the render target
|
||||||
|
sb->transferToCacheAndLock();
|
||||||
rt->setStencilBuffer(sb);
|
rt->setStencilBuffer(sb);
|
||||||
sb->unref();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
sb->abandon(); // otherwise we lose sbID
|
sb->abandon(); // otherwise we lose sbID
|
||||||
|
|
Загрузка…
Ссылка в новой задаче