aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2015-02-19 09:09:00 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-02-19 09:09:00 -0800
commit02a44a488605112aa6683c9d919e13b188112ce1 (patch)
tree2331653d7e79b66a0c8dda0168adc36b8becf64f /src/gpu
parent90c6bc4e85df2da37f436ea1da203e194c4740e2 (diff)
Recycle stencil buffers across render targets.
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrGpu.cpp17
-rw-r--r--src/gpu/GrGpu.h5
-rw-r--r--src/gpu/GrStencilBuffer.cpp14
-rw-r--r--src/gpu/GrStencilBuffer.h10
-rw-r--r--src/gpu/GrTest.cpp3
-rw-r--r--src/gpu/gl/GrGLGpu.cpp8
-rw-r--r--src/gpu/gl/GrGLGpu.h3
-rw-r--r--src/gpu/gl/GrGLStencilBuffer.h1
8 files changed, 26 insertions, 35 deletions
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index eef965e5b6..27fed3c582 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -66,7 +66,7 @@ GrTexture* GrGpu::createTexture(const GrSurfaceDesc& desc, bool budgeted,
!(kNoStencil_GrSurfaceFlag & desc.fFlags)) {
SkASSERT(tex->asRenderTarget());
// TODO: defer this and attach dynamically
- if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget(), budgeted)) {
+ if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget())) {
tex->unref();
return NULL;
}
@@ -84,12 +84,13 @@ GrTexture* GrGpu::createTexture(const GrSurfaceDesc& desc, bool budgeted,
return tex;
}
-bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt, bool budgeted) {
+bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
SkASSERT(NULL == rt->getStencilBuffer());
- GrScratchKey sbKey;
- GrStencilBuffer::ComputeKey(rt->width(), rt->height(), rt->numSamples(), &sbKey);
+ GrUniqueKey sbKey;
+ GrStencilBuffer::ComputeSharedStencilBufferKey(rt->width(), rt->height(), rt->numSamples(),
+ &sbKey);
SkAutoTUnref<GrStencilBuffer> sb(static_cast<GrStencilBuffer*>(
- this->getContext()->getResourceCache()->findAndRefScratchResource(sbKey)));
+ this->getContext()->getResourceCache()->findAndRefUniqueResource(sbKey)));
if (sb) {
rt->setStencilBuffer(sb);
bool attached = this->attachStencilBufferToRenderTarget(sb, rt);
@@ -98,7 +99,7 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt, bool budgeted)
}
return attached;
}
- if (this->createStencilBufferForRenderTarget(rt, budgeted, rt->width(), rt->height())) {
+ if (this->createStencilBufferForRenderTarget(rt, rt->width(), rt->height())) {
// Right now we're clearing the stencil buffer here after it is
// attached to an RT for the first time. When we start matching
// stencil buffers with smaller color targets this will no longer
@@ -108,6 +109,7 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt, bool budgeted)
// FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
// FBO status.
this->clearStencil(rt);
+ rt->getStencilBuffer()->resourcePriv().setUniqueKey(sbKey);
return true;
} else {
return false;
@@ -122,8 +124,7 @@ GrTexture* GrGpu::wrapBackendTexture(const GrBackendTextureDesc& desc) {
}
// TODO: defer this and attach dynamically
GrRenderTarget* tgt = tex->asRenderTarget();
- if (tgt &&
- !this->attachStencilBufferToRenderTarget(tgt, true /*budgeted*/)) {
+ if (tgt && !this->attachStencilBufferToRenderTarget(tgt)) {
tex->unref();
return NULL;
} else {
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 2d5eaba8e8..a0950e001c 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -481,8 +481,7 @@ private:
// width and height may be larger than rt (if underlying API allows it).
// Should attach the SB to the RT. Returns false if compatible sb could
// not be created.
- virtual bool createStencilBufferForRenderTarget(GrRenderTarget*, bool budgeted,
- int width, int height) = 0;
+ virtual bool createStencilBufferForRenderTarget(GrRenderTarget*, int width, int height) = 0;
// attaches an existing SB to an existing RT.
virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer*, GrRenderTarget*) = 0;
@@ -491,7 +490,7 @@ private:
virtual void clearStencil(GrRenderTarget* target) = 0;
// Given a rt, find or create a stencil buffer and attach it
- bool attachStencilBufferToRenderTarget(GrRenderTarget* target, bool budgeted);
+ bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
virtual void didAddGpuTraceMarker() = 0;
virtual void didRemoveGpuTraceMarker() = 0;
diff --git a/src/gpu/GrStencilBuffer.cpp b/src/gpu/GrStencilBuffer.cpp
index be463a0ccf..3f2b28f501 100644
--- a/src/gpu/GrStencilBuffer.cpp
+++ b/src/gpu/GrStencilBuffer.cpp
@@ -9,11 +9,11 @@
#include "GrStencilBuffer.h"
#include "GrResourceKey.h"
-void GrStencilBuffer::ComputeKey(int width, int height, int sampleCnt, GrScratchKey* key) {
- static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType();
- GrScratchKey::Builder builder(key, kType, 2);
- SkASSERT(width <= SK_MaxU16);
- SkASSERT(height <= SK_MaxU16);
- builder[0] = width | (height << 16);
- builder[1] = sampleCnt;
+void GrStencilBuffer::ComputeSharedStencilBufferKey(int width, int height, int sampleCnt,
+ GrUniqueKey* key) {
+ static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
+ GrUniqueKey::Builder builder(key, kDomain, 3);
+ builder[0] = width;
+ builder[1] = height;
+ builder[2] = sampleCnt;
}
diff --git a/src/gpu/GrStencilBuffer.h b/src/gpu/GrStencilBuffer.h
index 43d2114581..3788e61afc 100644
--- a/src/gpu/GrStencilBuffer.h
+++ b/src/gpu/GrStencilBuffer.h
@@ -47,7 +47,10 @@ public:
!fLastClipStackRect.contains(clipSpaceRect);
}
- static void ComputeKey(int width, int height, int sampleCnt, GrScratchKey* key);
+ // We create a unique stencil buffer at each width, height and sampleCnt and share it for
+ // all render targets that require a stencil with those params.
+ static void ComputeSharedStencilBufferKey(int width, int height, int sampleCnt,
+ GrUniqueKey* key);
protected:
GrStencilBuffer(GrGpu* gpu, LifeCycle lifeCycle, int width, int height, int bits, int sampleCnt)
@@ -57,11 +60,6 @@ protected:
, fBits(bits)
, fSampleCnt(sampleCnt)
, fLastClipStackGenID(SkClipStack::kInvalidGenID) {
- if (kCached_LifeCycle == lifeCycle) {
- GrScratchKey key;
- ComputeKey(width, height, sampleCnt, &key);
- this->setScratchKey(key);
- }
fLastClipStackRect.setEmpty();
}
diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp
index 8df59ff574..0e1c069ac2 100644
--- a/src/gpu/GrTest.cpp
+++ b/src/gpu/GrTest.cpp
@@ -229,8 +229,7 @@ private:
void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE { return; }
- bool createStencilBufferForRenderTarget(GrRenderTarget*, bool budgeted,
- int width, int height) SK_OVERRIDE {
+ bool createStencilBufferForRenderTarget(GrRenderTarget*, int width, int height) SK_OVERRIDE {
return false;
}
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 5a861d4923..ef4423ba6b 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -442,8 +442,6 @@ GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
GrRenderTarget* tgt = SkNEW_ARGS(GrGLRenderTarget, (this, desc, idDesc));
if (wrapDesc.fStencilBits) {
GrGLStencilBuffer::IDDesc sbDesc;
- sbDesc.fRenderbufferID = 0;
- sbDesc.fLifeCycle = GrGpuResource::kWrapped_LifeCycle;
GrGLStencilBuffer::Format format;
format.fInternalFormat = GrGLStencilBuffer::kUnknownInternalFormat;
format.fPacked = false;
@@ -1128,8 +1126,7 @@ void inline get_stencil_rb_sizes(const GrGLInterface* gl,
}
}
-bool GrGLGpu::createStencilBufferForRenderTarget(GrRenderTarget* rt, bool budgeted, int width,
- int height) {
+bool GrGLGpu::createStencilBufferForRenderTarget(GrRenderTarget* rt, int width, int height) {
// All internally created RTs are also textures. We don't create
// SBs for a client's standalone RT (that is a RT that isn't also a texture).
SkASSERT(rt->asTexture());
@@ -1138,9 +1135,6 @@ bool GrGLGpu::createStencilBufferForRenderTarget(GrRenderTarget* rt, bool budget
int samples = rt->numSamples();
GrGLStencilBuffer::IDDesc sbDesc;
- sbDesc.fRenderbufferID = 0;
- sbDesc.fLifeCycle = budgeted ? GrGpuResource::kCached_LifeCycle
- : GrGpuResource::kUncached_LifeCycle;
int stencilFmtCnt = this->glCaps().stencilFormats().count();
for (int i = 0; i < stencilFmtCnt; ++i) {
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 18f0f749c4..7cbca0108d 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -122,8 +122,7 @@ private:
GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) SK_OVERRIDE;
GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) SK_OVERRIDE;
GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) SK_OVERRIDE;
- bool createStencilBufferForRenderTarget(GrRenderTarget* rt, bool budgeted,
- int width, int height) SK_OVERRIDE;
+ bool createStencilBufferForRenderTarget(GrRenderTarget* rt, int width, int height) SK_OVERRIDE;
bool attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTarget* rt) SK_OVERRIDE;
void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
diff --git a/src/gpu/gl/GrGLStencilBuffer.h b/src/gpu/gl/GrGLStencilBuffer.h
index 305ece8d53..75e98a0a17 100644
--- a/src/gpu/gl/GrGLStencilBuffer.h
+++ b/src/gpu/gl/GrGLStencilBuffer.h
@@ -24,6 +24,7 @@ public:
};
struct IDDesc {
+ IDDesc() : fRenderbufferID(0), fLifeCycle(kCached_LifeCycle) {}
GrGLuint fRenderbufferID;
GrGpuResource::LifeCycle fLifeCycle;
};