Minimize retrieving SkGlyph in GrTextContext

BUG=skia:

Review URL: https://codereview.chromium.org/1257603005
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
index 91527ab..4c1ef04 100644
--- a/src/gpu/GrAtlasTextContext.cpp
+++ b/src/gpu/GrAtlasTextContext.cpp
@@ -890,10 +890,7 @@
         if (glyph.fWidth) {
             this->bmpAppendGlyph(blob,
                                  runIndex,
-                                 GrGlyph::Pack(glyph.getGlyphID(),
-                                               glyph.getSubXFixed(),
-                                               glyph.getSubYFixed(),
-                                               GrGlyph::kCoverage_MaskStyle),
+                                 glyph,
                                  Sk48Dot16FloorToInt(fx),
                                  Sk48Dot16FloorToInt(fy),
                                  color,
@@ -960,10 +957,7 @@
                 if (glyph.fWidth) {
                     this->bmpAppendGlyph(blob,
                                          runIndex,
-                                         GrGlyph::Pack(glyph.getGlyphID(),
-                                                       glyph.getSubXFixed(),
-                                                       glyph.getSubYFixed(),
-                                                       GrGlyph::kCoverage_MaskStyle),
+                                         glyph,
                                          Sk48Dot16FloorToInt(fx),
                                          Sk48Dot16FloorToInt(fy),
                                          color,
@@ -998,10 +992,7 @@
 
                     this->bmpAppendGlyph(blob,
                                          runIndex,
-                                         GrGlyph::Pack(glyph.getGlyphID(),
-                                                       glyph.getSubXFixed(),
-                                                       glyph.getSubYFixed(),
-                                                       GrGlyph::kCoverage_MaskStyle),
+                                         glyph,
                                          Sk48Dot16FloorToInt(fx),
                                          Sk48Dot16FloorToInt(fy),
                                          color,
@@ -1026,10 +1017,7 @@
                     Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + SK_ScalarHalf); //halfSampleY;
                     this->bmpAppendGlyph(blob,
                                          runIndex,
-                                         GrGlyph::Pack(glyph.getGlyphID(),
-                                                       glyph.getSubXFixed(),
-                                                       glyph.getSubYFixed(),
-                                                       GrGlyph::kCoverage_MaskStyle),
+                                         glyph,
                                          Sk48Dot16FloorToInt(fx),
                                          Sk48Dot16FloorToInt(fy),
                                          color,
@@ -1054,10 +1042,7 @@
                     Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + SK_ScalarHalf); //halfSampleY;
                     this->bmpAppendGlyph(blob,
                                          runIndex,
-                                         GrGlyph::Pack(glyph.getGlyphID(),
-                                                       glyph.getSubXFixed(),
-                                                       glyph.getSubYFixed(),
-                                                       GrGlyph::kCoverage_MaskStyle),
+                                         glyph,
                                          Sk48Dot16FloorToInt(fx),
                                          Sk48Dot16FloorToInt(fy),
                                          color,
@@ -1183,10 +1168,7 @@
 
                 if (!this->dfAppendGlyph(blob,
                                          runIndex,
-                                         GrGlyph::Pack(glyph.getGlyphID(),
-                                                       glyph.getSubXFixed(),
-                                                       glyph.getSubYFixed(),
-                                                       GrGlyph::kDistance_MaskStyle),
+                                         glyph,
                                          x, y, color, fontScaler, clipRect,
                                          textRatio, viewMatrix)) {
                     // couldn't append, send to fallback
@@ -1216,10 +1198,7 @@
 
                 if (!this->dfAppendGlyph(blob,
                                          runIndex,
-                                         GrGlyph::Pack(glyph.getGlyphID(),
-                                                       glyph.getSubXFixed(),
-                                                       glyph.getSubYFixed(),
-                                                       GrGlyph::kDistance_MaskStyle),
+                                         glyph,
                                          x - advanceX, y - advanceY, color,
                                          fontScaler,
                                          clipRect,
@@ -1239,7 +1218,7 @@
 }
 
 void GrAtlasTextContext::bmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
-                                        GrGlyph::PackedID packed,
+                                        const SkGlyph& skGlyph,
                                         int vx, int vy, GrColor color, GrFontScaler* scaler,
                                         const SkIRect& clipRect) {
     Run& run = blob->fRuns[runIndex];
@@ -1248,7 +1227,11 @@
         run.fStrike.reset(SkRef(fCurrStrike));
     }
 
-    GrGlyph* glyph = fCurrStrike->getGlyph(packed, scaler);
+    GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
+                                         skGlyph.getSubXFixed(),
+                                         skGlyph.getSubYFixed(),
+                                         GrGlyph::kCoverage_MaskStyle);
+    GrGlyph* glyph = fCurrStrike->getGlyph(skGlyph, id, scaler);
     if (!glyph) {
         return;
     }
@@ -1274,7 +1257,7 @@
 
     // If the glyph is too large we fall back to paths
     if (glyph->fTooLargeForAtlas) {
-        this->appendGlyphPath(blob, glyph, scaler, SkIntToScalar(vx), SkIntToScalar(vy));
+        this->appendGlyphPath(blob, glyph, scaler, skGlyph, SkIntToScalar(vx), SkIntToScalar(vy));
         return;
     }
 
@@ -1300,7 +1283,7 @@
 }
 
 bool GrAtlasTextContext::dfAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
-                                       GrGlyph::PackedID packed,
+                                       const SkGlyph& skGlyph,
                                        SkScalar sx, SkScalar sy, GrColor color,
                                        GrFontScaler* scaler,
                                        const SkIRect& clipRect,
@@ -1311,7 +1294,11 @@
         run.fStrike.reset(SkRef(fCurrStrike));
     }
 
-    GrGlyph* glyph = fCurrStrike->getGlyph(packed, scaler);
+    GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
+                                         skGlyph.getSubXFixed(),
+                                         skGlyph.getSubYFixed(),
+                                         GrGlyph::kDistance_MaskStyle);
+    GrGlyph* glyph = fCurrStrike->getGlyph(skGlyph, id, scaler);
     if (!glyph) {
         return true;
     }
@@ -1350,7 +1337,7 @@
     // TODO combine with the above
     // If the glyph is too large we fall back to paths
     if (glyph->fTooLargeForAtlas) {
-        this->appendGlyphPath(blob, glyph, scaler, sx - dx, sy - dy);
+        this->appendGlyphPath(blob, glyph, scaler, skGlyph, sx - dx, sy - dy);
         return true;
     }
 
@@ -1367,17 +1354,16 @@
 }
 
 inline void GrAtlasTextContext::appendGlyphPath(GrAtlasTextBlob* blob, GrGlyph* glyph,
-                                                GrFontScaler* scaler, SkScalar x, SkScalar y) {
+                                                GrFontScaler* scaler, const SkGlyph& skGlyph,
+                                                SkScalar x, SkScalar y) {
     if (NULL == glyph->fPath) {
-        SkPath* path = SkNEW(SkPath);
-        if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
-            // flag the glyph as being dead?
-            SkDELETE(path);
+        const SkPath* glyphPath = scaler->getGlyphPath(skGlyph);
+        if (!glyphPath) {
             return;
         }
-        glyph->fPath = path;
+
+        glyph->fPath = SkNEW_ARGS(SkPath, (*glyphPath));
     }
-    SkASSERT(glyph->fPath);
     blob->fBigGlyphs.push_back(GrAtlasTextBlob::BigGlyph(*glyph->fPath, x, y));
 }
 
@@ -1686,27 +1672,30 @@
                 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) {
                     if (regenerateTextureCoords) {
                         size_t glyphOffset = glyphIdx + info.fGlyphStartIndex;
-                        GrGlyph* glyph;
+
+                        GrGlyph* glyph = blob->fGlyphs[glyphOffset];
+                        GrGlyph::PackedID id = glyph->fPackedID;
+                        const SkGlyph& skGlyph = scaler->grToSkGlyph(id);
                         if (regenerateGlyphs) {
                             // Get the id from the old glyph, and use the new strike to lookup
                             // the glyph.
-                            glyph = blob->fGlyphs[glyphOffset];
-                            blob->fGlyphs[glyphOffset] = strike->getGlyph(glyph->fPackedID,
-                                                                          scaler);
+                            blob->fGlyphs[glyphOffset] = strike->getGlyph(skGlyph, id, scaler);
                         }
                         glyph = blob->fGlyphs[glyphOffset];
                         SkASSERT(glyph);
-                        SkASSERT(glyph->fMaskFormat == this->maskFormat());
+                        SkASSERT(id == glyph->fPackedID &&
+                                 glyph->fMaskFormat == this->maskFormat());
 
                         if (!fFontCache->hasGlyph(glyph) &&
-                            !strike->addGlyphToAtlas(batchTarget, glyph, scaler)) {
+                            !strike->addGlyphToAtlas(batchTarget, glyph, scaler, skGlyph)) {
                             this->flush(batchTarget, &flushInfo);
                             batchTarget->initDraw(gp, pipeline);
                             brokenRun = glyphIdx > 0;
 
                             SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(batchTarget,
                                                                                 glyph,
-                                                                                scaler);
+                                                                                scaler,
+                                                                                skGlyph);
                             SkASSERT(success);
                         }
                         fFontCache->addGlyphToBulkAndSetUseToken(&info.fBulkUseToken, glyph,
diff --git a/src/gpu/GrAtlasTextContext.h b/src/gpu/GrAtlasTextContext.h
index e89f987..41c5217 100644
--- a/src/gpu/GrAtlasTextContext.h
+++ b/src/gpu/GrAtlasTextContext.h
@@ -22,6 +22,7 @@
 class GrDrawTarget;
 class GrPipelineBuilder;
 class GrTextBlobCache;
+class SkGlyph;
 
 /*
  * This class implements GrTextContext using standard bitmap fonts, and can also process textblobs.
@@ -57,13 +58,13 @@
     GrAtlasTextBlob* setupDFBlob(int glyphCount, const SkPaint& origPaint,
                                 const SkMatrix& viewMatrix, SkGlyphCache** cache,
                                 SkPaint* dfPaint, SkScalar* textRatio);
-    void bmpAppendGlyph(GrAtlasTextBlob*, int runIndex, GrGlyph::PackedID, int left, int top,
+    void bmpAppendGlyph(GrAtlasTextBlob*, int runIndex, const SkGlyph&, int left, int top,
                         GrColor color, GrFontScaler*, const SkIRect& clipRect);
-    bool dfAppendGlyph(GrAtlasTextBlob*, int runIndex, GrGlyph::PackedID, SkScalar sx, SkScalar sy,
+    bool dfAppendGlyph(GrAtlasTextBlob*, int runIndex, const SkGlyph&, SkScalar sx, SkScalar sy,
                        GrColor color, GrFontScaler*, const SkIRect& clipRect, SkScalar textRatio,
                        const SkMatrix& viewMatrix);
-    inline void appendGlyphPath(GrAtlasTextBlob* blob, GrGlyph* glyph,
-                                GrFontScaler* scaler, SkScalar x, SkScalar y);
+    inline void appendGlyphPath(GrAtlasTextBlob*, GrGlyph*, GrFontScaler*, const SkGlyph&,
+                                SkScalar x, SkScalar y);
     inline void appendGlyphCommon(GrAtlasTextBlob*, Run*, Run::SubRunInfo*,
                                   const SkRect& positions, GrColor color,
                                   size_t vertexStride, bool useVertexColor,
diff --git a/src/gpu/GrBatchFontCache.cpp b/src/gpu/GrBatchFontCache.cpp
index 6ffcdcf..ecaa91e 100644
--- a/src/gpu/GrBatchFontCache.cpp
+++ b/src/gpu/GrBatchFontCache.cpp
@@ -163,20 +163,20 @@
     }
 }
 
-GrGlyph* GrBatchTextStrike::generateGlyph(GrGlyph::PackedID packed,
+GrGlyph* GrBatchTextStrike::generateGlyph(const SkGlyph& skGlyph, GrGlyph::PackedID packed,
                                           GrFontScaler* scaler) {
     SkIRect bounds;
     if (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(packed)) {
-        if (!scaler->getPackedGlyphDFBounds(packed, &bounds)) {
+        if (!scaler->getPackedGlyphDFBounds(skGlyph, &bounds)) {
             return NULL;
         }
     } else {
-        if (!scaler->getPackedGlyphBounds(packed, &bounds)) {
+        if (!scaler->getPackedGlyphBounds(skGlyph, &bounds)) {
             return NULL;
         }
     }
-    GrMaskFormat format = scaler->getPackedGlyphMaskFormat(packed);
-    
+    GrMaskFormat format = scaler->getPackedGlyphMaskFormat(skGlyph);
+
     GrGlyph* glyph = (GrGlyph*)fPool.alloc(sizeof(GrGlyph), SK_MALLOC_THROW);
     glyph->init(packed, bounds, format);
     fCache.add(glyph);
@@ -196,7 +196,7 @@
 }
 
 bool GrBatchTextStrike::addGlyphToAtlas(GrBatchTarget* batchTarget, GrGlyph* glyph,
-                                        GrFontScaler* scaler) {
+                                        GrFontScaler* scaler, const SkGlyph& skGlyph) {
     SkASSERT(glyph);
     SkASSERT(scaler);
     SkASSERT(fCache.find(glyph->fPackedID));
@@ -210,16 +210,13 @@
     SkAutoSMalloc<1024> storage(size);
 
     if (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(glyph->fPackedID)) {
-        if (!scaler->getPackedGlyphDFImage(glyph->fPackedID, glyph->width(),
-                                           glyph->height(),
+        if (!scaler->getPackedGlyphDFImage(skGlyph, glyph->width(), glyph->height(),
                                            storage.get())) {
             return false;
         }
     } else {
-        if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
-                                         glyph->height(),
-                                         glyph->width() * bytesPerPixel,
-                                         storage.get())) {
+        if (!scaler->getPackedGlyphImage(skGlyph, glyph->width(), glyph->height(),
+                                         glyph->width() * bytesPerPixel, storage.get())) {
             return false;
         }
     }
diff --git a/src/gpu/GrBatchFontCache.h b/src/gpu/GrBatchFontCache.h
index 28aa036..33f313c 100644
--- a/src/gpu/GrBatchFontCache.h
+++ b/src/gpu/GrBatchFontCache.h
@@ -11,6 +11,7 @@
 #include "GrBatchAtlas.h"
 #include "GrFontScaler.h"
 #include "GrGlyph.h"
+#include "SkGlyph.h"
 #include "SkTDynamicHash.h"
 #include "SkVarAlloc.h"
 
@@ -30,16 +31,17 @@
     const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; }
     GrBatchFontCache* getBatchFontCache() const { return fBatchFontCache; }
 
-    inline GrGlyph* getGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler) {
+    inline GrGlyph* getGlyph(const SkGlyph& skGlyph, GrGlyph::PackedID packed,
+                             GrFontScaler* scaler) {
         GrGlyph* glyph = fCache.find(packed);
         if (NULL == glyph) {
-            glyph = this->generateGlyph(packed, scaler);
+            glyph = this->generateGlyph(skGlyph, packed, scaler);
         }
         return glyph;
     }
 
     // returns true if glyph successfully added to texture atlas, false otherwise
-    bool addGlyphToAtlas(GrBatchTarget*, GrGlyph*, GrFontScaler*);
+    bool addGlyphToAtlas(GrBatchTarget*, GrGlyph*, GrFontScaler*, const SkGlyph&);
 
     // testing
     int countGlyphs() const { return fCache.count(); }
@@ -66,7 +68,7 @@
     int fAtlasedGlyphs;
     bool fIsAbandoned;
 
-    GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler);
+    GrGlyph* generateGlyph(const SkGlyph&, GrGlyph::PackedID, GrFontScaler*);
 
     friend class GrBatchFontCache;
 };
diff --git a/src/gpu/GrFontScaler.cpp b/src/gpu/GrFontScaler.cpp
index cc98ac5..84fd581 100644
--- a/src/gpu/GrFontScaler.cpp
+++ b/src/gpu/GrFontScaler.cpp
@@ -46,10 +46,7 @@
     return fKey;
 }
 
-GrMaskFormat GrFontScaler::getPackedGlyphMaskFormat(GrGlyph::PackedID packed) const {
-    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
-                                                      GrGlyph::UnpackFixedX(packed),
-                                                      GrGlyph::UnpackFixedY(packed));
+GrMaskFormat GrFontScaler::getPackedGlyphMaskFormat(const SkGlyph& glyph) const {
     SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
     switch (format) {
         case SkMask::kBW_Format:
@@ -66,19 +63,13 @@
     }
 }
 
-bool GrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed, SkIRect* bounds) {
-    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
-                                                      GrGlyph::UnpackFixedX(packed),
-                                                      GrGlyph::UnpackFixedY(packed));
+bool GrFontScaler::getPackedGlyphBounds(const SkGlyph& glyph, SkIRect* bounds) {
     bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
 
     return true;
 }
 
-bool GrFontScaler::getPackedGlyphDFBounds(GrGlyph::PackedID packed, SkIRect* bounds) {
-    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
-                                                      GrGlyph::UnpackFixedX(packed),
-                                                      GrGlyph::UnpackFixedY(packed));
+bool GrFontScaler::getPackedGlyphDFBounds(const SkGlyph& glyph, SkIRect* bounds) {
     bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
     bounds->outset(SK_DistanceFieldPad, SK_DistanceFieldPad);
 
@@ -111,12 +102,8 @@
 }
 }
 
-bool GrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
-                                         int width, int height,
-                                         int dstRB, void* dst) {
-    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
-                                                      GrGlyph::UnpackFixedX(packed),
-                                                      GrGlyph::UnpackFixedY(packed));
+bool GrFontScaler::getPackedGlyphImage(const SkGlyph& glyph, int width, int height, int dstRB,
+                                       void* dst) {
     SkASSERT(glyph.fWidth == width);
     SkASSERT(glyph.fHeight == height);
     const void* src = fStrike->findImage(glyph);
@@ -158,12 +145,7 @@
     return true;
 }
 
-bool GrFontScaler::getPackedGlyphDFImage(GrGlyph::PackedID packed,
-                                         int width, int height,
-                                         void* dst) {
-    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
-                                                      GrGlyph::UnpackFixedX(packed),
-                                                      GrGlyph::UnpackFixedY(packed));
+bool GrFontScaler::getPackedGlyphDFImage(const SkGlyph& glyph, int width, int height, void* dst) {
     SkASSERT(glyph.fWidth + 2*SK_DistanceFieldPad == width);
     SkASSERT(glyph.fHeight + 2*SK_DistanceFieldPad == height);
     const void* image = fStrike->findImage(glyph);
@@ -192,14 +174,12 @@
     return true;
 }
 
-// we should just return const SkPath* (NULL means false)
-bool GrFontScaler::getGlyphPath(uint16_t glyphID, SkPath* path) {
+const SkPath* GrFontScaler::getGlyphPath(const SkGlyph& glyph) {
+    return fStrike->findPath(glyph);
+}
 
-    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(glyphID);
-    const SkPath* skPath = fStrike->findPath(glyph);
-    if (skPath) {
-        *path = *skPath;
-        return true;
-    }
-    return false;
+const SkGlyph& GrFontScaler::grToSkGlyph(GrGlyph::PackedID id) {
+    return fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(id),
+                                      GrGlyph::UnpackFixedX(id),
+                                      GrGlyph::UnpackFixedY(id));
 }
diff --git a/src/gpu/GrFontScaler.h b/src/gpu/GrFontScaler.h
index 644c8b7..1dc5584 100644
--- a/src/gpu/GrFontScaler.h
+++ b/src/gpu/GrFontScaler.h
@@ -13,6 +13,7 @@
 
 #include "SkDescriptor.h"
 
+class SkGlyph;
 class SkPath;
 
 /*
@@ -49,14 +50,13 @@
     
     const GrFontDescKey* getKey();
     GrMaskFormat getMaskFormat() const;
-    GrMaskFormat getPackedGlyphMaskFormat(GrGlyph::PackedID) const;
-    bool getPackedGlyphBounds(GrGlyph::PackedID, SkIRect* bounds);
-    bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
-                                     int rowBytes, void* image);
-    bool getPackedGlyphDFBounds(GrGlyph::PackedID, SkIRect* bounds);
-    bool getPackedGlyphDFImage(GrGlyph::PackedID, int width, int height,
-                                       void* image);
-    bool getGlyphPath(uint16_t glyphID, SkPath*);
+    GrMaskFormat getPackedGlyphMaskFormat(const SkGlyph&) const;
+    bool getPackedGlyphBounds(const SkGlyph&, SkIRect* bounds);
+    bool getPackedGlyphImage(const SkGlyph&, int width, int height, int rowBytes, void* image);
+    bool getPackedGlyphDFBounds(const SkGlyph&, SkIRect* bounds);
+    bool getPackedGlyphDFImage(const SkGlyph&, int width, int height, void* image);
+    const SkPath* getGlyphPath(const SkGlyph&);
+    const SkGlyph& grToSkGlyph(GrGlyph::PackedID);
     
 private:
     SkGlyphCache*  fStrike;