Use a single stencil buffer for a given width,height,samplecount
Review URL: http://codereview.appspot.com/4854044/ git-svn-id: http://skia.googlecode.com/svn/trunk@2061 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
f121b05254
commit
558a75bcb3
@ -21,6 +21,7 @@ class GrIndexBufferAllocPool;
|
|||||||
class GrInOrderDrawBuffer;
|
class GrInOrderDrawBuffer;
|
||||||
class GrResourceEntry;
|
class GrResourceEntry;
|
||||||
class GrResourceCache;
|
class GrResourceCache;
|
||||||
|
class GrStencilBuffer;
|
||||||
class GrVertexBufferAllocPool;
|
class GrVertexBufferAllocPool;
|
||||||
|
|
||||||
|
|
||||||
@ -580,6 +581,17 @@ public:
|
|||||||
void resetStats();
|
void resetStats();
|
||||||
const GrGpuStats& getStats() const;
|
const GrGpuStats& getStats() const;
|
||||||
void printStats() const;
|
void printStats() const;
|
||||||
|
/**
|
||||||
|
* Stencil buffers add themselves to the cache using
|
||||||
|
* addAndLockStencilBuffer. When a SB's RT-attachment count
|
||||||
|
* reaches zero the SB unlocks itself using unlockStencilBuffer and is
|
||||||
|
* eligible for purging. findStencilBuffer is called to check the cache for
|
||||||
|
* a SB that matching an RT's criteria. If a match is found that has been
|
||||||
|
* unlocked (its attachment count has reached 0) then it will be relocked.
|
||||||
|
*/
|
||||||
|
GrResourceEntry* addAndLockStencilBuffer(GrStencilBuffer* sb);
|
||||||
|
void unlockStencilBuffer(GrResourceEntry* sbEntry);
|
||||||
|
GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// used to keep track of when we need to flush the draw buffer
|
// used to keep track of when we need to flush the draw buffer
|
||||||
|
@ -32,8 +32,8 @@ class GrTexture;
|
|||||||
* that wrap externally created render targets.
|
* that wrap externally created render targets.
|
||||||
*/
|
*/
|
||||||
class GrRenderTarget : public GrResource {
|
class GrRenderTarget : public GrResource {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the width of the rendertarget
|
* @return the width of the rendertarget
|
||||||
*/
|
*/
|
||||||
@ -177,8 +177,7 @@ protected:
|
|||||||
, fAllocatedWidth(allocatedWidth)
|
, fAllocatedWidth(allocatedWidth)
|
||||||
, fAllocatedHeight(allocatedHeight)
|
, fAllocatedHeight(allocatedHeight)
|
||||||
, fConfig(config)
|
, fConfig(config)
|
||||||
, fSampleCnt(sampleCnt)
|
, fSampleCnt(sampleCnt) {
|
||||||
{
|
|
||||||
fResolveRect.setLargestInverted();
|
fResolveRect.setLargestInverted();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,17 +192,16 @@ protected:
|
|||||||
fTexture = NULL;
|
fTexture = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrStencilBuffer* fStencilBuffer;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GrTexture* fTexture; // not ref'ed
|
GrStencilBuffer* fStencilBuffer;
|
||||||
int fWidth;
|
GrTexture* fTexture; // not ref'ed
|
||||||
int fHeight;
|
int fWidth;
|
||||||
int fAllocatedWidth;
|
int fHeight;
|
||||||
int fAllocatedHeight;
|
int fAllocatedWidth;
|
||||||
GrPixelConfig fConfig;
|
int fAllocatedHeight;
|
||||||
int fSampleCnt;
|
GrPixelConfig fConfig;
|
||||||
GrIRect fResolveRect;
|
int fSampleCnt;
|
||||||
|
GrIRect fResolveRect;
|
||||||
|
|
||||||
typedef GrResource INHERITED;
|
typedef GrResource INHERITED;
|
||||||
};
|
};
|
||||||
|
@ -64,7 +64,9 @@ public:
|
|||||||
* Approximate number of bytes used by the texture
|
* Approximate number of bytes used by the texture
|
||||||
*/
|
*/
|
||||||
virtual size_t sizeInBytes() const {
|
virtual size_t sizeInBytes() const {
|
||||||
return fAllocatedWidth * fAllocatedHeight * GrBytesPerPixel(fConfig);
|
return (size_t) fAllocatedWidth *
|
||||||
|
fAllocatedHeight *
|
||||||
|
GrBytesPerPixel(fConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "GrPathRenderer.h"
|
#include "GrPathRenderer.h"
|
||||||
#include "GrPathUtils.h"
|
#include "GrPathUtils.h"
|
||||||
#include "GrResourceCache.h"
|
#include "GrResourceCache.h"
|
||||||
|
#include "GrStencilBuffer.h"
|
||||||
#include "GrTextStrike.h"
|
#include "GrTextStrike.h"
|
||||||
#include "SkTrace.h"
|
#include "SkTrace.h"
|
||||||
|
|
||||||
@ -126,9 +127,14 @@ int GrContext::PaintStageVertexLayoutBits(
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kNPOTBit = 0x1,
|
// flags for textures
|
||||||
kFilterBit = 0x2,
|
kNPOTBit = 0x1,
|
||||||
kScratchBit = 0x4,
|
kFilterBit = 0x2,
|
||||||
|
kScratchBit = 0x4,
|
||||||
|
|
||||||
|
// resource type
|
||||||
|
kTextureBit = 0x8,
|
||||||
|
kStencilBufferBit = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
GrTexture* GrContext::TextureCacheEntry::texture() const {
|
GrTexture* GrContext::TextureCacheEntry::texture() const {
|
||||||
@ -176,8 +182,26 @@ bool gen_texture_key_values(const GrGpu* gpu,
|
|||||||
v[3] |= kScratchBit;
|
v[3] |= kScratchBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v[3] |= kTextureBit;
|
||||||
|
|
||||||
return v[3] & kNPOTBit;
|
return v[3] & kNPOTBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we should never have more than one stencil buffer with same combo of
|
||||||
|
// (width,height,samplecount)
|
||||||
|
void gen_stencil_key_values(int width, int height,
|
||||||
|
int sampleCnt, uint32_t v[4]) {
|
||||||
|
v[0] = width;
|
||||||
|
v[1] = height;
|
||||||
|
v[2] = sampleCnt;
|
||||||
|
v[3] = kStencilBufferBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_stencil_key_values(const GrStencilBuffer* sb,
|
||||||
|
uint32_t v[4]) {
|
||||||
|
gen_stencil_key_values(sb->width(), sb->height(),
|
||||||
|
sb->numSamples(), v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GrContext::TextureCacheEntry GrContext::findAndLockTexture(TextureKey key,
|
GrContext::TextureCacheEntry GrContext::findAndLockTexture(TextureKey key,
|
||||||
@ -187,7 +211,34 @@ GrContext::TextureCacheEntry GrContext::findAndLockTexture(TextureKey key,
|
|||||||
uint32_t v[4];
|
uint32_t v[4];
|
||||||
gen_texture_key_values(fGpu, sampler, key, width, height, false, v);
|
gen_texture_key_values(fGpu, sampler, key, width, height, false, v);
|
||||||
GrResourceKey resourceKey(v);
|
GrResourceKey resourceKey(v);
|
||||||
return TextureCacheEntry(fTextureCache->findAndLock(resourceKey));
|
return TextureCacheEntry(fTextureCache->findAndLock(resourceKey,
|
||||||
|
GrResourceCache::kNested_LockType));
|
||||||
|
}
|
||||||
|
|
||||||
|
GrResourceEntry* GrContext::addAndLockStencilBuffer(GrStencilBuffer* sb) {
|
||||||
|
uint32_t v[4];
|
||||||
|
gen_stencil_key_values(sb, v);
|
||||||
|
GrResourceKey resourceKey(v);
|
||||||
|
return fTextureCache->createAndLock(resourceKey, sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
GrStencilBuffer* GrContext::findStencilBuffer(int width, int height,
|
||||||
|
int sampleCnt) {
|
||||||
|
uint32_t v[4];
|
||||||
|
gen_stencil_key_values(width, height, sampleCnt, v);
|
||||||
|
GrResourceKey resourceKey(v);
|
||||||
|
GrResourceEntry* entry = fTextureCache->findAndLock(resourceKey,
|
||||||
|
GrResourceCache::kSingle_LockType);
|
||||||
|
if (NULL != entry) {
|
||||||
|
GrStencilBuffer* sb = (GrStencilBuffer*) entry->resource();
|
||||||
|
return sb;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrContext::unlockStencilBuffer(GrResourceEntry* sbEntry) {
|
||||||
|
fTextureCache->unlock(sbEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stretchImage(void* dst,
|
static void stretchImage(void* dst,
|
||||||
@ -376,7 +427,8 @@ GrContext::TextureCacheEntry GrContext::lockScratchTexture(
|
|||||||
uint32_t v[4];
|
uint32_t v[4];
|
||||||
gen_scratch_tex_key_values(fGpu, desc, v);
|
gen_scratch_tex_key_values(fGpu, desc, v);
|
||||||
GrResourceKey key(v);
|
GrResourceKey key(v);
|
||||||
entry = fTextureCache->findAndLock(key);
|
entry = 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 != entry || kExact_ScratchTexMatch == match) {
|
if (NULL != entry || kExact_ScratchTexMatch == match) {
|
||||||
|
@ -78,7 +78,7 @@ void GrGLRenderTarget::onRelease() {
|
|||||||
fMSColorRenderbufferID = 0;
|
fMSColorRenderbufferID = 0;
|
||||||
GrSafeUnref(fTexIDObj);
|
GrSafeUnref(fTexIDObj);
|
||||||
fTexIDObj = NULL;
|
fTexIDObj = NULL;
|
||||||
GrSafeSetNull(fStencilBuffer);
|
this->setStencilBuffer(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLRenderTarget::onAbandon() {
|
void GrGLRenderTarget::onAbandon() {
|
||||||
@ -89,6 +89,6 @@ void GrGLRenderTarget::onAbandon() {
|
|||||||
fTexIDObj->abandon();
|
fTexIDObj->abandon();
|
||||||
fTexIDObj = NULL;
|
fTexIDObj = NULL;
|
||||||
}
|
}
|
||||||
GrSafeSetNull(fStencilBuffer);
|
this->setStencilBuffer(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,8 +25,9 @@ public:
|
|||||||
|
|
||||||
GrGLStencilBuffer(GrGpu* gpu, GrGLint rbid,
|
GrGLStencilBuffer(GrGpu* gpu, GrGLint rbid,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
|
int sampleCnt,
|
||||||
const Format& format)
|
const Format& format)
|
||||||
: GrStencilBuffer(gpu, width, height, format.fStencilBits)
|
: GrStencilBuffer(gpu, width, height, format.fStencilBits, sampleCnt)
|
||||||
, fFormat(format)
|
, fFormat(format)
|
||||||
, fRenderbufferID(rbid) {
|
, fRenderbufferID(rbid) {
|
||||||
}
|
}
|
||||||
@ -36,7 +37,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t sizeInBytes() const {
|
virtual size_t sizeInBytes() const {
|
||||||
return this->width() * this->height() * fFormat.fTotalBits;
|
return (size_t) this->width() *
|
||||||
|
this->height() *
|
||||||
|
fFormat.fTotalBits *
|
||||||
|
GrMax(1,this->numSamples());
|
||||||
}
|
}
|
||||||
|
|
||||||
GrGLuint renderbufferID() const {
|
GrGLuint renderbufferID() const {
|
||||||
|
@ -8,8 +8,10 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "GrGpu.h"
|
#include "GrGpu.h"
|
||||||
|
|
||||||
#include "GrBufferAllocPool.h"
|
#include "GrBufferAllocPool.h"
|
||||||
#include "GrClipIterator.h"
|
#include "GrClipIterator.h"
|
||||||
|
#include "GrContext.h"
|
||||||
#include "GrIndexBuffer.h"
|
#include "GrIndexBuffer.h"
|
||||||
#include "GrPathRenderer.h"
|
#include "GrPathRenderer.h"
|
||||||
#include "GrGLStencilBuffer.h"
|
#include "GrGLStencilBuffer.h"
|
||||||
@ -59,7 +61,7 @@ GrGpu::GrGpu()
|
|||||||
}
|
}
|
||||||
|
|
||||||
GrGpu::~GrGpu() {
|
GrGpu::~GrGpu() {
|
||||||
releaseResources();
|
this->releaseResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGpu::abandonResources() {
|
void GrGpu::abandonResources() {
|
||||||
@ -155,10 +157,24 @@ GrTexture* GrGpu::createTexture(const GrTextureDesc& desc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
||||||
// TODO: use a cache of stencil buffers rather than create per-rt.
|
GrAssert(NULL == rt->getStencilBuffer());
|
||||||
bool ret = this->createStencilBufferForRenderTarget(rt, rt->allocatedWidth(),
|
GrStencilBuffer* sb =
|
||||||
rt->allocatedHeight());
|
this->getContext()->findStencilBuffer(rt->allocatedWidth(),
|
||||||
if (ret) {
|
rt->allocatedHeight(),
|
||||||
|
rt->numSamples());
|
||||||
|
if (NULL != sb) {
|
||||||
|
rt->setStencilBuffer(sb);
|
||||||
|
bool attached = this->attachStencilBufferToRenderTarget(sb, rt);
|
||||||
|
if (!attached) {
|
||||||
|
rt->setStencilBuffer(NULL);
|
||||||
|
}
|
||||||
|
return attached;
|
||||||
|
}
|
||||||
|
if (this->createStencilBufferForRenderTarget(rt, rt->allocatedWidth(),
|
||||||
|
rt->allocatedHeight())) {
|
||||||
|
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
|
||||||
@ -171,8 +187,10 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
|||||||
fCurrDrawState.fRenderTarget = rt;
|
fCurrDrawState.fRenderTarget = rt;
|
||||||
this->clearStencil();
|
this->clearStencil();
|
||||||
fCurrDrawState.fRenderTarget = oldRT;
|
fCurrDrawState.fRenderTarget = oldRT;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GrRenderTarget* GrGpu::createRenderTargetFrom3DApiState() {
|
GrRenderTarget* GrGpu::createRenderTargetFrom3DApiState() {
|
||||||
|
@ -602,6 +602,7 @@ GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc)
|
|||||||
|
|
||||||
if (isRenderTarget) {
|
if (isRenderTarget) {
|
||||||
rtDesc.fRTFBOID = desc.fPlatformRenderTarget;
|
rtDesc.fRTFBOID = desc.fPlatformRenderTarget;
|
||||||
|
rtDesc.fConfig = desc.fConfig;
|
||||||
#if GR_USE_PLATFORM_CREATE_SAMPLE_COUNT
|
#if GR_USE_PLATFORM_CREATE_SAMPLE_COUNT
|
||||||
if (desc.fSampleCnt) {
|
if (desc.fSampleCnt) {
|
||||||
#else
|
#else
|
||||||
@ -638,7 +639,7 @@ GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc)
|
|||||||
format.fStencilBits = desc.fStencilBits;
|
format.fStencilBits = desc.fStencilBits;
|
||||||
format.fTotalBits = desc.fStencilBits;
|
format.fTotalBits = desc.fStencilBits;
|
||||||
sb = new GrGLStencilBuffer(this, 0, desc.fWidth,
|
sb = new GrGLStencilBuffer(this, 0, desc.fWidth,
|
||||||
desc.fHeight, format);
|
desc.fHeight, rtDesc.fSampleCnt, format);
|
||||||
}
|
}
|
||||||
rtDesc.fOwnIDs = false;
|
rtDesc.fOwnIDs = false;
|
||||||
}
|
}
|
||||||
@ -836,6 +837,7 @@ GrRenderTarget* GrGpuGL::onCreateRenderTargetFrom3DApiState() {
|
|||||||
GrGLIRect viewport;
|
GrGLIRect viewport;
|
||||||
viewport.setFromGLViewport();
|
viewport.setFromGLViewport();
|
||||||
int stencilBits = get_fbo_stencil_bits(arbFBO);
|
int stencilBits = get_fbo_stencil_bits(arbFBO);
|
||||||
|
GR_GL_GetIntegerv(GR_GL_SAMPLES, &rtDesc.fSampleCnt);
|
||||||
|
|
||||||
GrGLStencilBuffer* sb = NULL;
|
GrGLStencilBuffer* sb = NULL;
|
||||||
if (stencilBits) {
|
if (stencilBits) {
|
||||||
@ -846,10 +848,10 @@ GrRenderTarget* GrGpuGL::onCreateRenderTargetFrom3DApiState() {
|
|||||||
format.fStencilBits = stencilBits;
|
format.fStencilBits = stencilBits;
|
||||||
format.fTotalBits = stencilBits;
|
format.fTotalBits = stencilBits;
|
||||||
sb = new GrGLStencilBuffer(this, 0, viewport.fWidth,
|
sb = new GrGLStencilBuffer(this, 0, viewport.fWidth,
|
||||||
viewport.fHeight, format);
|
viewport.fHeight, rtDesc.fSampleCnt,
|
||||||
|
format);
|
||||||
}
|
}
|
||||||
|
|
||||||
GR_GL_GetIntegerv(GR_GL_SAMPLES, &rtDesc.fSampleCnt);
|
|
||||||
GrGLenum fmat = get_fbo_color_format();
|
GrGLenum fmat = get_fbo_color_format();
|
||||||
if (kUnknownGLFormat == fmat) {
|
if (kUnknownGLFormat == fmat) {
|
||||||
rtDesc.fConfig = get_implied_color_config(arbFBO);
|
rtDesc.fConfig = get_implied_color_config(arbFBO);
|
||||||
@ -1326,7 +1328,7 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
|
|||||||
// that we won't go through this loop more than once after the
|
// that we won't go through this loop more than once after the
|
||||||
// first (painful) stencil creation.
|
// first (painful) stencil creation.
|
||||||
int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt;
|
int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt;
|
||||||
// we do this if so that we don't call the multisample
|
// we do this "if" so that we don't call the multisample
|
||||||
// version on a GL that doesn't have an MSAA extension.
|
// version on a GL that doesn't have an MSAA extension.
|
||||||
if (samples > 1) {
|
if (samples > 1) {
|
||||||
GR_GL_NO_ERR(RenderbufferStorageMultisample(
|
GR_GL_NO_ERR(RenderbufferStorageMultisample(
|
||||||
@ -1347,9 +1349,11 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
|
|||||||
// sizes GL gives us. In that case we query for the size.
|
// sizes GL gives us. In that case we query for the size.
|
||||||
GrGLStencilBuffer::Format format = fStencilFormats[sIdx];
|
GrGLStencilBuffer::Format format = fStencilFormats[sIdx];
|
||||||
get_stencil_rb_sizes(sbID, &format);
|
get_stencil_rb_sizes(sbID, &format);
|
||||||
sb = new GrGLStencilBuffer(this, sbID, width, height, format);
|
sb = new GrGLStencilBuffer(this, sbID, width, height,
|
||||||
|
samples, format);
|
||||||
if (this->attachStencilBufferToRenderTarget(sb, rt)) {
|
if (this->attachStencilBufferToRenderTarget(sb, rt)) {
|
||||||
fLastSuccessfulStencilFmtIdx = sIdx;
|
fLastSuccessfulStencilFmtIdx = sIdx;
|
||||||
|
rt->setStencilBuffer(sb);
|
||||||
sb->unref();
|
sb->unref();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1358,7 +1362,7 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
GR_GL(DeleteRenderbuffers(1, &sbID));
|
GR_GL(DeleteRenderbuffers(1, &sbID));
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
|
bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
|
||||||
@ -1414,7 +1418,6 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
rt->setStencilBuffer(sb);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,10 @@ size_t GrRenderTarget::sizeInBytes() const {
|
|||||||
} else {
|
} else {
|
||||||
colorBits = GrBytesPerPixel(fConfig);
|
colorBits = GrBytesPerPixel(fConfig);
|
||||||
}
|
}
|
||||||
return fAllocatedWidth * fAllocatedHeight * colorBits * GrMax(1,fSampleCnt);
|
return (size_t) fAllocatedWidth *
|
||||||
|
fAllocatedHeight *
|
||||||
|
colorBits *
|
||||||
|
GrMax(1,fSampleCnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrRenderTarget::flagAsNeedingResolve(const GrIRect* rect) {
|
void GrRenderTarget::flagAsNeedingResolve(const GrIRect* rect) {
|
||||||
@ -59,5 +62,13 @@ void GrRenderTarget::overrideResolveRect(const GrIRect rect) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GrRenderTarget::setStencilBuffer(GrStencilBuffer* stencilBuffer) {
|
void GrRenderTarget::setStencilBuffer(GrStencilBuffer* stencilBuffer) {
|
||||||
GrSafeAssign(fStencilBuffer, stencilBuffer);
|
if (NULL != fStencilBuffer) {
|
||||||
|
fStencilBuffer->wasDetachedFromRenderTarget(this);
|
||||||
|
fStencilBuffer->unref();
|
||||||
|
}
|
||||||
|
fStencilBuffer = stencilBuffer;
|
||||||
|
if (NULL != fStencilBuffer) {
|
||||||
|
fStencilBuffer->wasAttachedToRenderTarget(this);
|
||||||
|
fStencilBuffer->ref();
|
||||||
|
}
|
||||||
}
|
}
|
@ -155,7 +155,8 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
GrResourceEntry* GrResourceCache::findAndLock(const GrResourceKey& key) {
|
GrResourceEntry* GrResourceCache::findAndLock(const GrResourceKey& key,
|
||||||
|
LockType type) {
|
||||||
GrAutoResourceCacheValidate atcv(this);
|
GrAutoResourceCacheValidate atcv(this);
|
||||||
|
|
||||||
GrResourceEntry* entry = fCache.find(key);
|
GrResourceEntry* entry = fCache.find(key);
|
||||||
@ -163,7 +164,9 @@ GrResourceEntry* GrResourceCache::findAndLock(const GrResourceKey& key) {
|
|||||||
this->internalDetach(entry, false);
|
this->internalDetach(entry, false);
|
||||||
// mark the entry as "busy" so it doesn't get purged
|
// mark the entry as "busy" so it doesn't get purged
|
||||||
// do this between detach and attach for locked count tracking
|
// do this between detach and attach for locked count tracking
|
||||||
entry->lock();
|
if (kNested_LockType == type || !entry->isLocked()) {
|
||||||
|
entry->lock();
|
||||||
|
}
|
||||||
this->attachToHead(entry, false);
|
this->attachToHead(entry, false);
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
|
@ -208,11 +208,19 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setLimits(int maxResource, size_t maxResourceBytes);
|
void setLimits(int maxResource, size_t maxResourceBytes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls whether locks should be nestable or not.
|
||||||
|
*/
|
||||||
|
enum LockType {
|
||||||
|
kNested_LockType,
|
||||||
|
kSingle_LockType,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
GrResourceEntry* findAndLock(const GrResourceKey&);
|
GrResourceEntry* findAndLock(const GrResourceKey&, LockType style);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new entry, based on the specified key and resource, and return
|
* Create a new entry, based on the specified key and resource, and return
|
||||||
|
26
gpu/src/GrStencilBuffer.cpp
Normal file
26
gpu/src/GrStencilBuffer.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GrStencilBuffer.h"
|
||||||
|
|
||||||
|
#include "GrContext.h"
|
||||||
|
#include "GrGpu.h"
|
||||||
|
|
||||||
|
void GrStencilBuffer::wasDetachedFromRenderTarget(const GrRenderTarget* rt) {
|
||||||
|
GrAssert(fRTAttachmentCnt > 0);
|
||||||
|
if (0 == --fRTAttachmentCnt && NULL != fCacheEntry) {
|
||||||
|
this->getGpu()->getContext()->unlockStencilBuffer(fCacheEntry);
|
||||||
|
// At this point we could be deleted!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrStencilBuffer::transferToCacheAndLock() {
|
||||||
|
GrAssert(NULL == fCacheEntry);
|
||||||
|
fCacheEntry =
|
||||||
|
this->getGpu()->getContext()->addAndLockStencilBuffer(this);
|
||||||
|
}
|
@ -13,11 +13,24 @@
|
|||||||
#include "GrClip.h"
|
#include "GrClip.h"
|
||||||
#include "GrResource.h"
|
#include "GrResource.h"
|
||||||
|
|
||||||
|
// REMOVE ME
|
||||||
|
#include "GrRenderTarget.h"
|
||||||
|
|
||||||
|
class GrRenderTarget;
|
||||||
|
class GrResourceEntry;
|
||||||
|
|
||||||
class GrStencilBuffer : public GrResource {
|
class GrStencilBuffer : public GrResource {
|
||||||
public:
|
public:
|
||||||
|
virtual ~GrStencilBuffer() {
|
||||||
|
// currently each rt that has attached this sb keeps a ref
|
||||||
|
// TODO: allow SB to be purged and detach itself from rts
|
||||||
|
GrAssert(0 == fRTAttachmentCnt);
|
||||||
|
}
|
||||||
|
|
||||||
int width() const { return fWidth; }
|
int width() const { return fWidth; }
|
||||||
int height() const { return fHeight; }
|
int height() const { return fHeight; }
|
||||||
int bits() const { return fBits; }
|
int bits() const { return fBits; }
|
||||||
|
int numSamples() const { return fSampleCnt; }
|
||||||
|
|
||||||
// called to note the last clip drawn to this buffer.
|
// called to note the last clip drawn to this buffer.
|
||||||
void setLastClip(const GrClip& clip, int width, int height) {
|
void setLastClip(const GrClip& clip, int width, int height) {
|
||||||
@ -43,26 +56,43 @@ public:
|
|||||||
return fLastClip;
|
return fLastClip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// places the sb in the cache and locks it. Caller transfers
|
||||||
|
// a ref to the the cache which will unref when purged.
|
||||||
|
void transferToCacheAndLock();
|
||||||
|
|
||||||
|
void wasAttachedToRenderTarget(const GrRenderTarget* rt) {
|
||||||
|
++fRTAttachmentCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wasDetachedFromRenderTarget(const GrRenderTarget* rt);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GrStencilBuffer(GrGpu* gpu, int width, int height, int bits)
|
GrStencilBuffer(GrGpu* gpu, int width, int height, int bits, int sampleCnt)
|
||||||
: GrResource(gpu)
|
: GrResource(gpu)
|
||||||
, fWidth(width)
|
, fWidth(width)
|
||||||
, fHeight(height)
|
, fHeight(height)
|
||||||
, fBits(bits)
|
, fBits(bits)
|
||||||
|
, fSampleCnt(sampleCnt)
|
||||||
, fLastClip()
|
, fLastClip()
|
||||||
, fLastClipWidth(-1)
|
, fLastClipWidth(-1)
|
||||||
, fLastClipHeight(-1) {
|
, fLastClipHeight(-1)
|
||||||
|
, fCacheEntry(NULL)
|
||||||
|
, fRTAttachmentCnt(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fWidth;
|
int fWidth;
|
||||||
int fHeight;
|
int fHeight;
|
||||||
int fBits;
|
int fBits;
|
||||||
|
int fSampleCnt;
|
||||||
|
|
||||||
GrClip fLastClip;
|
GrClip fLastClip;
|
||||||
int fLastClipWidth;
|
int fLastClipWidth;
|
||||||
int fLastClipHeight;
|
int fLastClipHeight;
|
||||||
|
|
||||||
|
GrResourceEntry* fCacheEntry;
|
||||||
|
int fRTAttachmentCnt;
|
||||||
|
|
||||||
typedef GrResource INHERITED;
|
typedef GrResource INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -180,6 +180,7 @@
|
|||||||
'../gpu/src/GrResourceCache.cpp',
|
'../gpu/src/GrResourceCache.cpp',
|
||||||
'../gpu/src/GrResourceCache.h',
|
'../gpu/src/GrResourceCache.h',
|
||||||
'../gpu/src/GrStencil.cpp',
|
'../gpu/src/GrStencil.cpp',
|
||||||
|
'../gpu/src/GrStencilBuffer.cpp',
|
||||||
'../gpu/src/GrStencilBuffer.h',
|
'../gpu/src/GrStencilBuffer.h',
|
||||||
'../gpu/src/GrTesselatedPathRenderer.cpp',
|
'../gpu/src/GrTesselatedPathRenderer.cpp',
|
||||||
'../gpu/src/GrTextContext.cpp',
|
'../gpu/src/GrTextContext.cpp',
|
||||||
|
Loading…
Reference in New Issue
Block a user