Add Gray8 pixel config

This is still just linear (non-sRGB), but adding sRGB will
be the next step. I've verified that this is really making
R8 textures when uploading Gray8 bitmaps. Tests pass, and
the all_bitmap_configs GM still renders correctly (unlike
when we just mapped Gray8 to Alpha8).

This adds another pixel config, which could grow our cache
footprint, but the benefits of not using 4bpp for 1bpp data
should outweigh that?

BUG=skia:6110

Change-Id: I4fc4c2479fc25f1d278e174a9bb5b542a0cb184c
Reviewed-on: https://skia-review.googlesource.com/6817
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 0cc3346..2b18fac 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -170,6 +170,7 @@
     static const char* kConfigNames[] = {
         "Unknown",       // kUnknown_GrPixelConfig
         "Alpha8",        // kAlpha_8_GrPixelConfig,
+        "Gray8",         // kGray_8_GrPixelConfig,
         "Index8",        // kIndex_8_GrPixelConfig,
         "RGB565",        // kRGB_565_GrPixelConfig,
         "RGBA444",       // kRGBA_4444_GrPixelConfig,
@@ -188,21 +189,22 @@
     };
     GR_STATIC_ASSERT(0  == kUnknown_GrPixelConfig);
     GR_STATIC_ASSERT(1  == kAlpha_8_GrPixelConfig);
-    GR_STATIC_ASSERT(2  == kIndex_8_GrPixelConfig);
-    GR_STATIC_ASSERT(3  == kRGB_565_GrPixelConfig);
-    GR_STATIC_ASSERT(4  == kRGBA_4444_GrPixelConfig);
-    GR_STATIC_ASSERT(5  == kRGBA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(6  == kBGRA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(7  == kSRGBA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(8  == kSBGRA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(9  == kRGBA_8888_sint_GrPixelConfig);
-    GR_STATIC_ASSERT(10 == kETC1_GrPixelConfig);
-    GR_STATIC_ASSERT(11 == kLATC_GrPixelConfig);
-    GR_STATIC_ASSERT(12 == kR11_EAC_GrPixelConfig);
-    GR_STATIC_ASSERT(13 == kASTC_12x12_GrPixelConfig);
-    GR_STATIC_ASSERT(14 == kRGBA_float_GrPixelConfig);
-    GR_STATIC_ASSERT(15 == kAlpha_half_GrPixelConfig);
-    GR_STATIC_ASSERT(16 == kRGBA_half_GrPixelConfig);
+    GR_STATIC_ASSERT(2  == kGray_8_GrPixelConfig);
+    GR_STATIC_ASSERT(3  == kIndex_8_GrPixelConfig);
+    GR_STATIC_ASSERT(4  == kRGB_565_GrPixelConfig);
+    GR_STATIC_ASSERT(5  == kRGBA_4444_GrPixelConfig);
+    GR_STATIC_ASSERT(6  == kRGBA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(7  == kBGRA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(8  == kSRGBA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(9  == kSBGRA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(10 == kRGBA_8888_sint_GrPixelConfig);
+    GR_STATIC_ASSERT(11 == kETC1_GrPixelConfig);
+    GR_STATIC_ASSERT(12 == kLATC_GrPixelConfig);
+    GR_STATIC_ASSERT(13 == kR11_EAC_GrPixelConfig);
+    GR_STATIC_ASSERT(14 == kASTC_12x12_GrPixelConfig);
+    GR_STATIC_ASSERT(15 == kRGBA_float_GrPixelConfig);
+    GR_STATIC_ASSERT(16 == kAlpha_half_GrPixelConfig);
+    GR_STATIC_ASSERT(17 == kRGBA_half_GrPixelConfig);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt);
 
     SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig, false));
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 30f596f..fd8aba0 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -680,6 +680,7 @@
     static const GrPixelConfig kFallback[] = {
         kUnknown_GrPixelConfig,        // kUnknown_GrPixelConfig
         kRGBA_8888_GrPixelConfig,      // kAlpha_8_GrPixelConfig
+        kUnknown_GrPixelConfig,        // kGray_8_GrPixelConfig
         kUnknown_GrPixelConfig,        // kIndex_8_GrPixelConfig
         kRGBA_8888_GrPixelConfig,      // kRGB_565_GrPixelConfig
         kRGBA_8888_GrPixelConfig,      // kRGBA_4444_GrPixelConfig
@@ -700,21 +701,22 @@
 
     GR_STATIC_ASSERT(0  == kUnknown_GrPixelConfig);
     GR_STATIC_ASSERT(1  == kAlpha_8_GrPixelConfig);
-    GR_STATIC_ASSERT(2  == kIndex_8_GrPixelConfig);
-    GR_STATIC_ASSERT(3  == kRGB_565_GrPixelConfig);
-    GR_STATIC_ASSERT(4  == kRGBA_4444_GrPixelConfig);
-    GR_STATIC_ASSERT(5  == kRGBA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(6  == kBGRA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(7  == kSRGBA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(8  == kSBGRA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(9  == kRGBA_8888_sint_GrPixelConfig);
-    GR_STATIC_ASSERT(10 == kETC1_GrPixelConfig);
-    GR_STATIC_ASSERT(11 == kLATC_GrPixelConfig);
-    GR_STATIC_ASSERT(12 == kR11_EAC_GrPixelConfig);
-    GR_STATIC_ASSERT(13 == kASTC_12x12_GrPixelConfig);
-    GR_STATIC_ASSERT(14 == kRGBA_float_GrPixelConfig);
-    GR_STATIC_ASSERT(15 == kAlpha_half_GrPixelConfig);
-    GR_STATIC_ASSERT(16 == kRGBA_half_GrPixelConfig);
+    GR_STATIC_ASSERT(2  == kGray_8_GrPixelConfig);
+    GR_STATIC_ASSERT(3  == kIndex_8_GrPixelConfig);
+    GR_STATIC_ASSERT(4  == kRGB_565_GrPixelConfig);
+    GR_STATIC_ASSERT(5  == kRGBA_4444_GrPixelConfig);
+    GR_STATIC_ASSERT(6  == kRGBA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(7  == kBGRA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(8  == kSRGBA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(9  == kSBGRA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(10 == kRGBA_8888_sint_GrPixelConfig);
+    GR_STATIC_ASSERT(11 == kETC1_GrPixelConfig);
+    GR_STATIC_ASSERT(12 == kLATC_GrPixelConfig);
+    GR_STATIC_ASSERT(13 == kR11_EAC_GrPixelConfig);
+    GR_STATIC_ASSERT(14 == kASTC_12x12_GrPixelConfig);
+    GR_STATIC_ASSERT(15 == kRGBA_float_GrPixelConfig);
+    GR_STATIC_ASSERT(16 == kAlpha_half_GrPixelConfig);
+    GR_STATIC_ASSERT(17 == kRGBA_half_GrPixelConfig);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kFallback) == kGrPixelConfigCnt);
 }
 
diff --git a/src/gpu/GrShaderCaps.cpp b/src/gpu/GrShaderCaps.cpp
index 3e6323f..90df176 100644
--- a/src/gpu/GrShaderCaps.cpp
+++ b/src/gpu/GrShaderCaps.cpp
@@ -202,6 +202,7 @@
         uint8_t* table = fSamplerPrecisions[visibility];
         table[kUnknown_GrPixelConfig]        = kDefault_GrSLPrecision;
         table[kAlpha_8_GrPixelConfig]        = lowp;
+        table[kGray_8_GrPixelConfig]         = lowp;
         table[kIndex_8_GrPixelConfig]        = lowp;
         table[kRGB_565_GrPixelConfig]        = lowp;
         table[kRGBA_4444_GrPixelConfig]      = lowp;
@@ -218,7 +219,7 @@
         table[kAlpha_half_GrPixelConfig]     = mediump;
         table[kRGBA_half_GrPixelConfig]      = mediump;
 
-        GR_STATIC_ASSERT(17 == kGrPixelConfigCnt);
+        GR_STATIC_ASSERT(18 == kGrPixelConfigCnt);
     }
 }
 
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 4147855..9d6072c 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -253,25 +253,6 @@
         pmap = &tmpPixmap;
         // must rebuild desc, since we've forced the info to be N32
         desc = GrImageInfoToSurfaceDesc(pmap->info(), *caps);
-    } else if (kGray_8_SkColorType == pixmap.colorType()) {
-        // We don't have Gray8 support as a pixel config, so expand to 8888
-
-        // We should have converted sRGB Gray8 above (if we have sRGB support):
-        SkASSERT(!caps->srgbSupport() || !pixmap.info().colorSpace() ||
-                 !pixmap.info().colorSpace()->gammaCloseToSRGB());
-
-        SkImageInfo info = SkImageInfo::MakeN32(pixmap.width(), pixmap.height(),
-                                                kOpaque_SkAlphaType);
-        tmpBitmap.allocPixels(info);
-        if (!pixmap.readPixels(info, tmpBitmap.getPixels(), tmpBitmap.rowBytes())) {
-            return nullptr;
-        }
-        if (!tmpBitmap.peekPixels(&tmpPixmap)) {
-            return nullptr;
-        }
-        pmap = &tmpPixmap;
-        // must rebuild desc, since we've forced the info to be N32
-        desc = GrImageInfoToSurfaceDesc(pmap->info(), *caps);
     } else if (kIndex_8_SkColorType == pixmap.colorType()) {
         if (caps->isConfigTexturable(kIndex_8_GrPixelConfig)) {
             size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig,
@@ -482,7 +463,7 @@
         case kIndex_8_SkColorType:
             return kIndex_8_GrPixelConfig;
         case kGray_8_SkColorType:
-            return kAlpha_8_GrPixelConfig; // TODO: gray8 support on gpu
+            return kGray_8_GrPixelConfig;
         case kRGBA_F16_SkColorType:
             return kRGBA_half_GrPixelConfig;
     }
@@ -496,6 +477,9 @@
         case kAlpha_8_GrPixelConfig:
             ct = kAlpha_8_SkColorType;
             break;
+        case kGray_8_GrPixelConfig:
+            ct = kGray_8_SkColorType;
+            break;
         case kIndex_8_GrPixelConfig:
             ct = kIndex_8_SkColorType;
             break;
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index d3adc28..bd9380c 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -1756,6 +1756,39 @@
         fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
     }
 
+    if (this->textureRedSupport()) {
+        fConfigTable[kGray_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RED;
+        fConfigTable[kGray_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_R8;
+        fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+            GR_GL_RED;
+        fConfigTable[kGray_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRA();
+        if (texelBufferSupport) {
+            fConfigTable[kGray_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag;
+        }
+    } else {
+        fConfigTable[kGray_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_LUMINANCE;
+        fConfigTable[kGray_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_LUMINANCE8;
+        fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+            GR_GL_LUMINANCE;
+        fConfigTable[kGray_8_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
+    }
+    fConfigTable[kGray_8_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
+    fConfigTable[kGray_8_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
+    fConfigTable[kGray_8_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
+#if 0 // Leaving Gray8 as non-renderable, to keep things simple and match raster
+    if (this->textureRedSupport() ||
+        (kDesktop_ARB_MSFBOType == this->msFBOType() &&
+         ctxInfo.renderer() != kOSMesa_GrGLRenderer)) {
+        // desktop ARB extension/3.0+ supports LUMINANCE8 as renderable.
+        // However, osmesa fails if it used even when GL_ARB_framebuffer_object is present.
+        // Core profile removes LUMINANCE8 support, but we should have chosen R8 in that case.
+        fConfigTable[kGray_8_GrPixelConfig].fFlags |= allRenderFlags;
+    }
+#endif
+    if (texStorageSupported) {
+        fConfigTable[kGray_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
+    }
+
     // Check for [half] floating point texture support
     // NOTE: We disallow floating point textures on ES devices if linear filtering modes are not
     // supported. This is for simplicity, but a more granular approach is possible. Coincidentally,
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index 18dee28..05a594e 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -461,6 +461,9 @@
 #define GR_GL_R32I                           0x8235
 #define GR_GL_R32UI                          0x8236
 
+/* Luminance sized formats */
+#define GR_GL_LUMINANCE8                     0x8040
+
 /* Alpha sized formats */
 #define GR_GL_ALPHA8                         0x803C
 #define GR_GL_ALPHA16                        0x803E
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 577aca8..74e5258 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -927,6 +927,7 @@
     SkASSERT(!GrPixelConfigIsCompressed(config));
     switch (config) {
         case kAlpha_8_GrPixelConfig:
+        case kGray_8_GrPixelConfig:
             return 1;
         case kRGB_565_GrPixelConfig:
         case kRGBA_4444_GrPixelConfig:
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index 3071fc8..b92f03e 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -48,6 +48,9 @@
         case kAlpha_8_GrPixelConfig:
             *format = VK_FORMAT_R8_UNORM;
             return true;
+        case kGray_8_GrPixelConfig:
+            *format = VK_FORMAT_R8_UNORM;
+            return true;
         case kETC1_GrPixelConfig:
             // converting to ETC2 which is a superset of ETC1
             *format = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;