Add GPU support for color bitmap fonts

BUG=skia:1869
R=bungeman@google.com, robertphillips@google.com, bsalomon@google.com

Author: jvanverth@google.com

Review URL: https://codereview.chromium.org/99993002

git-svn-id: http://skia.googlecode.com/svn/trunk@12471 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index 8d955bb..a43c4a2 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -70,7 +70,10 @@
                                 GrCustomCoordsTextureEffect::Create(fCurrTexture, params),
                                 kGlyphCoordsAttributeIndex)->unref();
 
-        if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
+        if (NULL != fStrike && kARGB_GrMaskFormat == fStrike->getMaskFormat()) {
+            drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
+            drawState->setColor(0xffffffff);
+        } else if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
             if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
                 kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
                 fPaint.numColorStages()) {
diff --git a/src/gpu/GrTextStrike.cpp b/src/gpu/GrTextStrike.cpp
index ddab1e9..a4d3575 100644
--- a/src/gpu/GrTextStrike.cpp
+++ b/src/gpu/GrTextStrike.cpp
@@ -28,7 +28,7 @@
 
 GrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) {
     gpu->ref();
-    for (int i = 0; i < kMaskFormatCount; ++i) {
+    for (int i = 0; i < kAtlasCount; ++i) {
         fAtlasMgr[i] = NULL;
     }
 
@@ -37,7 +37,7 @@
 
 GrFontCache::~GrFontCache() {
     fCache.deleteAll();
-    for (int i = 0; i < kMaskFormatCount; ++i) {
+    for (int i = 0; i < kAtlasCount; ++i) {
         delete fAtlasMgr[i];
     }
     fGpu->unref();
@@ -47,28 +47,40 @@
 }
 
 static GrPixelConfig mask_format_to_pixel_config(GrMaskFormat format) {
-    switch (format) {
-        case kA8_GrMaskFormat:
-            return kAlpha_8_GrPixelConfig;
-        case kA565_GrMaskFormat:
-            return kRGB_565_GrPixelConfig;
-        case kA888_GrMaskFormat:
-            return kSkia8888_GrPixelConfig;
-        default:
-            SkDEBUGFAIL("unknown maskformat");
-    }
-    return kUnknown_GrPixelConfig;
+    static const GrPixelConfig sPixelConfigs[] = { 
+        kAlpha_8_GrPixelConfig, 
+        kRGB_565_GrPixelConfig, 
+        kSkia8888_GrPixelConfig,
+        kSkia8888_GrPixelConfig
+    };
+    SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sPixelConfigs) == kMaskFormatCount, array_size_mismatch);
+
+    return sPixelConfigs[format];
+}
+
+static int mask_format_to_atlas_index(GrMaskFormat format) {
+    static const int sAtlasIndices[] = { 
+        GrFontCache::kA8_AtlasType, 
+        GrFontCache::k565_AtlasType, 
+        GrFontCache::k8888_AtlasType, 
+        GrFontCache::k8888_AtlasType 
+    };
+    SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, array_size_mismatch);
+
+    SkASSERT(sAtlasIndices[format] < GrFontCache::kAtlasCount);
+    return sAtlasIndices[format];
 }
 
 GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler,
                                           const Key& key) {
     GrMaskFormat format = scaler->getMaskFormat();
     GrPixelConfig config = mask_format_to_pixel_config(format);
-    if (NULL == fAtlasMgr[format]) {
-        fAtlasMgr[format] = SkNEW_ARGS(GrAtlasMgr, (fGpu, config));
+    int atlasIndex = mask_format_to_atlas_index(format);
+    if (NULL == fAtlasMgr[atlasIndex]) {
+        fAtlasMgr[atlasIndex] = SkNEW_ARGS(GrAtlasMgr, (fGpu, config));
     }
     GrTextStrike* strike = SkNEW_ARGS(GrTextStrike,
-                                      (this, scaler->getKey(), format, fAtlasMgr[format]));
+                                      (this, scaler->getKey(), format, fAtlasMgr[atlasIndex]));
     fCache.insert(key, strike);
 
     if (fHead) {
@@ -86,7 +98,7 @@
 
 void GrFontCache::freeAll() {
     fCache.deleteAll();
-    for (int i = 0; i < kMaskFormatCount; ++i) {
+    for (int i = 0; i < kAtlasCount; ++i) {
         delete fAtlasMgr[i];
         fAtlasMgr[i] = NULL;
     }
@@ -177,7 +189,7 @@
 #ifdef SK_DEVELOPER
 void GrFontCache::dump() const {
     static int gDumpCount = 0;
-    for (int i = 0; i < kMaskFormatCount; ++i) {
+    for (int i = 0; i < kAtlasCount; ++i) {
         if (NULL != fAtlasMgr[i]) {
             GrTexture* texture = fAtlasMgr[i]->getTexture();
             if (NULL != texture) {
diff --git a/src/gpu/GrTextStrike.h b/src/gpu/GrTextStrike.h
index 422ae0c..c5a3f65 100644
--- a/src/gpu/GrTextStrike.h
+++ b/src/gpu/GrTextStrike.h
@@ -108,6 +108,15 @@
     void dump() const;
 #endif
 
+    enum AtlasType {
+        kA8_AtlasType,   //!< 1-byte per pixel
+        k565_AtlasType,  //!< 2-bytes per pixel
+        k8888_AtlasType, //!< 4-bytes per pixel
+
+        kLast_AtlasType = k8888_AtlasType
+    };
+    static const int kAtlasCount = kLast_AtlasType + 1;
+
 private:
     friend class GrFontPurgeListener;
 
@@ -118,7 +127,7 @@
     GrTextStrike* fTail;
 
     GrGpu*      fGpu;
-    GrAtlasMgr* fAtlasMgr[kMaskFormatCount];
+    GrAtlasMgr* fAtlasMgr[kAtlasCount];
 
     GrTextStrike* generateStrike(GrFontScaler*, const Key&);
     inline void detachStrikeFromList(GrTextStrike*);
diff --git a/src/gpu/SkGrFontScaler.cpp b/src/gpu/SkGrFontScaler.cpp
index 1ca9357..8fdae48 100644
--- a/src/gpu/SkGrFontScaler.cpp
+++ b/src/gpu/SkGrFontScaler.cpp
@@ -85,10 +85,10 @@
             return kA8_GrMaskFormat;
         case SkMask::kLCD16_Format:
             return kA565_GrMaskFormat;
-        // TODO: properly support kARGB32_Format.
-        case SkMask::kARGB32_Format:
         case SkMask::kLCD32_Format:
             return kA888_GrMaskFormat;
+        case SkMask::kARGB32_Format:
+            return kARGB_GrMaskFormat;
         default:
             SkDEBUGFAIL("unsupported SkMask::Format");
             return kA8_GrMaskFormat;
@@ -174,8 +174,8 @@
                 expand_bits(rgba8888, bits, width, height, dstRB, srcRB);
                 break;
             }
-           default:
-             GrCrash("Unknown GrMaskFormat");
+            default:
+                GrCrash("Invalid GrMaskFormat");
         }
     } else if (srcRB == dstRB) {
         memcpy(dst, src, dstRB * height);