aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-03-30 21:26:44 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-03-30 21:26:44 +0000
commit8fe72477f204b1a45393e6a64caa84fd287b805b (patch)
treeee45cdc16a5e66a5a198920897d82db4284b97da /gpu
parenta7d948523dce6044fc02db90726e5f971a93628b (diff)
Add GrResource base class for ibs, texs, vbs, etc.
Add lostContext() to GrContext. Review URL: http://codereview.appspot.com/4328044/ git-svn-id: http://skia.googlecode.com/svn/trunk@1026 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu')
-rw-r--r--gpu/include/GrAtlas.h2
-rw-r--r--gpu/include/GrContext.h27
-rw-r--r--gpu/include/GrGLIndexBuffer.h29
-rw-r--r--gpu/include/GrGLTexture.h97
-rw-r--r--gpu/include/GrGLVertexBuffer.h26
-rw-r--r--gpu/include/GrGeometryBuffer.h76
-rw-r--r--gpu/include/GrGpu.h30
-rw-r--r--gpu/include/GrIndexBuffer.h4
-rw-r--r--gpu/include/GrRefCnt.h8
-rw-r--r--gpu/include/GrResource.h77
-rw-r--r--gpu/include/GrTextStrike.h1
-rw-r--r--gpu/include/GrTexture.h52
-rw-r--r--gpu/include/GrTextureCache.h8
-rw-r--r--gpu/include/GrVertexBuffer.h4
-rw-r--r--gpu/src/GrAtlas.cpp12
-rw-r--r--gpu/src/GrContext.cpp60
-rw-r--r--gpu/src/GrGLIndexBuffer.cpp51
-rw-r--r--gpu/src/GrGLTexture.cpp68
-rw-r--r--gpu/src/GrGLVertexBuffer.cpp52
-rw-r--r--gpu/src/GrGpu.cpp99
-rw-r--r--gpu/src/GrGpuGL.cpp14
-rw-r--r--gpu/src/GrResource.cpp41
-rw-r--r--gpu/src/GrTextStrike.cpp11
-rw-r--r--gpu/src/GrTextureCache.cpp7
24 files changed, 555 insertions, 301 deletions
diff --git a/gpu/include/GrAtlas.h b/gpu/include/GrAtlas.h
index a933842757..406b45c138 100644
--- a/gpu/include/GrAtlas.h
+++ b/gpu/include/GrAtlas.h
@@ -80,8 +80,6 @@ public:
// to be called by ~GrAtlas()
void freePlot(int x, int y);
- void abandonAll();
-
private:
GrGpu* fGpu;
GrTexture* fTexture[kCount_GrMaskFormats];
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index 106ac8a502..cccc14f428 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -52,14 +52,27 @@ public:
*/
void resetContext();
- ///////////////////////////////////////////////////////////////////////////
- // Textures
+ /**
+ * Abandons all gpu resources, assumes 3D API state is unknown. Call this
+ * if you have lost the associated GPU context, and thus internal texture,
+ * buffer, etc. references/IDs are now invalid. Should be called even when
+ * GrContext is no longer going to be used for two reasons:
+ * 1) ~GrContext will not try to free the objects in the 3D API.
+ * 2) If you've created GrResources that outlive the GrContext they will
+ * be marked as invalid (GrResource::isValid()) and won't attempt to
+ * free their underlying resource in the 3D API.
+ * Content drawn since the last GrContext::flush() may be lost.
+ */
+ void contextLost();
/**
- * Abandons all textures. Call this if you have lost the associated GPU
- * context, and thus internal texture references/IDs are now invalid.
+ * Frees gpu created by the context. Can be called to reduce GPU memory
+ * pressure.
*/
- void abandonAllTextures();
+ void freeGpuResources();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Textures
/**
* Search for an entry with the same Key. If found, "lock" it and return it.
@@ -409,7 +422,7 @@ public:
* @param flagsBitfield flags that control the flushing behavior. See
* FlushBits.
*/
- void flush(int flagsBitfield);
+ void flush(int flagsBitfield = 0);
/**
* Return true on success, i.e. if we could copy the specified range of
* pixels from the current render-target into the buffer, converting into
@@ -489,6 +502,8 @@ private:
GrContext(GrGpu* gpu);
+ void setupDrawBuffer();
+
void flushDrawBuffer();
static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
diff --git a/gpu/include/GrGLIndexBuffer.h b/gpu/include/GrGLIndexBuffer.h
index 0ecbe6d8a1..92aadcf90d 100644
--- a/gpu/include/GrGLIndexBuffer.h
+++ b/gpu/include/GrGLIndexBuffer.h
@@ -24,33 +24,38 @@
class GrGpuGL;
class GrGLIndexBuffer : public GrIndexBuffer {
-protected:
- GrGLIndexBuffer(GrGLuint id,
- GrGpuGL* gl,
- size_t sizeInBytes,
- bool dynamic);
+
public:
- virtual ~GrGLIndexBuffer();
+
+ virtual ~GrGLIndexBuffer() { this->release(); }
GrGLuint bufferID() const;
// overrides of GrIndexBuffer
- virtual void abandon();
virtual void* lock();
virtual void* lockPtr() const;
virtual void unlock();
virtual bool isLocked() const;
virtual bool updateData(const void* src, size_t srcSizeInBytes);
- virtual bool updateSubData(const void* src,
- size_t srcSizeInBytes,
+ virtual bool updateSubData(const void* src,
+ size_t srcSizeInBytes,
size_t offset);
+protected:
+ GrGLIndexBuffer(GrGpuGL* gpu,
+ GrGLuint id,
+ size_t sizeInBytes,
+ bool dynamic);
+
+ // overrides of GrResource
+ virtual void onAbandon();
+ virtual void onRelease();
+
private:
void bind() const;
-
- GrGpuGL* fGL;
+
GrGLuint fBufferID;
void* fLockPtr;
-
+
friend class GrGpuGL;
typedef GrIndexBuffer INHERITED;
diff --git a/gpu/include/GrGLTexture.h b/gpu/include/GrGLTexture.h
index 1747b6d674..0624f405cc 100644
--- a/gpu/include/GrGLTexture.h
+++ b/gpu/include/GrGLTexture.h
@@ -29,6 +29,7 @@ class GrGLTexture;
* A ref counted tex id that deletes the texture in its destructor.
*/
class GrGLTexID : public GrRefCnt {
+
public:
GrGLTexID(GrGLuint texID) : fTexID(texID) {}
@@ -46,20 +47,18 @@ private:
};
class GrGLRenderTarget : public GrRenderTarget {
+
public:
- virtual ~GrGLRenderTarget();
-
+ virtual ~GrGLRenderTarget() { this->release(); }
+
bool resolveable() const { return fRTFBOID != fTexFBOID; }
bool needsResolve() const { return fNeedsResolve; }
void setDirty(bool dirty) { fNeedsResolve = resolveable() && dirty; }
-
+
GrGLuint renderFBOID() const { return fRTFBOID; }
GrGLuint textureFBOID() const { return fTexFBOID; }
- void abandon();
-
protected:
-
struct GLRenderTargetIDs {
GrGLuint fRTFBOID;
GrGLuint fTexFBOID;
@@ -67,34 +66,38 @@ protected:
GrGLuint fMSColorRenderbufferID;
bool fOwnIDs;
};
-
- GrGLRenderTarget(const GLRenderTargetIDs& ids,
+
+ GrGLRenderTarget(GrGpuGL* gpu,
+ const GLRenderTargetIDs& ids,
GrGLTexID* texID,
GrGLuint stencilBits,
const GrGLIRect& fViewport,
- GrGLTexture* texture,
- GrGpuGL* gl);
-
+ GrGLTexture* texture);
+
void setViewport(const GrGLIRect& rect) { fViewport = rect; }
const GrGLIRect& getViewport() const { return fViewport; }
+
+ // overloads of GrResource
+ virtual void onAbandon();
+ virtual void onRelease();
+
private:
- GrGpuGL* fGL;
GrGLuint fRTFBOID;
GrGLuint fTexFBOID;
GrGLuint fStencilRenderbufferID;
GrGLuint fMSColorRenderbufferID;
-
+
// Should this object delete IDs when it is destroyed or does someone
// else own them.
bool fOwnIDs;
-
+
// If there separate Texture and RenderTarget FBO IDs then the rendertarget
// must be resolved to the texture FBO before it is used as a texture.
bool fNeedsResolve;
-
- // when we switch to this rendertarget we want to set the viewport to
+
+ // when we switch to this rendertarget we want to set the viewport to
// only render to to content area (as opposed to the whole allocation) and
- // we want the rendering to be at top left (GL has origin in bottom left)
+ // we want the rendering to be at top left (GL has origin in bottom left)
GrGLIRect fViewport;
// non-NULL if this RT was created by Gr with an associated GrGLTexture.
@@ -102,48 +105,27 @@ private:
friend class GrGpuGL;
friend class GrGLTexture;
-
+
typedef GrRenderTarget INHERITED;
};
class GrGLTexture : public GrTexture {
+
public:
enum Orientation {
kBottomUp_Orientation,
kTopDown_Orientation,
};
-
+
struct TexParams {
GrGLenum fFilter;
GrGLenum fWrapS;
GrGLenum fWrapT;
};
-protected:
- struct GLTextureDesc {
- uint32_t fContentWidth;
- uint32_t fContentHeight;
- uint32_t fAllocWidth;
- uint32_t fAllocHeight;
- PixelConfig fFormat;
- GrGLuint fTextureID;
- GrGLenum fUploadFormat;
- GrGLenum fUploadByteCount;
- GrGLenum fUploadType;
- GrGLuint fStencilBits;
- Orientation fOrientation;
- };
- typedef GrGLRenderTarget::GLRenderTargetIDs GLRenderTargetIDs;
- GrGLTexture(const GLTextureDesc& textureDesc,
- const GLRenderTargetIDs& rtIDs,
- const TexParams& initialTexParams,
- GrGpuGL* gl);
+ virtual ~GrGLTexture() { this->release(); }
-public:
- virtual ~GrGLTexture();
-
// overloads of GrTexture
- virtual void abandon();
virtual GrRenderTarget* asRenderTarget();
virtual void releaseRenderTarget();
virtual void uploadTextureData(uint32_t x,
@@ -189,12 +171,37 @@ public:
// in the top-left corner of the image. OpenGL, however,
// has the origin in the lower-left corner. For content that
// is loaded by Ganesh we just push the content "upside down"
- // (by GL's understanding of the world ) in glTex*Image and the
- // addressing just works out. However, content generated by GL
- // (FBO or externally imported texture) will be updside down
+ // (by GL's understanding of the world ) in glTex*Image and the
+ // addressing just works out. However, content generated by GL
+ // (FBO or externally imported texture) will be updside down
// and it is up to the GrGpuGL derivative to handle y-mirroing.
Orientation orientation() const { return fOrientation; }
+protected:
+
+ struct GLTextureDesc {
+ uint32_t fContentWidth;
+ uint32_t fContentHeight;
+ uint32_t fAllocWidth;
+ uint32_t fAllocHeight;
+ PixelConfig fFormat;
+ GrGLuint fTextureID;
+ GrGLenum fUploadFormat;
+ GrGLenum fUploadByteCount;
+ GrGLenum fUploadType;
+ GrGLuint fStencilBits;
+ Orientation fOrientation;
+ };
+ typedef GrGLRenderTarget::GLRenderTargetIDs GLRenderTargetIDs;
+ GrGLTexture(GrGpuGL* gpu,
+ const GLTextureDesc& textureDesc,
+ const GLRenderTargetIDs& rtIDs,
+ const TexParams& initialTexParams);
+
+ // overloads of GrResource
+ virtual void onAbandon();
+ virtual void onRelease();
+
private:
TexParams fTexParams;
GrGLTexID* fTexIDObj;
diff --git a/gpu/include/GrGLVertexBuffer.h b/gpu/include/GrGLVertexBuffer.h
index c4f62a0e4a..183cabaa65 100644
--- a/gpu/include/GrGLVertexBuffer.h
+++ b/gpu/include/GrGLVertexBuffer.h
@@ -24,31 +24,33 @@
class GrGpuGL;
class GrGLVertexBuffer : public GrVertexBuffer {
-protected:
- GrGLVertexBuffer(GrGLuint id,
- GrGpuGL* gl,
- size_t sizeInBytes,
- bool dynamic);
public:
- virtual ~GrGLVertexBuffer();
-
+ virtual ~GrGLVertexBuffer() { this->release(); }
// overrides of GrVertexBuffer
- virtual void abandon();
virtual void* lock();
virtual void* lockPtr() const;
virtual void unlock();
virtual bool isLocked() const;
virtual bool updateData(const void* src, size_t srcSizeInBytes);
- virtual bool updateSubData(const void* src,
- size_t srcSizeInBytes,
+ virtual bool updateSubData(const void* src,
+ size_t srcSizeInBytes,
size_t offset);
GrGLuint bufferID() const;
+protected:
+ GrGLVertexBuffer(GrGpuGL* gpu,
+ GrGLuint id,
+ size_t sizeInBytes,
+ bool dynamic);
+
+ // overrides of GrResource
+ virtual void onAbandon();
+ virtual void onRelease();
+
private:
void bind() const;
-
- GrGpuGL* fGL;
+
GrGLuint fBufferID;
void* fLockPtr;
diff --git a/gpu/include/GrGeometryBuffer.h b/gpu/include/GrGeometryBuffer.h
index 1447e73185..98f58bd04f 100644
--- a/gpu/include/GrGeometryBuffer.h
+++ b/gpu/include/GrGeometryBuffer.h
@@ -1,12 +1,12 @@
/*
Copyright 2011 Google Inc.
-
+
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
-
+
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,47 +17,40 @@
#ifndef GrGeometryBuffer_DEFINED
#define GrGeometryBuffer_DEFINED
-#include "GrRefCnt.h"
+#include "GrResource.h"
+
+class GrGpu;
/**
* Parent class for vertex and index buffers
*/
-class GrGeometryBuffer : public GrRefCnt {
+class GrGeometryBuffer : public GrResource {
public:
- virtual ~GrGeometryBuffer() {}
-
/**
* Retrieves the size of the buffer
*
* @return the size of the buffer in bytes
*/
size_t size() const { return fSizeInBytes; }
-
+
/**
*Retrieves whether the buffer was created with the dynamic flag
*
* @return true if the buffer was created with the dynamic flag
*/
bool dynamic() const { return fDynamic; }
-
- /**
- * Indicates that GPU context in which this veretx buffer was created is
- * destroyed and that Ganesh should not attempt to free the buffer in the
- * underlying API.
- */
- virtual void abandon() = 0;
-
+
/**
* Locks the buffer to be written by the CPU.
- *
+ *
* The previous content of the buffer is invalidated. It is an error
* to draw from the buffer while it is locked. It is an error to call lock
* on an already locked buffer.
- *
+ *
* @return a pointer to the data or NULL if the lock fails.
*/
virtual void* lock() = 0;
-
+
/**
* Returns the same ptr that lock() returned at time of lock or NULL if the
* is not locked.
@@ -65,52 +58,53 @@ public:
* @return ptr to locked buffer data or undefined if buffer is not locked.
*/
virtual void* lockPtr() const = 0;
-
- /**
- * Unlocks the buffer.
- *
+
+ /**
+ * Unlocks the buffer.
+ *
* The pointer returned by the previous lock call will no longer be valid.
*/
virtual void unlock() = 0;
-
- /**
+
+ /**
Queries whether the buffer has been locked.
-
+
@return true if the buffer is locked, false otherwise.
*/
virtual bool isLocked() const = 0;
-
+
/**
- * Updates the buffer data.
- *
- * The size of the buffer will be preserved. The src data will be
+ * Updates the buffer data.
+ *
+ * The size of the buffer will be preserved. The src data will be
* placed at the begining of the buffer and any remaining contents will
* be undefined.
- *
+ *
* @return returns true if the update succeeds, false otherwise.
*/
virtual bool updateData(const void* src, size_t srcSizeInBytes) = 0;
-
+
/**
- * Updates a portion of the buffer data.
- *
+ * Updates a portion of the buffer data.
+ *
* The contents of the buffer outside the update region are preserved.
- *
+ *
* @return returns true if the update succeeds, false otherwise.
*/
- virtual bool updateSubData(const void* src,
- size_t srcSizeInBytes,
+ virtual bool updateSubData(const void* src,
+ size_t srcSizeInBytes,
size_t offset) = 0;
protected:
- GrGeometryBuffer(size_t sizeInBytes, bool dynamic) :
- fSizeInBytes(sizeInBytes),
- fDynamic(dynamic) {}
+ GrGeometryBuffer(GrGpu* gpu, size_t sizeInBytes, bool dynamic)
+ : INHERITED(gpu)
+ , fSizeInBytes(sizeInBytes)
+ , fDynamic(dynamic) {}
private:
size_t fSizeInBytes;
bool fDynamic;
- typedef GrRefCnt INHERITED;
+ typedef GrResource INHERITED;
};
#endif
diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h
index 7e12456d09..c4f5e4b7bc 100644
--- a/gpu/include/GrGpu.h
+++ b/gpu/include/GrGpu.h
@@ -25,6 +25,7 @@
class GrVertexBufferAllocPool;
class GrIndexBufferAllocPool;
+class GrResource;
class GrGpu : public GrDrawTarget {
@@ -158,7 +159,7 @@ public:
* will be embedded in a power of two texture. The extra width and height
* is filled as though srcData were rendered clamped into the texture.
*
- * If kRenderTarget_TextureFlag is specified the GrRenderTarget is
+ * If kRenderTarget_TextureFlag is specified the GrRenderTarget is
* accessible via GrTexture::asRenderTarget(). The texture will hold a ref
* on the render target until its releaseRenderTarget() is called or it is
* destroyed.
@@ -353,11 +354,34 @@ public:
bool readPixels(int left, int top, int width, int height,
GrTexture::PixelConfig, void* buffer);
-
const Stats& getStats() const;
void resetStats();
void printStats() const;
+ /**
+ * Called to tell Gpu object that all GrResources have been lost and should
+ * be abandoned.
+ */
+ void abandonResources();
+
+ /**
+ * Called to tell Gpu object to release all GrResources.
+ */
+ void releaseResources();
+
+ /**
+ * Add resource to list of resources. Should only be called by GrResource.
+ * @param resource the resource to add.
+ */
+ void insertResource(GrResource* resource);
+
+ /**
+ * Remove resource from list of resources. Should only be called by
+ * GrResource.
+ * @param resource the resource to remove.
+ */
+ void removeResource(GrResource* resource);
+
protected:
enum PrivateStateBits {
kFirstBit = (kLastPublicStateBit << 1),
@@ -535,6 +559,8 @@ private:
bool fVertexPoolInUse;
bool fIndexPoolInUse;
+ GrResource* fResourceHead;
+
// used to save and restore state when the GrGpu needs
// to make its geometry pools available internally
class AutoInternalDrawGeomRestore {
diff --git a/gpu/include/GrIndexBuffer.h b/gpu/include/GrIndexBuffer.h
index 09d1977bfc..366640e821 100644
--- a/gpu/include/GrIndexBuffer.h
+++ b/gpu/include/GrIndexBuffer.h
@@ -29,8 +29,8 @@ public:
*/
int maxQuads() const { return size() / (sizeof(uint16_t) * 6); }
protected:
- GrIndexBuffer(size_t sizeInBytes, bool dynamic) :
- INHERITED(sizeInBytes, dynamic) {}
+ GrIndexBuffer(GrGpu* gpu, size_t sizeInBytes, bool dynamic)
+ : INHERITED(gpu, sizeInBytes, dynamic) {}
private:
typedef GrGeometryBuffer INHERITED;
};
diff --git a/gpu/include/GrRefCnt.h b/gpu/include/GrRefCnt.h
index c462b2c4b3..9c9fed1b92 100644
--- a/gpu/include/GrRefCnt.h
+++ b/gpu/include/GrRefCnt.h
@@ -104,6 +104,14 @@ static inline void GrSafeAssign(T*& dst, T* src) {
dst = src;
}
+template<typename T>
+static inline void GrSafeSetNull(T*& obj) {
+ if (NULL != obj) {
+ obj->unref();
+ obj = NULL;
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
class GrAutoRef : GrNoncopyable {
diff --git a/gpu/include/GrResource.h b/gpu/include/GrResource.h
new file mode 100644
index 0000000000..8cc4d5714b
--- /dev/null
+++ b/gpu/include/GrResource.h
@@ -0,0 +1,77 @@
+/*
+ Copyright 2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#ifndef GrResource_DEFINED
+#define GrResource_DEFINED
+
+#include "GrRefCnt.h"
+
+class GrGpu;
+
+class GrResource : public GrRefCnt {
+public:
+ explicit GrResource(GrGpu* gpu);
+
+ virtual ~GrResource() {
+ // subclass should have released this.
+ GrAssert(!isValid());
+ }
+
+ /**
+ * Frees the resource in the underlying 3D API. It must be safe to call this
+ * when the resource has been previously abandoned.
+ */
+ void release();
+
+ /**
+ * Removes references to objects in the underlying 3D API without freeing
+ * them. Used when the API context has been torn down before the GrContext.
+ */
+ void abandon();
+
+ /**
+ * Tests whether a resource has been abandoned or released. All resources
+ * will be in this state after their creating GrContext is destroyed or has
+ * contextLost called. It's up to the client to test isValid() before
+ * attempting to use a resource if it holds refs on resources across
+ * ~GrContext, freeResources with the force flag, or contextLost.
+ *
+ * @return true if the resource has been released or abandoned,
+ * false otherwise.
+ */
+ bool isValid() const { return NULL != fGpu; }
+
+protected:
+
+ virtual void onRelease() = 0;
+ virtual void onAbandon() = 0;
+
+ GrGpu* getGpu() const { return fGpu; }
+
+private:
+ GrResource(); // unimpl
+
+ GrGpu* fGpu; // not reffed. This can outlive the GrGpu.
+
+ friend class GrGpu; // GrGpu manages list of resources.
+
+ GrResource* fNext; // dl-list of resources per-GrGpu
+ GrResource* fPrevious;
+
+ typedef GrRefCnt INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrTextStrike.h b/gpu/include/GrTextStrike.h
index 610222cb5f..2bdcc90ebe 100644
--- a/gpu/include/GrTextStrike.h
+++ b/gpu/include/GrTextStrike.h
@@ -85,7 +85,6 @@ public:
inline GrTextStrike* getStrike(GrFontScaler*);
void freeAll();
- void abandonAll();
void purgeExceptFor(GrTextStrike*);
diff --git a/gpu/include/GrTexture.h b/gpu/include/GrTexture.h
index 0a65ff75ce..d1853e3837 100644
--- a/gpu/include/GrTexture.h
+++ b/gpu/include/GrTexture.h
@@ -20,6 +20,7 @@
#include "GrRefCnt.h"
#include "GrClip.h"
+#include "GrResource.h"
class GrTexture;
@@ -30,7 +31,7 @@ class GrTexture;
* Additionally, GrContext provides methods for creating GrRenderTargets
* that wrap externally created render targets.
*/
-class GrRenderTarget : public GrRefCnt {
+class GrRenderTarget : public GrResource {
public:
/**
* @return the width of the rendertarget
@@ -52,14 +53,17 @@ public:
GrTexture* asTexture() {return fTexture;}
protected:
- GrRenderTarget(GrTexture* texture,
+ GrRenderTarget(GrGpu* gpu,
+ GrTexture* texture,
int width,
int height,
int stencilBits)
- : fTexture(texture),
- fWidth(width),
- fHeight(height),
- fStencilBits(stencilBits) {}
+ : INHERITED(gpu)
+ , fTexture(texture)
+ , fWidth(width)
+ , fHeight(height)
+ , fStencilBits(stencilBits)
+ {}
GrTexture* fTexture;
@@ -73,10 +77,10 @@ private:
friend class GrGpu;
GrClip fLastStencilClip;
- typedef GrRefCnt INHERITED;
+ typedef GrResource INHERITED;
};
-class GrTexture : public GrRefCnt {
+class GrTexture : public GrResource {
public:
enum PixelConfig {
kUnknown_PixelConfig,
@@ -92,16 +96,19 @@ public:
static bool PixelConfigIsAlphaOnly(PixelConfig);
protected:
- GrTexture(int width,
+ GrTexture(GrGpu* gpu,
+ int width,
int height,
- PixelConfig config) :
- fWidth(width),
- fHeight(height),
- fConfig(config) {
- // only make sense if alloc size is pow2
- fShiftFixedX = 31 - Gr_clz(fWidth);
- fShiftFixedY = 31 - Gr_clz(fHeight);
- }
+ PixelConfig config)
+ : INHERITED(gpu)
+ , fWidth(width)
+ , fHeight(height)
+ , fConfig(config) {
+ // only make sense if alloc size is pow2
+ fShiftFixedX = 31 - Gr_clz(fWidth);
+ fShiftFixedY = 31 - Gr_clz(fHeight);
+ }
+
public:
virtual ~GrTexture();
@@ -111,6 +118,7 @@ public:
* @return the width in texels
*/
int width() const { return fWidth; }
+
/**
* Retrieves the height of the texture.
*
@@ -154,12 +162,6 @@ public:
uint32_t width,
uint32_t height,
const void* srcData) = 0;
- /**
- * Indicates that GPU context in which this texture was created is destroyed
- * and that Ganesh should not attempt to free the texture with the
- * underlying API.
- */
- virtual void abandon() = 0;
/**
* Retrieves the render target underlying this texture that can be passed to
@@ -172,7 +174,7 @@ public:
/**
* Removes the reference on the associated GrRenderTarget held by this
- * texture. Afterwards asRenderTarget() will return NULL. The
+ * texture. Afterwards asRenderTarget() will return NULL. The
* GrRenderTarget survives the release if another ref is held on it.
*/
virtual void releaseRenderTarget() = 0;
@@ -200,7 +202,7 @@ private:
int fShiftFixedY;
PixelConfig fConfig;
- typedef GrRefCnt INHERITED;
+ typedef GrResource INHERITED;
};
#endif
diff --git a/gpu/include/GrTextureCache.h b/gpu/include/GrTextureCache.h
index 68e1daab04..466dafa3e4 100644
--- a/gpu/include/GrTextureCache.h
+++ b/gpu/include/GrTextureCache.h
@@ -191,7 +191,7 @@ private:
class GrTextureCache {
public:
GrTextureCache(int maxCount, size_t maxBytes);
- ~GrTextureCache(); // uses kFreeTexture_DeleteMode
+ ~GrTextureCache();
/**
* Return the current texture cache limits.
@@ -250,11 +250,7 @@ public:
*/
void unlock(GrTextureEntry*);
- enum DeleteMode {
- kFreeTexture_DeleteMode,
- kAbandonTexture_DeleteMode
- };
- void deleteAll(DeleteMode);
+ void removeAll();
#if GR_DEBUG
void validate() const;
diff --git a/gpu/include/GrVertexBuffer.h b/gpu/include/GrVertexBuffer.h
index 3792c15b01..34abe2ce11 100644
--- a/gpu/include/GrVertexBuffer.h
+++ b/gpu/include/GrVertexBuffer.h
@@ -22,8 +22,8 @@
class GrVertexBuffer : public GrGeometryBuffer {
protected:
- GrVertexBuffer(size_t sizeInBytes, bool dynamic) :
- INHERITED(sizeInBytes, dynamic) {}
+ GrVertexBuffer(GrGpu* gpu, size_t sizeInBytes, bool dynamic)
+ : INHERITED(gpu, sizeInBytes, dynamic) {}
private:
typedef GrGeometryBuffer INHERITED;
};
diff --git a/gpu/src/GrAtlas.cpp b/gpu/src/GrAtlas.cpp
index ab99d9a280..a37df9c89a 100644
--- a/gpu/src/GrAtlas.cpp
+++ b/gpu/src/GrAtlas.cpp
@@ -203,16 +203,4 @@ void GrAtlasMgr::freePlot(int x, int y) {
fPlotMgr->freePlot(x, y);
}
-void GrAtlasMgr::abandonAll() {
-#if 0
- GrAtlas** curr = fList.begin();
- GrAtlas** stop = fList.end();
- for (; curr < stop; curr++) {
- (*curr)->texture()->abandon();
- delete *curr;
- }
- fList.reset();
-#endif
-}
-
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index f6009f55ae..d093d7c4c1 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -57,6 +57,7 @@ GrContext* GrContext::CreateGLShaderContext() {
}
GrContext::~GrContext() {
+ this->flush();
fGpu->unref();
delete fTextureCache;
delete fFontCache;
@@ -66,9 +67,31 @@ GrContext::~GrContext() {
GrSafeUnref(fCustomPathRenderer);
}
-void GrContext::abandonAllTextures() {
- fTextureCache->deleteAll(GrTextureCache::kAbandonTexture_DeleteMode);
- fFontCache->abandonAll();
+void GrContext::contextLost() {
+ delete fDrawBuffer;
+ fDrawBuffer = NULL;
+ delete fDrawBufferVBAllocPool;
+ fDrawBufferVBAllocPool = NULL;
+ delete fDrawBufferIBAllocPool;
+ fDrawBufferIBAllocPool = NULL;
+
+ fTextureCache->removeAll();
+ fFontCache->freeAll();
+ fGpu->markContextDirty();
+
+ fGpu->abandonResources();
+
+ this->setupDrawBuffer();
+}
+
+void GrContext::resetContext() {
+ fGpu->markContextDirty();
+}
+
+void GrContext::freeGpuResources() {
+ this->flush();
+ fTextureCache->removeAll();
+ fFontCache->freeAll();
}
GrTextureEntry* GrContext::findAndLockTexture(GrTextureKey* key,
@@ -688,12 +711,8 @@ GrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint,
////////////////////////////////////////////////////////////////////////////////
-void GrContext::resetContext() {
- fGpu->markContextDirty();
-}
-
void GrContext::setRenderTarget(GrRenderTarget* target) {
- flush(false);
+ this->flush(false);
fGpu->setRenderTarget(target);
}
@@ -745,7 +764,7 @@ GrContext::GrContext(GrGpu* gpu) :
fGpu = gpu;
fGpu->ref();
-
+
fCustomPathRenderer = GrPathRenderer::CreatePathRenderer();
fGpu->setClipPathRenderer(fCustomPathRenderer);
@@ -755,22 +774,31 @@ GrContext::GrContext(GrGpu* gpu) :
fLastDrawCategory = kUnbuffered_DrawCategory;
+ fDrawBuffer = NULL;
+ fDrawBufferVBAllocPool = NULL;
+ fDrawBufferIBAllocPool = NULL;
+
+ this->setupDrawBuffer();
+}
+
+void GrContext::setupDrawBuffer() {
+
+ GrAssert(NULL == fDrawBuffer);
+ GrAssert(NULL == fDrawBufferVBAllocPool);
+ GrAssert(NULL == fDrawBufferIBAllocPool);
+
#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT
fDrawBufferVBAllocPool =
- new GrVertexBufferAllocPool(gpu, false,
+ new GrVertexBufferAllocPool(fGpu, false,
DRAW_BUFFER_VBPOOL_BUFFER_SIZE,
DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS);
fDrawBufferIBAllocPool =
- new GrIndexBufferAllocPool(gpu, false,
+ new GrIndexBufferAllocPool(fGpu, false,
DRAW_BUFFER_IBPOOL_BUFFER_SIZE,
DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS);
fDrawBuffer = new GrInOrderDrawBuffer(fDrawBufferVBAllocPool,
fDrawBufferIBAllocPool);
-#else
- fDrawBuffer = NULL;
- fDrawBufferVBAllocPool = NULL;
- fDrawBufferIBAllocPool = NULL;
#endif
#if BATCH_RECT_TO_RECT
@@ -818,7 +846,7 @@ const GrIndexBuffer* GrContext::getQuadIndexBuffer() const {
GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
GrPathIter* path,
GrPathFill fill) {
- if (NULL != fCustomPathRenderer &&
+ if (NULL != fCustomPathRenderer &&
fCustomPathRenderer->canDrawPath(target, path, fill)) {
return fCustomPathRenderer;
} else {
diff --git a/gpu/src/GrGLIndexBuffer.cpp b/gpu/src/GrGLIndexBuffer.cpp
index 9d73419376..4fb1e99ce4 100644
--- a/gpu/src/GrGLIndexBuffer.cpp
+++ b/gpu/src/GrGLIndexBuffer.cpp
@@ -18,42 +18,46 @@
#include "GrGLIndexBuffer.h"
#include "GrGpuGL.h"
-GrGLIndexBuffer::GrGLIndexBuffer(GrGLuint id, GrGpuGL* gl, size_t sizeInBytes,
- bool dynamic) :
- INHERITED(sizeInBytes, dynamic),
- fGL(gl),
- fBufferID(id),
- fLockPtr(NULL) {
+#define GPUGL static_cast<GrGpuGL*>(getGpu())
+
+GrGLIndexBuffer::GrGLIndexBuffer(GrGpuGL* gpu,
+ GrGLuint id,
+ size_t sizeInBytes,
+ bool dynamic)
+ : INHERITED(gpu, sizeInBytes, dynamic)
+ , fBufferID(id)
+ , fLockPtr(NULL) {
+
}
-GrGLIndexBuffer::~GrGLIndexBuffer() {
+void GrGLIndexBuffer::onRelease() {
// make sure we've not been abandoned
if (fBufferID) {
- fGL->notifyIndexBufferDelete(this);
+ GPUGL->notifyIndexBufferDelete(this);
GR_GL(DeleteBuffers(1, &fBufferID));
+ fBufferID = 0;
}
}
+void GrGLIndexBuffer::onAbandon() {
+ fBufferID = 0;
+ fLockPtr = NULL;
+}
+
void GrGLIndexBuffer::bind() const {
GR_GL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, fBufferID));
- fGL->notifyIndexBufferBind(this);
+ GPUGL->notifyIndexBufferBind(this);
}
GrGLuint GrGLIndexBuffer::bufferID() const {
return fBufferID;
}
-void GrGLIndexBuffer::abandon() {
- fBufferID = 0;
- fGL = NULL;
- fLockPtr = NULL;
-}
-
void* GrGLIndexBuffer::lock() {
GrAssert(fBufferID);
GrAssert(!isLocked());
- if (fGL->supportsBufferLocking()) {
- bind();
+ if (GPUGL->supportsBufferLocking()) {
+ this->bind();
// Let driver know it can discard the old data
GR_GL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER, size(), NULL,
dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
@@ -71,18 +75,17 @@ void* GrGLIndexBuffer::lockPtr() const {
void GrGLIndexBuffer::unlock() {
GrAssert(fBufferID);
GrAssert(isLocked());
- GrAssert(fGL->supportsBufferLocking());
+ GrAssert(GPUGL->supportsBufferLocking());
- bind();
+ this->bind();
GR_GL(UnmapBuffer(GR_GL_ELEMENT_ARRAY_BUFFER));
fLockPtr = NULL;
}
bool GrGLIndexBuffer::isLocked() const {
- GrAssert(fBufferID);
#if GR_DEBUG
- if (fGL->supportsBufferLocking()) {
- bind();
+ if (this->isValid() && GPUGL->supportsBufferLocking()) {
+ this->bind();
GrGLint mapped;
GR_GL(GetBufferParameteriv(GR_GL_ELEMENT_ARRAY_BUFFER,
GR_GL_BUFFER_MAPPED, &mapped));
@@ -98,7 +101,7 @@ bool GrGLIndexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
if (srcSizeInBytes > size()) {
return false;
}
- bind();
+ this->bind();
GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
if (size() == srcSizeInBytes) {
GR_GL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER, srcSizeInBytes, src, usage));
@@ -117,7 +120,7 @@ bool GrGLIndexBuffer::updateSubData(const void* src,
if (srcSizeInBytes + offset > size()) {
return false;
}
- bind();
+ this->bind();
GR_GL(BufferSubData(GR_GL_ELEMENT_ARRAY_BUFFER, offset, srcSizeInBytes, src));
return true;
}
diff --git a/gpu/src/GrGLTexture.cpp b/gpu/src/GrGLTexture.cpp
index ae36e4cfcc..bd157d26bb 100644
--- a/gpu/src/GrGLTexture.cpp
+++ b/gpu/src/GrGLTexture.cpp
@@ -18,16 +18,15 @@
#include "GrGLTexture.h"
#include "GrGpuGL.h"
-GrGLRenderTarget::GrGLRenderTarget(const GLRenderTargetIDs& ids,
+#define GPUGL static_cast<GrGpuGL*>(getGpu())
+
+GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
+ const GLRenderTargetIDs& ids,
GrGLTexID* texID,
GrGLuint stencilBits,
const GrGLIRect& viewport,
- GrGLTexture* texture,
- GrGpuGL* gl) : INHERITED(texture,
- viewport.fWidth,
- viewport.fHeight,
- stencilBits) {
- fGL = gl;
+ GrGLTexture* texture)
+ : INHERITED(gpu, texture, viewport.fWidth, viewport.fHeight, stencilBits) {
fRTFBOID = ids.fRTFBOID;
fTexFBOID = ids.fTexFBOID;
fStencilRenderbufferID = ids.fStencilRenderbufferID;
@@ -39,10 +38,10 @@ GrGLRenderTarget::GrGLRenderTarget(const GLRenderTargetIDs& ids,
GrSafeRef(fTexIDObj);
}
-GrGLRenderTarget::~GrGLRenderTarget() {
- fGL->notifyRenderTargetDelete(this);
+void GrGLRenderTarget::onRelease() {
if (fOwnIDs) {
if (fTexFBOID) {
+ GPUGL->notifyRenderTargetDelete(this);
GR_GL(DeleteFramebuffers(1, &fTexFBOID));
}
if (fRTFBOID && fRTFBOID != fTexFBOID) {
@@ -55,16 +54,22 @@ GrGLRenderTarget::~GrGLRenderTarget() {
GR_GL(DeleteRenderbuffers(1, &fMSColorRenderbufferID));
}
}
+ fRTFBOID = 0;
+ fTexFBOID = 0;
+ fStencilRenderbufferID = 0;
+ fMSColorRenderbufferID = 0;
GrSafeUnref(fTexIDObj);
+ fTexIDObj = NULL;
}
-void GrGLRenderTarget::abandon() {
+void GrGLRenderTarget::onAbandon() {
fRTFBOID = 0;
fTexFBOID = 0;
fStencilRenderbufferID = 0;
fMSColorRenderbufferID = 0;
if (NULL != fTexIDObj) {
fTexIDObj->abandon();
+ fTexIDObj = NULL;
}
}
@@ -92,13 +97,14 @@ const GrGLenum* GrGLTexture::WrapMode2GLWrap() {
};
-GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc,
+GrGLTexture::GrGLTexture(GrGpuGL* gpu,
+ const GLTextureDesc& textureDesc,
const GLRenderTargetIDs& rtIDs,
- const TexParams& initialTexParams,
- GrGpuGL* gl)
- : INHERITED(textureDesc.fContentWidth,
- textureDesc.fContentHeight,
- textureDesc.fFormat) {
+ const TexParams& initialTexParams)
+ : INHERITED(gpu,
+ textureDesc.fContentWidth,
+ textureDesc.fContentHeight,
+ textureDesc.fFormat) {
fTexParams = initialTexParams;
fTexIDObj = new GrGLTexID(textureDesc.fTextureID);
@@ -113,7 +119,6 @@ GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc,
fScaleY = GrIntToScalar(textureDesc.fContentHeight) /
textureDesc.fAllocHeight;
fRenderTarget = NULL;
- fGpuGL = gl;
GrAssert(0 != textureDesc.fTextureID);
@@ -125,27 +130,32 @@ GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc,
vp.fHeight = textureDesc.fContentHeight;
vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight;
- fRenderTarget = new GrGLRenderTarget(rtIDs, fTexIDObj,
+ fRenderTarget = new GrGLRenderTarget(gpu, rtIDs, fTexIDObj,
textureDesc.fStencilBits,
- vp, this, gl);
+ vp, this);
}
}
-GrGLTexture::~GrGLTexture() {
- fGpuGL->notifyTextureDelete(this);
- fTexIDObj->unref();
- GrSafeUnref(fRenderTarget);
+void GrGLTexture::onRelease() {
+ if (NULL != fTexIDObj) {
+ GPUGL->notifyTextureDelete(this);
+ fTexIDObj->unref();
+ fTexIDObj = NULL;
+ GrSafeUnref(fRenderTarget);
+ }
}
-void GrGLTexture::abandon() {
- fTexIDObj->abandon();
+void GrGLTexture::onAbandon() {
+ if (NULL != fTexIDObj) {
+ fTexIDObj->abandon();
+ }
if (NULL != fRenderTarget) {
fRenderTarget->abandon();
}
}
GrRenderTarget* GrGLTexture::asRenderTarget() {
- return (GrRenderTarget*)fRenderTarget;
+ return fRenderTarget;
}
void GrGLTexture::releaseRenderTarget() {
@@ -158,8 +168,8 @@ void GrGLTexture::uploadTextureData(uint32_t x,
uint32_t width,
uint32_t height,
const void* srcData) {
-
- fGpuGL->setSpareTextureUnit();
+
+ GPUGL->setSpareTextureUnit();
// glCompressedTexSubImage2D doesn't support any formats
// (at least without extensions)
@@ -170,7 +180,7 @@ void GrGLTexture::uploadTextureData(uint32_t x,
GrAssert(kTopDown_Orientation == fOrientation);
GR_GL(BindTexture(GR_GL_TEXTURE_2D, fTexIDObj->id()));
GR_GL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, fUploadByteCount));
- GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, x, y, width, height,
+ GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, x, y, width, height,
fUploadFormat, fUploadType, srcData));
}
diff --git a/gpu/src/GrGLVertexBuffer.cpp b/gpu/src/GrGLVertexBuffer.cpp
index f96f90ea5f..3fa1425d02 100644
--- a/gpu/src/GrGLVertexBuffer.cpp
+++ b/gpu/src/GrGLVertexBuffer.cpp
@@ -18,42 +18,45 @@
#include "GrGLVertexBuffer.h"
#include "GrGpuGL.h"
-GrGLVertexBuffer::GrGLVertexBuffer(GrGLuint id, GrGpuGL* gl, size_t sizeInBytes,
- bool dynamic) :
- INHERITED(sizeInBytes, dynamic),
- fGL(gl),
- fBufferID(id),
- fLockPtr(NULL) {
+#define GPUGL static_cast<GrGpuGL*>(getGpu())
+
+GrGLVertexBuffer::GrGLVertexBuffer(GrGpuGL* gpu,
+ GrGLuint id,
+ size_t sizeInBytes,
+ bool dynamic)
+ : INHERITED(gpu, sizeInBytes, dynamic)
+ , fBufferID(id)
+ , fLockPtr(NULL) {
}
-GrGLVertexBuffer::~GrGLVertexBuffer() {
+void GrGLVertexBuffer::onRelease() {
// make sure we've not been abandoned
if (fBufferID) {
- fGL->notifyVertexBufferDelete(this);
+ GPUGL->notifyVertexBufferDelete(this);
GR_GL(DeleteBuffers(1, &fBufferID));
+ fBufferID = 0;
}
}
+void GrGLVertexBuffer::onAbandon() {
+ fBufferID = 0;
+ fLockPtr = NULL;
+}
+
void GrGLVertexBuffer::bind() const {
GR_GL(BindBuffer(GR_GL_ARRAY_BUFFER, fBufferID));
- fGL->notifyVertexBufferBind(this);
+ GPUGL->notifyVertexBufferBind(this);
}
GrGLuint GrGLVertexBuffer::bufferID() const {
return fBufferID;
}
-void GrGLVertexBuffer::abandon() {
- fBufferID = 0;
- fGL = NULL;
- fLockPtr = NULL;
-}
-
void* GrGLVertexBuffer::lock() {
GrAssert(fBufferID);
GrAssert(!isLocked());
- if (fGL->supportsBufferLocking()) {
- bind();
+ if (GPUGL->supportsBufferLocking()) {
+ this->bind();
// Let driver know it can discard the old data
GR_GL(BufferData(GR_GL_ARRAY_BUFFER, size(), NULL,
dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
@@ -68,21 +71,22 @@ void* GrGLVertexBuffer::lockPtr() const {
}
void GrGLVertexBuffer::unlock() {
+
GrAssert(fBufferID);
GrAssert(isLocked());
- GrAssert(fGL->supportsBufferLocking());
+ GrAssert(GPUGL->supportsBufferLocking());
- bind();
+ this->bind();
GR_GL(UnmapBuffer(GR_GL_ARRAY_BUFFER));
fLockPtr = NULL;
}
bool GrGLVertexBuffer::isLocked() const {
- GrAssert(fBufferID);
+ GrAssert(!this->isValid() || fBufferID);
#if GR_DEBUG
- if (fGL->supportsBufferLocking()) {
+ if (this->isValid() && GPUGL->supportsBufferLocking()) {
GrGLint mapped;
- bind();
+ this->bind();
GR_GL(GetBufferParameteriv(GR_GL_ARRAY_BUFFER, GR_GL_BUFFER_MAPPED, &mapped));
GrAssert(!!mapped == !!fLockPtr);
}
@@ -96,7 +100,7 @@ bool GrGLVertexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
if (srcSizeInBytes > size()) {
return false;
}
- bind();
+ this->bind();
GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
if (size() == srcSizeInBytes) {
GR_GL(BufferData(GR_GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));
@@ -115,7 +119,7 @@ bool GrGLVertexBuffer::updateSubData(const void* src,
if (srcSizeInBytes + offset > size()) {
return false;
}
- bind();
+ this->bind();
GR_GL(BufferSubData(GR_GL_ARRAY_BUFFER, offset, srcSizeInBytes, src));
return true;
}
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 378b881637..31e4d99668 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -69,20 +69,22 @@ bool GrTexture::PixelConfigIsAlphaOnly(PixelConfig config) {
extern void gr_run_unittests();
-GrGpu::GrGpu() : f8bitPaletteSupport(false),
- fCurrPoolVertexBuffer(NULL),
- fCurrPoolStartVertex(0),
- fCurrPoolIndexBuffer(NULL),
- fCurrPoolStartIndex(0),
- fVertexPool(NULL),
- fIndexPool(NULL),
- fQuadIndexBuffer(NULL),
- fUnitSquareVertexBuffer(NULL),
- fDefaultPathRenderer(NULL),
- fClientPathRenderer(NULL),
- fContextIsDirty(true),
- fVertexPoolInUse(false),
- fIndexPoolInUse(false) {
+GrGpu::GrGpu()
+ : f8bitPaletteSupport(false)
+ , fCurrPoolVertexBuffer(NULL)
+ , fCurrPoolStartVertex(0)
+ , fCurrPoolIndexBuffer(NULL)
+ , fCurrPoolStartIndex(0)
+ , fVertexPool(NULL)
+ , fIndexPool(NULL)
+ , fQuadIndexBuffer(NULL)
+ , fUnitSquareVertexBuffer(NULL)
+ , fDefaultPathRenderer(NULL)
+ , fClientPathRenderer(NULL)
+ , fContextIsDirty(true)
+ , fVertexPoolInUse(false)
+ , fIndexPoolInUse(false)
+ , fResourceHead(NULL) {
#if GR_DEBUG
//gr_run_unittests();
#endif
@@ -90,17 +92,76 @@ GrGpu::GrGpu() : f8bitPaletteSupport(false),
}
GrGpu::~GrGpu() {
- GrSafeUnref(fQuadIndexBuffer);
- GrSafeUnref(fUnitSquareVertexBuffer);
+ releaseResources();
+}
+
+void GrGpu::abandonResources() {
+
+ while (NULL != fResourceHead) {
+ fResourceHead->abandon();
+ }
+
+ GrAssert(NULL == fQuadIndexBuffer || !fQuadIndexBuffer->isValid());
+ GrAssert(NULL == fUnitSquareVertexBuffer ||
+ !fUnitSquareVertexBuffer->isValid());
+ GrSafeSetNull(fQuadIndexBuffer);
+ GrSafeSetNull(fUnitSquareVertexBuffer);
delete fVertexPool;
+ fVertexPool = NULL;
delete fIndexPool;
- GrSafeUnref(fClientPathRenderer);
- GrSafeUnref(fDefaultPathRenderer);
+ fIndexPool = NULL;
}
-void GrGpu::resetContext() {
+void GrGpu::releaseResources() {
+
+ while (NULL != fResourceHead) {
+ fResourceHead->release();
+ }
+
+ GrAssert(NULL == fQuadIndexBuffer || !fQuadIndexBuffer->isValid());
+ GrAssert(NULL == fUnitSquareVertexBuffer ||
+ !fUnitSquareVertexBuffer->isValid());
+ GrSafeSetNull(fQuadIndexBuffer);
+ GrSafeSetNull(fUnitSquareVertexBuffer);
+ delete fVertexPool;
+ fVertexPool = NULL;
+ delete fIndexPool;
+ fIndexPool = NULL;
}
+void GrGpu::insertResource(GrResource* resource) {
+ GrAssert(NULL != resource);
+ GrAssert(this == resource->getGpu());
+ GrAssert(NULL == resource->fNext);
+ GrAssert(NULL == resource->fPrevious);
+
+ resource->fNext = fResourceHead;
+ if (NULL != fResourceHead) {
+ GrAssert(NULL == fResourceHead->fPrevious);
+ fResourceHead->fPrevious = resource;
+ }
+ fResourceHead = resource;
+}
+
+void GrGpu::removeResource(GrResource* resource) {
+ GrAssert(NULL != resource);
+ GrAssert(NULL != fResourceHead);
+
+ if (fResourceHead == resource) {
+ GrAssert(NULL == resource->fPrevious);
+ fResourceHead = resource->fNext;
+ } else {
+ GrAssert(NULL != fResourceHead);
+ resource->fPrevious->fNext = resource->fNext;
+ }
+ if (NULL != resource->fNext) {
+ resource->fNext->fPrevious = resource->fPrevious;
+ }
+ resource->fNext = NULL;
+ resource->fPrevious = NULL;
+}
+
+
void GrGpu::unimpl(const char msg[]) {
#if GR_DEBUG
GrPrintf("--- GrGpu unimplemented(\"%s\")\n", msg);
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index 6833a314e1..bb71255d63 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -232,7 +232,7 @@ GrGpuGL::GrGpuGL() {
fMSFBOType = kNone_MSFBO;
if (GR_GL_SUPPORT_ES) {
if (has_gl_extension("GL_CHROMIUM_framebuffer_multisample")) {
- // chrome's extension is equivalent to the EXT msaa
+ // chrome's extension is equivalent to the EXT msaa
// and fbo_blit extensions.
fMSFBOType = kDesktopEXT_MSFBO;
} else if (has_gl_extension("GL_APPLE_framebuffer_multisample")) {
@@ -552,7 +552,7 @@ GrRenderTarget* GrGpuGL::createPlatformRenderTargetHelper(
rtIDs.fRTFBOID = (GrGLuint)platformRenderTarget;
rtIDs.fTexFBOID = (GrGLuint)platformRenderTarget;
- return new GrGLRenderTarget(rtIDs, NULL, stencilBits, viewport, NULL, this);
+ return new GrGLRenderTarget(this, rtIDs, NULL, stencilBits, viewport, NULL);
}
GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiStateHelper() {
@@ -571,7 +571,7 @@ GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiStateHelper() {
rtIDs.fOwnIDs = false;
- return new GrGLRenderTarget(rtIDs, NULL, stencilBits, viewport, NULL, this);
+ return new GrGLRenderTarget(this, rtIDs, NULL, stencilBits, viewport, NULL);
}
///////////////////////////////////////////////////////////////////////////////
@@ -833,7 +833,7 @@ GrTexture* GrGpuGL::createTextureHelper(const TextureDesc& desc,
GR_GL(GenFramebuffers(1, &rtIDs.fTexFBOID));
GrAssert(rtIDs.fTexFBOID);
- // If we are using multisampling and we will create two FBOS We render
+ // If we are using multisampling and we will create two FBOS We render
// to one and then resolve to the texture bound to the other.
if (samples > 1 && kNone_MSFBO != fMSFBOType) {
GR_GL(GenFramebuffers(1, &rtIDs.fRTFBOID));
@@ -997,7 +997,7 @@ GrTexture* GrGpuGL::createTextureHelper(const TextureDesc& desc,
GrPrintf("--- new texture [%d] size=(%d %d) bpp=%d\n",
tex->fTextureID, width, height, tex->fUploadByteCount);
#endif
- GrGLTexture* tex = new GrGLTexture(glDesc, rtIDs, DEFAULT_PARAMS, this);
+ GrGLTexture* tex = new GrGLTexture(this, glDesc, rtIDs, DEFAULT_PARAMS);
if (0 != rtIDs.fTexFBOID) {
GrRenderTarget* rt = tex->asRenderTarget();
@@ -1032,7 +1032,7 @@ GrVertexBuffer* GrGpuGL::createVertexBufferHelper(uint32_t size, bool dynamic) {
fHWGeometryState.fVertexBuffer = NULL;
return NULL;
}
- GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(id, this,
+ GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, id,
size, dynamic);
fHWGeometryState.fVertexBuffer = vertexBuffer;
return vertexBuffer;
@@ -1055,7 +1055,7 @@ GrIndexBuffer* GrGpuGL::createIndexBufferHelper(uint32_t size, bool dynamic) {
fHWGeometryState.fIndexBuffer = NULL;
return NULL;
}
- GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(id, this,
+ GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, id,
size, dynamic);
fHWGeometryState.fIndexBuffer = indexBuffer;
return indexBuffer;
diff --git a/gpu/src/GrResource.cpp b/gpu/src/GrResource.cpp
new file mode 100644
index 0000000000..70e87d51c3
--- /dev/null
+++ b/gpu/src/GrResource.cpp
@@ -0,0 +1,41 @@
+/*
+ Copyright 2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#include "GrResource.h"
+#include "GrGpu.h"
+
+GrResource::GrResource(GrGpu* gpu) {
+ fGpu = gpu;
+ fNext = NULL;
+ fPrevious = NULL;
+ fGpu->insertResource(this);
+}
+
+void GrResource::release() {
+ if (NULL != fGpu) {
+ this->onRelease();
+ fGpu->removeResource(this);
+ fGpu = NULL;
+ }
+}
+
+void GrResource::abandon() {
+ if (NULL != fGpu) {
+ this->onAbandon();
+ fGpu->removeResource(this);
+ fGpu = NULL;
+ }
+}
diff --git a/gpu/src/GrTextStrike.cpp b/gpu/src/GrTextStrike.cpp
index 6cdb61cdb5..a245997d20 100644
--- a/gpu/src/GrTextStrike.cpp
+++ b/gpu/src/GrTextStrike.cpp
@@ -58,19 +58,12 @@ GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler,
return strike;
}
-void GrFontCache::abandonAll() {
- fCache.deleteAll();
- if (fAtlasMgr) {
- fAtlasMgr->abandonAll();
- delete fAtlasMgr;
- fAtlasMgr = NULL;
- }
-}
-
void GrFontCache::freeAll() {
fCache.deleteAll();
delete fAtlasMgr;
fAtlasMgr = NULL;
+ fHead = NULL;
+ fTail = NULL;
}
void GrFontCache::purgeExceptFor(GrTextStrike* preserveStrike) {
diff --git a/gpu/src/GrTextureCache.cpp b/gpu/src/GrTextureCache.cpp
index fe3ff689a4..c3a61ac2e7 100644
--- a/gpu/src/GrTextureCache.cpp
+++ b/gpu/src/GrTextureCache.cpp
@@ -55,7 +55,7 @@ GrTextureCache::GrTextureCache(int maxCount, size_t maxBytes) :
GrTextureCache::~GrTextureCache() {
GrAutoTextureCacheValidate atcv(this);
- this->deleteAll(kFreeTexture_DeleteMode);
+ this->removeAll();
}
void GrTextureCache::getLimits(int* maxTextures, size_t* maxTextureBytes) const{
@@ -237,7 +237,7 @@ void GrTextureCache::purgeAsNeeded() {
}
}
-void GrTextureCache::deleteAll(DeleteMode mode) {
+void GrTextureCache::removeAll() {
GrAssert(!fClientDetachedCount);
GrAssert(!fClientDetachedBytes);
@@ -246,9 +246,6 @@ void GrTextureCache::deleteAll(DeleteMode mode) {
GrAssert(!entry->isLocked());
GrTextureEntry* next = entry->fNext;
- if (kAbandonTexture_DeleteMode == mode) {
- entry->texture()->abandon();
- }
delete entry;
entry = next;
}