Add lockKeylessTexture() for caching texture without a content key.

Review URL: http://codereview.appspot.com/4440065/




git-svn-id: http://skia.googlecode.com/svn/trunk@1172 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrAtlas.cpp b/gpu/src/GrAtlas.cpp
index dfc0a69..e577beb 100644
--- a/gpu/src/GrAtlas.cpp
+++ b/gpu/src/GrAtlas.cpp
@@ -175,9 +175,9 @@
     GrAssert(0 == kA8_GrMaskFormat);
     GrAssert(1 == kA565_GrMaskFormat);
     if (NULL == fTexture[format]) {
-        GrGpu::TextureDesc desc = {
-            GrGpu::kDynamicUpdate_TextureFlag,
-            GrGpu::kNone_AALevel,
+        GrTextureDesc desc = {
+            kDynamicUpdate_GrTextureFlagBit,
+            kNone_GrAALevel,
             GR_ATLAS_TEXTURE_WIDTH,
             GR_ATLAS_TEXTURE_HEIGHT,
             maskformat2pixelconfig(format)
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index 7cf0cca..75caa74 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -103,9 +103,46 @@
     fFontCache->freeAll();
 }
 
+////////////////////////////////////////////////////////////////////////////////
+
+
+enum {
+    kNPOTBit    = 0x1,
+    kFilterBit  = 0x2,
+    kKeylessBit = 0x4,
+};
+
+bool GrContext::finalizeTextureKey(GrTextureKey* key,
+                                   const GrSamplerState& sampler,
+                                   bool keyless) const {
+    uint32_t bits = 0;
+    uint16_t width = key->width();
+    uint16_t height = key->height();
+
+    if (!fGpu->npotTextureTileSupport()) {
+        bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
+
+        bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) ||
+                     (sampler.getWrapY() != GrSamplerState::kClamp_WrapMode);
+
+        if (tiled && !isPow2) {
+            bits |= kNPOTBit;
+            if (sampler.isFilter()) {
+                bits |= kFilterBit;
+            }
+        }
+    }
+
+    if (keyless) {
+        bits |= kKeylessBit;
+    }
+    key->finalize(bits);
+    return 0 != bits;
+}
+
 GrTextureEntry* GrContext::findAndLockTexture(GrTextureKey* key,
                                               const GrSamplerState& sampler) {
-    finalizeTextureKey(key, sampler);
+    finalizeTextureKey(key, sampler, false);
     return fTextureCache->findAndLock(*key);
 }
 
@@ -138,7 +175,7 @@
 
 GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key,
                                                 const GrSamplerState& sampler,
-                                                const GrGpu::TextureDesc& desc,
+                                                const GrTextureDesc& desc,
                                                 void* srcData, size_t rowBytes) {
     GrAssert(key->width() == desc.fWidth);
     GrAssert(key->height() == desc.fHeight);
@@ -148,7 +185,7 @@
 #endif
 
     GrTextureEntry* entry = NULL;
-    bool special = finalizeTextureKey(key, sampler);
+    bool special = finalizeTextureKey(key, sampler, false);
     if (special) {
         GrTextureEntry* clampEntry;
         GrTextureKey clampKey(*key);
@@ -163,9 +200,10 @@
                 return NULL;
             }
         }
-        GrGpu::TextureDesc rtDesc = desc;
-        rtDesc.fFlags |= GrGpu::kRenderTarget_TextureFlag |
-                         GrGpu::kNoStencil_TextureFlag;
+        GrTextureDesc rtDesc = desc;
+        rtDesc.fFlags =  rtDesc.fFlags |
+                         kRenderTarget_GrTextureFlagBit |
+                         kNoStencil_GrTextureFlagBit;
         rtDesc.fWidth  = GrNextPow2(GrMax<int>(desc.fWidth,
                                                fGpu->minRenderTargetWidth()));
         rtDesc.fHeight = GrNextPow2(GrMax<int>(desc.fHeight,
@@ -211,7 +249,7 @@
             // not. Either implement filtered stretch blit on CPU or just create
             // one when FBO case fails.
 
-            rtDesc.fFlags = 0;
+            rtDesc.fFlags = kNone_GrTextureFlags;
             // no longer need to clamp at min RT size.
             rtDesc.fWidth  = GrNextPow2(desc.fWidth);
             rtDesc.fHeight = GrNextPow2(desc.fHeight);
@@ -243,19 +281,37 @@
     return entry;
 }
 
+GrTextureEntry* GrContext::lockKeylessTexture(const GrTextureDesc& desc,
+                                              const GrSamplerState& state) {
+    uint32_t p0 = desc.fFormat;
+    uint32_t p1 = (desc.fAALevel << 16) | desc.fFlags;
+    GrTextureKey key(p0, p1, desc.fWidth, desc.fHeight);
+    this->finalizeTextureKey(&key, state, true);
+    GrTextureEntry* entry = fTextureCache->findAndLock(key);
+    if (NULL == entry) {
+        GrTexture* texture = fGpu->createTexture(desc, NULL, 0);
+        if (NULL != texture) {
+            entry = fTextureCache->createAndLock(key, texture);
+        }
+    }
+    // If the caller gives us the same desc/sampler twice we don't want
+    // to return the same texture the second time (unless it was previously
+    // released). So we detach the entry from the cache and reattach at release.
+    if (NULL != entry) {
+        fTextureCache->detach(entry);
+    }
+    return entry;
+}
+
 void GrContext::unlockTexture(GrTextureEntry* entry) {
-    fTextureCache->unlock(entry);
+    if (kKeylessBit & entry->key().getPrivateBits()) {
+        fTextureCache->reattachAndUnlock(entry);
+    } else {
+        fTextureCache->unlock(entry);
+    }
 }
 
-void GrContext::detachCachedTexture(GrTextureEntry* entry) {
-    fTextureCache->detach(entry);
-}
-
-void GrContext::reattachAndUnlockCachedTexture(GrTextureEntry* entry) {
-    fTextureCache->reattachAndUnlock(entry);
-}
-
-GrTexture* GrContext::createUncachedTexture(const GrGpu::TextureDesc& desc,
+GrTexture* GrContext::createUncachedTexture(const GrTextureDesc& desc,
                                             void* srcData,
                                             size_t rowBytes) {
     return fGpu->createTexture(desc, srcData, rowBytes);
@@ -935,8 +991,8 @@
     // TODO: when underlying api has a direct way to do this we should use it
     // (e.g. glDrawPixels on desktop GL).
 
-    const GrGpu::TextureDesc desc = {
-        0, GrGpu::kNone_AALevel, width, height, config
+    const GrTextureDesc desc = {
+        kNone_GrTextureFlags, kNone_GrAALevel, width, height, config
     };
     GrTexture* texture = fGpu->createTexture(desc, buffer, stride);
     if (NULL == texture) {
@@ -1123,28 +1179,6 @@
 #endif
 }
 
-bool GrContext::finalizeTextureKey(GrTextureKey* key,
-                                   const GrSamplerState& sampler) const {
-    uint32_t bits = 0;
-    uint16_t width = key->width();
-    uint16_t height = key->height();
-
-
-    if (!fGpu->npotTextureTileSupport()) {
-        bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
-
-        bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) ||
-                     (sampler.getWrapY() != GrSamplerState::kClamp_WrapMode);
-
-        if (tiled && !isPow2) {
-            bits |= 1;
-            bits |= sampler.isFilter() ? 2 : 0;
-        }
-    }
-    key->finalize(bits);
-    return 0 != bits;
-}
-
 GrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) {
     GrDrawTarget* target;
 #if DEFER_TEXT_RENDERING
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index c8e2bc7..c05a04a 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -136,7 +136,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-GrTexture* GrGpu::createTexture(const TextureDesc& desc,
+GrTexture* GrGpu::createTexture(const GrTextureDesc& desc,
                                 const void* srcData, size_t rowBytes) {
     this->handleDirtyContext();
     return this->onCreateTexture(desc, srcData, rowBytes);
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index f2ec450..b0ec2bc 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -223,10 +223,10 @@
         GrPrintf("Palette8 support: %s\n", (f8bitPaletteSupport ? "YES" : "NO"));
     }
 
-    GR_STATIC_ASSERT(0 == kNone_AALevel);
-    GR_STATIC_ASSERT(1 == kLow_AALevel);
-    GR_STATIC_ASSERT(2 == kMed_AALevel);
-    GR_STATIC_ASSERT(3 == kHigh_AALevel);
+    GR_STATIC_ASSERT(0 == kNone_GrAALevel);
+    GR_STATIC_ASSERT(1 == kLow_GrAALevel);
+    GR_STATIC_ASSERT(2 == kMed_GrAALevel);
+    GR_STATIC_ASSERT(3 == kHigh_GrAALevel);
 
     memset(fAASamples, 0, sizeof(fAASamples));
     fMSFBOType = kNone_MSFBO;
@@ -268,14 +268,14 @@
         GrGLint maxSamples;
         GR_GL_GetIntegerv(GR_GL_MAX_SAMPLES, &maxSamples);
         if (maxSamples > 1 ) {
-            fAASamples[kNone_AALevel] = 0;
-            fAASamples[kLow_AALevel] = GrMax(2,
-                                             GrFixedFloorToInt((GR_FixedHalf) *
-                                                             maxSamples));
-            fAASamples[kMed_AALevel] = GrMax(2,
-                                             GrFixedFloorToInt(((GR_Fixed1*3)/4) *
-                                                             maxSamples));
-            fAASamples[kHigh_AALevel] = maxSamples;
+            fAASamples[kNone_GrAALevel] = 0;
+            fAASamples[kLow_GrAALevel] = GrMax(2,
+                                               GrFixedFloorToInt((GR_FixedHalf) *
+                                               maxSamples));
+            fAASamples[kMed_GrAALevel] = GrMax(2,
+                                               GrFixedFloorToInt(((GR_Fixed1*3)/4) *
+                                               maxSamples));
+            fAASamples[kHigh_GrAALevel] = maxSamples;
         }
         if (gPrintStartupSpew) {
             GrPrintf("\tMax Samples: %d\n", maxSamples);
@@ -529,8 +529,10 @@
 
     fHWGeometryState.fIndexBuffer = NULL;
     fHWGeometryState.fVertexBuffer = NULL;
+    
     GR_GL(BindBuffer(GR_GL_ARRAY_BUFFER, 0));
     GR_GL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 0));
+    
     fHWGeometryState.fArrayPtrsDirty = true;
 
     GR_GL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
@@ -701,7 +703,7 @@
 }
 #endif
 
-GrTexture* GrGpuGL::onCreateTexture(const TextureDesc& desc,
+GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
                                     const void* srcData,
                                     size_t rowBytes) {
 
@@ -728,7 +730,7 @@
     glDesc.fFormat        = desc.fFormat;
     glDesc.fOwnsID        = true;
 
-    bool renderTarget = 0 != (desc.fFlags & kRenderTarget_TextureFlag);
+    bool renderTarget = 0 != (desc.fFlags & kRenderTarget_GrTextureFlagBit);
     if (!canBeTexture(desc.fFormat,
                       &internalFormat,
                       &glDesc.fUploadFormat,
@@ -738,7 +740,7 @@
 
     GrAssert(as_size_t(desc.fAALevel) < GR_ARRAY_COUNT(fAASamples));
     GrGLint samples = fAASamples[desc.fAALevel];
-    if (kNone_MSFBO == fMSFBOType && desc.fAALevel != kNone_AALevel) {
+    if (kNone_MSFBO == fMSFBOType && desc.fAALevel != kNone_GrAALevel) {
         GrPrintf("AA RT requested but not supported on this platform.");
     }
 
@@ -815,7 +817,7 @@
         GrAssert(desc.fWidth == glDesc.fAllocWidth);
         GrAssert(desc.fHeight == glDesc.fAllocHeight);
         GrGLsizei imageSize = glDesc.fAllocWidth * glDesc.fAllocHeight +
-                              kColorTableSize;
+                              kGrColorTableSize;
         GR_GL(CompressedTexImage2D(GR_GL_TEXTURE_2D, 0, glDesc.fUploadFormat,
                                    glDesc.fAllocWidth, glDesc.fAllocHeight,
                                    0, imageSize, srcData));
@@ -932,7 +934,7 @@
         } else {
             rtIDs.fRTFBOID = rtIDs.fTexFBOID;
         }
-        if (!(kNoStencil_TextureFlag & desc.fFlags)) {
+        if (!(kNoStencil_GrTextureFlagBit & desc.fFlags)) {
             GR_GL(GenRenderbuffers(1, &rtIDs.fStencilRenderbufferID));
             GrAssert(0 != rtIDs.fStencilRenderbufferID);
         }
@@ -1079,7 +1081,7 @@
         fHWDrawState.fRenderTarget = NULL;
 
         // clear the new stencil buffer if we have one
-        if (!(desc.fFlags & kNoStencil_TextureFlag)) {
+        if (!(desc.fFlags & kNoStencil_GrTextureFlagBit)) {
             GrRenderTarget* rtSave = fCurrDrawState.fRenderTarget;
             fCurrDrawState.fRenderTarget = rt;
             this->clearStencil(0, ~0);
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
index 08edb27..918ab80 100644
--- a/gpu/src/GrGpuGL.h
+++ b/gpu/src/GrGpuGL.h
@@ -72,7 +72,7 @@
     // overrides from GrGpu
     virtual void resetContext();
 
-    virtual GrTexture* onCreateTexture(const TextureDesc& desc,
+    virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
                                        const void* srcData,
                                        size_t rowBytes);
     virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size,