Cache the GrEffect used for text rendering in GrBitmapTextContext.

R=jvanverth@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/338093005
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index fdefee3..fed08f2 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -58,6 +58,7 @@
       '<(skia_src_path)/gpu/GrBlend.h',
       '<(skia_src_path)/gpu/GrBufferAllocPool.cpp',
       '<(skia_src_path)/gpu/GrBufferAllocPool.h',
+      '<(skia_src_path)/gpu/GrCacheable.cpp',
       '<(skia_src_path)/gpu/GrCacheID.cpp',
       '<(skia_src_path)/gpu/GrClipData.cpp',
       '<(skia_src_path)/gpu/GrContext.cpp',
diff --git a/include/gpu/GrCacheable.h b/include/gpu/GrCacheable.h
index 39c62b1..344ae6b 100644
--- a/include/gpu/GrCacheable.h
+++ b/include/gpu/GrCacheable.h
@@ -41,8 +41,17 @@
     void setCacheEntry(GrResourceCacheEntry* cacheEntry) { fCacheEntry = cacheEntry; }
     GrResourceCacheEntry* getCacheEntry() { return fCacheEntry; }
 
+    /**
+     * Gets an id that is unique for this GrCacheable object. It is static in that it does
+     * not change when the content of the GrCacheable object changes. This will never return
+     * 0.
+     */
+    uint32_t getGenerationID() const;
+
 protected:
-    GrCacheable() : fCacheEntry(NULL) {}
+    GrCacheable()
+        : fCacheEntry(NULL)
+        , fGenID(0) {}
 
     bool isInCache() const { return NULL != fCacheEntry; }
 
@@ -55,7 +64,8 @@
     void didChangeGpuMemorySize() const;
 
 private:
-    GrResourceCacheEntry* fCacheEntry;  // NULL if not in cache
+    GrResourceCacheEntry*   fCacheEntry;  // NULL if not in cache
+    mutable uint32_t        fGenID;
 
     typedef SkRefCnt INHERITED;
 };
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index 4f6a1af..25c13ec 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -56,6 +56,7 @@
 
     fCurrTexture = NULL;
     fCurrVertex = 0;
+    fEffectTextureGenID = 0;
 
     fVertices = NULL;
     fMaxVertices = 0;
@@ -93,12 +94,17 @@
         SkASSERT(fCurrTexture);
         GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);
 
+        uint32_t textureGenID = fCurrTexture->getGenerationID();
+        
+        if (textureGenID != fEffectTextureGenID) {
+            fCachedEffect.reset(GrCustomCoordsTextureEffect::Create(fCurrTexture, params));
+            fEffectTextureGenID = textureGenID;
+        }
+
         // This effect could be stored with one of the cache objects (atlas?)
         int coordsIdx = drawState->hasColorVertexAttribute() ? kGlyphCoordsWithColorAttributeIndex :
                                                                kGlyphCoordsNoColorAttributeIndex;
-        drawState->addCoverageEffect(
-                                GrCustomCoordsTextureEffect::Create(fCurrTexture, params),
-                                coordsIdx)->unref();
+        drawState->addCoverageEffect(fCachedEffect.get(), coordsIdx);
         SkASSERT(NULL != fStrike);
         switch (fStrike->getMaskFormat()) {
             // Color bitmap text
diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h
index 51193c8..836cc76 100644
--- a/src/gpu/GrBitmapTextContext.h
+++ b/src/gpu/GrBitmapTextContext.h
@@ -45,11 +45,13 @@
         kDefaultRequestedVerts   = kDefaultRequestedGlyphs * 4,
     };
 
-    void*                   fVertices;
-    int32_t                 fMaxVertices;
-    GrTexture*              fCurrTexture;
-    int                     fCurrVertex;
-    SkRect                  fVertexBounds;
+    void*                       fVertices;
+    int32_t                     fMaxVertices;
+    GrTexture*                  fCurrTexture;
+    SkAutoTUnref<GrEffectRef>   fCachedEffect;
+    uint32_t                    fEffectTextureGenID;
+    int                         fCurrVertex;
+    SkRect                      fVertexBounds;
 };
 
 #endif
diff --git a/src/gpu/GrCacheable.cpp b/src/gpu/GrCacheable.cpp
new file mode 100644
index 0000000..120be78
--- /dev/null
+++ b/src/gpu/GrCacheable.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "GrCacheable.h"
+
+uint32_t GrCacheable::getGenerationID() const {
+    static int32_t gPathRefGenerationID;
+    while (!fGenID) {
+        fGenID = static_cast<uint32_t>(sk_atomic_inc(&gPathRefGenerationID) + 1);
+    }
+    return fGenID;
+}