Add GPU support for color bitmap fonts
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 3 Dec 2013 19:45:22 +0000 (19:45 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 3 Dec 2013 19:45:22 +0000 (19:45 +0000)
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

expectations/gm/ignored-tests.txt
include/gpu/GrTypes.h
src/gpu/GrBitmapTextContext.cpp
src/gpu/GrTextStrike.cpp
src/gpu/GrTextStrike.h
src/gpu/SkGrFontScaler.cpp

index 234e9fe..8d89cbc 100644 (file)
@@ -61,4 +61,7 @@ filterbitmap_checkerboard_4_4
 downsamplebitmap_text_high_72.00pt
 filterbitmap_text_3.00pt
 filterbitmap_text_7.00pt
-filterbitmap_text_10.00pt
\ No newline at end of file
+filterbitmap_text_10.00pt
+
+# Added by jvanverth in https://codereview.chromium.org/99993002/
+colortype_gpu
index ff8f442..67dcf51 100644 (file)
@@ -238,8 +238,9 @@ enum GrMaskFormat {
     kA8_GrMaskFormat,    //!< 1-byte per pixel
     kA565_GrMaskFormat,  //!< 2-bytes per pixel
     kA888_GrMaskFormat,  //!< 4-bytes per pixel
+    kARGB_GrMaskFormat,  //!< 4-bytes per pixel, color format
 
-    kLast_GrMaskFormat = kA888_GrMaskFormat
+    kLast_GrMaskFormat = kARGB_GrMaskFormat
 };
 static const int kMaskFormatCount = kLast_GrMaskFormat + 1;
 
@@ -247,11 +248,15 @@ static const int kMaskFormatCount = kLast_GrMaskFormat + 1;
  *  Return the number of bytes-per-pixel for the specified mask format.
  */
 static inline int GrMaskFormatBytesPerPixel(GrMaskFormat format) {
-    SkASSERT((unsigned)format <= 2);
+    SkASSERT((unsigned)format <= 3);
     // kA8   (0) -> 1
     // kA565 (1) -> 2
     // kA888 (2) -> 4
-    return 1 << (int)format;
+    // kARGB (3) -> 4    
+    static const int sBytesPerPixel[] = { 1, 2, 4, 4 };
+    SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sBytesPerPixel) == kMaskFormatCount, array_size_mismatch);
+
+    return sBytesPerPixel[(int) format];
 }
 
 /**
index 8d955bb..a43c4a2 100755 (executable)
@@ -70,7 +70,10 @@ void GrBitmapTextContext::flushGlyphs() {
                                 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()) {
index ddab1e9..a4d3575 100644 (file)
@@ -28,7 +28,7 @@ static int g_PurgeCount = 0;
 
 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(GrGpu* gpu) : fGpu(gpu) {
 
 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 @@ GrFontCache::~GrFontCache() {
 }
 
 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 @@ GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler,
 
 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 @@ void GrFontCache::validate() const {
 #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) {
index 422ae0c..c5a3f65 100644 (file)
@@ -108,6 +108,15 @@ public:
     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 @@ private:
     GrTextStrike* fTail;
 
     GrGpu*      fGpu;
-    GrAtlasMgr* fAtlasMgr[kMaskFormatCount];
+    GrAtlasMgr* fAtlasMgr[kAtlasCount];
 
     GrTextStrike* generateStrike(GrFontScaler*, const Key&);
     inline void detachStrikeFromList(GrTextStrike*);
index 1ca9357..8fdae48 100644 (file)
@@ -85,10 +85,10 @@ GrMaskFormat SkGrFontScaler::getMaskFormat() {
             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 @@ bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
                 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);