Make GrTextureCache into a generic GrResource cache. Also some GrContext texture interface cleanup.
http://codereview.appspot.com/4815055/
git-svn-id: http://skia.googlecode.com/svn/trunk@1965 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index 0f69e0b..c7a87da 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -18,16 +18,18 @@
#define GrContext_DEFINED
#include "GrClip.h"
-#include "GrTextureCache.h"
#include "GrPaint.h"
#include "GrPathRenderer.h"
class GrFontCache;
class GrGpu;
struct GrGpuStats;
-class GrVertexBufferAllocPool;
class GrIndexBufferAllocPool;
class GrInOrderDrawBuffer;
+class GrResourceEntry;
+class GrResourceCache;
+class GrVertexBufferAllocPool;
+
class GR_API GrContext : public GrRefCnt {
public:
@@ -82,54 +84,92 @@
// Textures
/**
- * Search for an entry with the same Key. If found, "lock" it and return it.
- * If not found, return null.
+ * Token that refers to an entry in the texture cache. Returned by
+ * functions that lock textures. Passed to unlockTexture.
*/
- GrTextureEntry* findAndLockTexture(GrTextureKey*,
- const GrSamplerState&);
+ class TextureCacheEntry {
+ public:
+ TextureCacheEntry() : fEntry(NULL) {}
+ TextureCacheEntry(const TextureCacheEntry& e) : fEntry(e.fEntry) {}
+ TextureCacheEntry& operator= (const TextureCacheEntry& e) {
+ fEntry = e.fEntry;
+ return *this;
+ }
+ GrTexture* texture() const;
+ void reset() { fEntry = NULL; }
+ private:
+ explicit TextureCacheEntry(GrResourceEntry* entry) { fEntry = entry; }
+ void set(GrResourceEntry* entry) { fEntry = entry; }
+ GrResourceEntry* cacheEntry() { return fEntry; }
+ GrResourceEntry* fEntry;
+ friend class GrContext;
+ };
+ /**
+ * Key generated by client. Should be a unique key on the texture data.
+ * Does not need to consider that width and height of the texture. Two
+ * textures with the same TextureKey but different bounds will not collide.
+ */
+ typedef uint64_t TextureKey;
+
+ /**
+ * Search for an entry based on key and dimensions. If found, "lock" it and
+ * return it. The entry's texture() function will return NULL if not found.
+ * Must call be balanced with an unlockTexture() call.
+ */
+ TextureCacheEntry findAndLockTexture(TextureKey key,
+ int width,
+ int height,
+ const GrSamplerState&);
/**
* Create a new entry, based on the specified key and texture, and return
- * its "locked" entry.
- *
- * Ownership of the texture is transferred to the Entry, which will unref()
- * it when we are purged or deleted.
+ * its "locked" entry. Must call be balanced with an unlockTexture() call.
*/
- GrTextureEntry* createAndLockTexture(GrTextureKey* key,
- const GrSamplerState&,
- const GrTextureDesc&,
- void* srcData, size_t rowBytes);
+ TextureCacheEntry createAndLockTexture(TextureKey key,
+ const GrSamplerState&,
+ const GrTextureDesc&,
+ void* srcData, size_t rowBytes);
+
+ /**
+ * Enum that determines how closely a returned scratch texture must match
+ * a provided GrTextureDesc.
+ */
+ enum ScratchTexMatch {
+ /**
+ * Finds a texture that exactly matches the descriptor.
+ */
+ kExact_ScratchTexMatch,
+ /**
+ * Finds a texture that approximately matches the descriptor. Will be
+ * at least as large in width and height as desc specifies. If desc
+ * specifies that texture is a render target then result will be a
+ * render target. If desc specifies a render target and doesn't set the
+ * no stencil flag then result will have a stencil. Format and aa level
+ * will always match.
+ */
+ kApprox_ScratchTexMatch
+ };
/**
* Returns a texture matching the desc. It's contents are unknown. Subsequent
* requests with the same descriptor are not guaranteed to return the same
* texture. The same texture is guaranteed not be returned again until it is
- * unlocked.
+ * unlocked. Must call be balanced with an unlockTexture() call.
*
* Textures created by createAndLockTexture() hide the complications of
* tiling non-power-of-two textures on APIs that don't support this (e.g.
- * unextended GLES2). Tiling a npot texture created by lockKeylessTexture on
+ * unextended GLES2). Tiling a npot texture created by lockScratchTexture on
* such an API will create gaps in the tiling pattern. This includes clamp
* mode. (This may be addressed in a future update.)
*/
- GrTextureEntry* lockKeylessTexture(const GrTextureDesc& desc);
-
- /**
- * Finds a texture that approximately matches the descriptor. Will be
- * at least as large in width and height as desc specifies. If desc
- * specifies that texture is a render target then result will be a
- * render target. If desc specifies a render target and doesn't set the
- * no stencil flag then result will have a stencil. Format and aa level
- * will always match.
- */
- GrTextureEntry* findApproximateKeylessTexture(const GrTextureDesc& desc);
+ TextureCacheEntry lockScratchTexture(const GrTextureDesc& desc, ScratchTexMatch match);
/**
* When done with an entry, call unlockTexture(entry) on it, which returns
* it to the cache, where it may be purged.
*/
- void unlockTexture(GrTextureEntry* entry);
+ void unlockTexture(TextureCacheEntry entry);
/**
* Creates a texture that is outside the cache. Does not count against
@@ -195,9 +235,6 @@
///////////////////////////////////////////////////////////////////////////
// Platform Surfaces
- // GrContext provides an interface for wrapping externally created textures
- // and rendertargets in their Gr-equivalents.
-
/**
* Wraps an existing 3D API surface in a GrObject. desc.fFlags determines
* the type of object returned. If kIsTexture is set the returned object
@@ -213,6 +250,7 @@
* on failure.
*/
GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
+
/**
* Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
* viewport state from the underlying 3D API and wraps it in a
@@ -559,9 +597,9 @@
};
DrawCategory fLastDrawCategory;
- GrGpu* fGpu;
- GrTextureCache* fTextureCache;
- GrFontCache* fFontCache;
+ GrGpu* fGpu;
+ GrResourceCache* fTextureCache;
+ GrFontCache* fFontCache;
GrPathRenderer* fCustomPathRenderer;
GrDefaultPathRenderer fDefaultPathRenderer;
@@ -597,10 +635,6 @@
static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
- bool finalizeTextureKey(GrTextureKey*,
- const GrSamplerState&,
- bool keyless) const;
-
GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
void drawClipIntoStencil();
@@ -680,24 +714,54 @@
};
/**
- * Unlocks a texture entry when this goes out of scope. Entry may be NULL.
+ * Gets and locks a scratch texture from a descriptor using
+ * either exact or approximate criteria. Unlocks texture in
+ * the destructor.
*/
-class GrAutoUnlockTextureEntry : ::GrNoncopyable {
+class GrAutoScratchTexture : ::GrNoncopyable {
public:
- GrAutoUnlockTextureEntry(GrContext* context, GrTextureEntry* entry)
- : fContext(context)
- , fEntry(entry) {
+ GrAutoScratchTexture()
+ : fContext(NULL) {
}
- ~GrAutoUnlockTextureEntry() {
- if (fContext && fEntry) {
+
+ GrAutoScratchTexture(GrContext* context,
+ const GrTextureDesc& desc,
+ GrContext::ScratchTexMatch match =
+ GrContext::kApprox_ScratchTexMatch)
+ : fContext(NULL) {
+ this->set(context, desc, match);
+ }
+
+ ~GrAutoScratchTexture() {
+ if (NULL != fContext) {
fContext->unlockTexture(fEntry);
}
}
- GrTexture* texture() { return fEntry->texture(); }
+ GrTexture* set(GrContext* context,
+ const GrTextureDesc& desc,
+ GrContext::ScratchTexMatch match =
+ GrContext::kApprox_ScratchTexMatch) {
+ if (NULL != fContext) {
+ fContext->unlockTexture(fEntry);
+ }
+ fContext = context;
+ if (NULL != fContext) {
+ fEntry = fContext->lockScratchTexture(desc, match);
+ GrTexture* ret = fEntry.texture();
+ if (NULL == ret) {
+ fContext = NULL;
+ }
+ return ret;
+ } else {
+ return NULL;
+ }
+ }
+
+ GrTexture* texture() { return fEntry.texture(); }
private:
- GrContext* fContext;
- GrTextureEntry* fEntry;
+ GrContext* fContext;
+ GrContext::TextureCacheEntry fEntry;
};
#endif