Fix ref leak on GrGpu.
Review URL: http://codereview.appspot.com/4323043/
git-svn-id: http://skia.googlecode.com/svn/trunk@1015 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrBufferAllocPool.cpp b/gpu/src/GrBufferAllocPool.cpp
index 35f0c5e..0db12fe 100644
--- a/gpu/src/GrBufferAllocPool.cpp
+++ b/gpu/src/GrBufferAllocPool.cpp
@@ -34,11 +34,14 @@
size_t blockSize,
int preallocBufferCnt) :
fBlocks(GrMax(8, 2*preallocBufferCnt)) {
+
GrAssert(NULL != gpu);
fGpu = gpu;
+ fGpu->ref();
+ fGpuIsReffed = true;
+
fBufferType = bufferType;
fFrequentResetHint = frequentResetHint;
- fGpu->ref();
fBufferPtr = NULL;
fMinBlockSize = GrMax(GrBufferAllocPool_MIN_BLOCK_SIZE, blockSize);
@@ -61,11 +64,18 @@
buffer->unlock();
}
}
- fPreallocBuffers.unrefAll();
while (!fBlocks.empty()) {
destroyBlock();
}
- fGpu->unref();
+ fPreallocBuffers.unrefAll();
+ releaseGpuRef();
+}
+
+void GrBufferAllocPool::releaseGpuRef() {
+ if (fGpuIsReffed) {
+ fGpu->unref();
+ fGpuIsReffed = false;
+ }
}
void GrBufferAllocPool::reset() {
diff --git a/gpu/src/GrBufferAllocPool.h b/gpu/src/GrBufferAllocPool.h
index 80f16ab..7d70ebb 100644
--- a/gpu/src/GrBufferAllocPool.h
+++ b/gpu/src/GrBufferAllocPool.h
@@ -39,10 +39,45 @@
* be allocated at the min size and kept around until the pool is destroyed.
*/
class GrBufferAllocPool : GrNoncopyable {
-protected:
- // We could make the createBuffer a virtual except that we want to use it
- // in the cons for pre-allocated buffers.
+public:
+ /**
+ * Ensures all buffers are unlocked and have all data written to them.
+ * Call before drawing using buffers from the pool.
+ */
+ void unlock();
+
+ /**
+ * Invalidates all the data in the pool, unrefs non-preallocated buffers.
+ */
+ void reset();
+
+ /**
+ * Gets the number of preallocated buffers that are yet to be used.
+ */
+ int preallocatedBuffersRemaining() const;
+
+ /**
+ * gets the number of preallocated buffers
+ */
+ int preallocatedBufferCount() const;
+
+ /**
+ * Frees data from makeSpaces in LIFO order.
+ */
+ void putBack(size_t bytes);
+
+ /**
+ * Gets the GrGpu that this pool is associated with.
+ */
+ GrGpu* getGpu() { return fGpu; }
+
+protected:
+ /**
+ * Used to determine what type of buffers to create. We could make the
+ * createBuffer a virtual except that we want to use it in the cons for
+ * pre-allocated buffers.
+ */
enum BufferType {
kVertex_BufferType,
kIndex_BufferType,
@@ -72,40 +107,6 @@
virtual ~GrBufferAllocPool();
-public:
- /**
- * Ensures all buffers are unlocked and have all data written to them.
- * Call before drawing using buffers from the pool.
- */
- void unlock();
-
- /**
- * Invalidates all the data in the pool, unrefs non-preallocated buffers.
- */
- void reset();
-
- /**
- * Gets the number of preallocated buffers that are yet to be used.
- */
- int preallocatedBuffersRemaining() const;
-
- /**
- * gets the number of preallocated buffers
- */
- int preallocatedBufferCount() const;
-
-
- /**
- * Frees data from makeSpaces in LIFO order.
- */
- void putBack(size_t bytes);
-
- /**
- * Gets the GrGpu that this pool is associated with.
- */
- GrGpu* getGpu() { return fGpu; }
-
-protected:
/**
* Gets the size of the preallocated buffers.
*
@@ -155,6 +156,10 @@
private:
+ // The GrGpu must be able to clear the ref of pools it creates as members
+ friend class GrGpu;
+ void releaseGpuRef();
+
struct BufferBlock {
size_t fBytesFree;
GrGeometryBuffer* fBuffer;
@@ -168,6 +173,7 @@
#endif
GrGpu* fGpu;
+ bool fGpuIsReffed;
bool fFrequentResetHint;
GrTDArray<GrGeometryBuffer*> fPreallocBuffers;
size_t fMinBlockSize;
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 1db9252..378b881 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -432,7 +432,7 @@
const GrPath& path = clip.getPath(c);
pathIter.reset(path);
pr = this->getClipPathRenderer(&pathIter, NonInvertedFill(fill));
- canRenderDirectToStencil =
+ canRenderDirectToStencil =
!pr->requiresStencilPass(this, &pathIter,
NonInvertedFill(fill));
}
@@ -441,14 +441,14 @@
int passes;
GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClipPasses];
- bool canDrawDirectToClip; // Given the renderer, the element,
+ bool canDrawDirectToClip; // Given the renderer, the element,
// fill rule, and set operation can
// we render the element directly to
// stencil bit used for clipping.
- canDrawDirectToClip =
- GrStencilSettings::GetClipPasses(op,
+ canDrawDirectToClip =
+ GrStencilSettings::GetClipPasses(op,
canRenderDirectToStencil,
- clipBit,
+ clipBit,
IsFillInverted(fill),
&passes, stencilSettings);
@@ -469,7 +469,7 @@
} else {
if (canRenderDirectToStencil) {
this->setStencil(gDrawToStencil);
- pr->drawPath(this, 0,
+ pr->drawPath(this, 0,
&pathIter,
NonInvertedFill(fill),
NULL);
@@ -519,12 +519,12 @@
GrPathRenderer* GrGpu::getClipPathRenderer(GrPathIter* path,
GrPathFill fill) {
- if (NULL != fClientPathRenderer &&
+ if (NULL != fClientPathRenderer &&
fClientPathRenderer->canDrawPath(this, path, fill)) {
return fClientPathRenderer;
} else {
if (NULL == fDefaultPathRenderer) {
- fDefaultPathRenderer =
+ fDefaultPathRenderer =
new GrDefaultPathRenderer(this->supportsTwoSidedStencil(),
this->supportsStencilWrapOps());
}
@@ -603,6 +603,7 @@
fVertexPool = new GrVertexBufferAllocPool(this, true,
VERTEX_POOL_VB_SIZE,
VERTEX_POOL_VB_COUNT);
+ fVertexPool->releaseGpuRef();
} else if (!fVertexPoolInUse) {
// the client doesn't have valid data in the pool
fVertexPool->reset();
@@ -612,6 +613,7 @@
void GrGpu::prepareIndexPool() {
if (NULL == fIndexPool) {
fIndexPool = new GrIndexBufferAllocPool(this, true, 0, 1);
+ fIndexPool->releaseGpuRef();
} else if (!fIndexPoolInUse) {
// the client doesn't have valid data in the pool
fIndexPool->reset();