Add kRG_1616 and kAlpha_16 SkColorTypes

This also switches GrColorType::kR_16 to kAlpha_16 to more closely match raster.

Bug: skia:9121
Change-Id: I03c6e6c52c90aa4223478c5ea6c8b2ed8558f677
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/239930
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index bdf986d..6a72f3f 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -92,8 +92,12 @@
     https://review.skia.org/238856
 
   * Added kRG_88_SkColorType. This is intended to help support YUV uses case (e.g., NV12).
-    As such, it the addition is focused on allowing creation of SkPixmaps and SkImages and not
+    As such, the addition is focused on allowing creation of SkPixmaps and SkImages and not
     SkSurfaces (i.e., who wants to render to RG?)
 
   * Add GrContext::precompileShader to allow up-front compilation of previously-cached shaders.
     https://review.skia.org/239438
+
+  * Added kAlpha_16_SkColorType and kRG_1616_SkColorType. This is intended to help support HDR YUV
+    uses case (e.g., P010 and P016). As such, the addition is focused on allowing creation of
+    SkPixmaps and SkImages and not SkSurfaces (i.e., who wants to render to render to these?)
diff --git a/gm/bitmapcopy.cpp b/gm/bitmapcopy.cpp
index be6ab85..c1806d3 100644
--- a/gm/bitmapcopy.cpp
+++ b/gm/bitmapcopy.cpp
@@ -41,6 +41,8 @@
         case kRGBA_F16_SkColorType:     return "F16";
         case kRGBA_F32_SkColorType:     return "F32";
         case kRG_88_SkColorType:        return "RG88";
+        case kAlpha_16_SkColorType:     return "A16";
+        case kRG_1616_SkColorType:      return "RG1616";
     }
     return "";
 }
diff --git a/gm/wacky_yuv_formats.cpp b/gm/wacky_yuv_formats.cpp
index d2f1983..5f22dbc 100644
--- a/gm/wacky_yuv_formats.cpp
+++ b/gm/wacky_yuv_formats.cpp
@@ -100,11 +100,7 @@
 }
 
 static bool format_cant_be_represented_with_pixmaps(YUVFormat yuvFormat) {
-    return kP016_YUVFormat == yuvFormat ||      // bc missing SkColorType::kRG_1616 and kR_16
-           kP010_YUVFormat == yuvFormat ||      // bc missing SkColorType::kRG_1616 and kR_16
-           kY416_YUVFormat == yuvFormat ||      // bc missing SkColorType::kRGBA_16161616
-           kNV12_YUVFormat == yuvFormat ||      // bc missing SkColorType::kRG_88
-           kNV21_YUVFormat == yuvFormat;        // bc missing SkColorType::kRG_88
+    return kY416_YUVFormat == yuvFormat;        // bc missing SkColorType::kRGBA_16161616
 }
 
 // Helper to setup the SkYUVAIndex array correctly
@@ -116,14 +112,14 @@
         case kP016_YUVFormat: // fall through
         case kP010_YUVFormat:
             yuvaIndices[0].fIndex = 0;
-            yuvaIndices[0].fChannel = SkColorChannel::kR; // bc 16bit is stored in R16 format
+            yuvaIndices[0].fChannel = SkColorChannel::kA; // bc 16bit is stored in A16 format
             yuvaIndices[1].fIndex = 1;
             yuvaIndices[1].fChannel = SkColorChannel::kR;
             yuvaIndices[2].fIndex = 1;
             yuvaIndices[2].fChannel = SkColorChannel::kG;
             if (addExtraAlpha) {
                 yuvaIndices[3].fIndex = 2;
-                yuvaIndices[3].fChannel = SkColorChannel::kR; // bc 16bit is stored in R16 format
+                yuvaIndices[3].fChannel = SkColorChannel::kA; // bc 16bit is stored in A16 format
             } else {
                 yuvaIndices[3].fIndex = -1; // No alpha channel
             }
@@ -228,6 +224,9 @@
    SkBitmap fAFull;
    SkBitmap fUQuarter; // 2x2 downsampled U channel
    SkBitmap fVQuarter; // 2x2 downsampled V channel
+
+   SkBitmap fFull;
+   SkBitmap fQuarter; // 2x2 downsampled YUVA
 };
 
 // Add a portion of a circle to 'path'. The points 'o1' and 'o2' are on the border of the circle
@@ -480,6 +479,12 @@
     planes->fVQuarter.allocPixels(SkImageInfo::Make(bm.width()/2, bm.height()/2,
                                   kGray_8_SkColorType, kUnpremul_SkAlphaType));
 
+    planes->fFull.allocPixels(SkImageInfo::Make(bm.width(), bm.height(),
+                              kRGBA_F32_SkColorType, kUnpremul_SkAlphaType));
+    planes->fQuarter.allocPixels(SkImageInfo::Make(bm.width()/2, bm.height()/2,
+                                 kRGBA_F32_SkColorType, kUnpremul_SkAlphaType));
+
+    SkColor4f* dst = (SkColor4f *) planes->fFull.getAddr(0, 0);
     for (int y = 0; y < bm.height(); ++y) {
         for (int x = 0; x < bm.width(); ++x) {
             SkColor col = bm.getColor(x, y);
@@ -499,12 +504,25 @@
             *planes->fUFull.getAddr8(x, y) = yuva[1];
             *planes->fVFull.getAddr8(x, y) = yuva[2];
             *planes->fAFull.getAddr8(x, y) = yuva[3];
+
+            // TODO: render in F32 rather than converting here
+            dst->fR = yuva[0] / 255.0f;
+            dst->fG = yuva[1] / 255.0f;
+            dst->fB = yuva[2] / 255.0f;
+            dst->fA = yuva[3] / 255.0f;
+            ++dst;
         }
     }
 
+    dst = (SkColor4f *) planes->fQuarter.getAddr(0, 0);
     for (int y = 0; y < bm.height()/2; ++y) {
         for (int x = 0; x < bm.width()/2; ++x) {
-            uint32_t uAccum = 0, vAccum = 0;
+            uint32_t yAccum = 0, uAccum = 0, vAccum = 0, aAccum = 0;
+
+            yAccum += *planes->fYFull.getAddr8(2*x, 2*y);
+            yAccum += *planes->fYFull.getAddr8(2*x+1, 2*y);
+            yAccum += *planes->fYFull.getAddr8(2*x, 2*y+1);
+            yAccum += *planes->fYFull.getAddr8(2*x+1, 2*y+1);
 
             uAccum += *planes->fUFull.getAddr8(2*x, 2*y);
             uAccum += *planes->fUFull.getAddr8(2*x+1, 2*y);
@@ -519,12 +537,24 @@
             vAccum += *planes->fVFull.getAddr8(2*x+1, 2*y+1);
 
             *planes->fVQuarter.getAddr8(x, y) = vAccum / 4.0f;
+
+            aAccum += *planes->fAFull.getAddr8(2*x, 2*y);
+            aAccum += *planes->fAFull.getAddr8(2*x+1, 2*y);
+            aAccum += *planes->fAFull.getAddr8(2*x, 2*y+1);
+            aAccum += *planes->fAFull.getAddr8(2*x+1, 2*y+1);
+
+            // TODO: render in F32 rather than converting here
+            dst->fR = yAccum / (4.0f * 255.0f);
+            dst->fG = uAccum / (4.0f * 255.0f);
+            dst->fB = vAccum / (4.0f * 255.0f);
+            dst->fA = aAccum / (4.0f * 255.0f);
+            ++dst;
         }
     }
 }
 
 // Create a 2x2 downsampled SkBitmap. It is stored in an RG texture. It can optionally be
-// uv (i.e., for P016, P010 and NV12) or vu (i.e., NV21).
+// uv (i.e., NV12) or vu (i.e., NV21).
 static SkBitmap make_quarter_2_channel(const SkBitmap& fullY,
                                        const SkBitmap& quarterU,
                                        const SkBitmap& quarterV,
@@ -552,6 +582,65 @@
     return result;
 }
 
+// Extract one channel of 'src' into a single channel 16 bit result. Optionally, set
+// the lower 6 bits to 0 for the 10bpp formats (i.e., P010).
+static SkBitmap make_single_channel_16(const SkBitmap& src, int channel, bool tenBitsPP) {
+    SkASSERT(0 <= channel && channel <= 3);
+    SkASSERT(src.colorType() == kRGBA_F32_SkColorType);
+
+    SkBitmap result;
+
+    result.allocPixels(SkImageInfo::Make(src.width(), src.height(),
+                                         kAlpha_16_SkColorType,
+                                         kUnpremul_SkAlphaType));
+
+    const float* pixels = (const float*) src.getAddr(0, 0);
+    for (int y = 0; y < src.height(); ++y) {
+        for (int x = 0; x < src.width(); ++x) {
+            uint32_t val16 = SkScalarRoundToInt(pixels[channel] * 65535.0f);
+
+            if (tenBitsPP) {
+                val16 &= 0xFFC0;
+            }
+
+            *result.getAddr16(x, y) = val16;
+            pixels += 4;
+        }
+    }
+
+    return result;
+}
+
+// Extract the green and blue channels from src into an 16bit per channel
+// RG texture.
+static SkBitmap make_two_channel_16(const SkBitmap& src, bool tenBitsPP) {
+    SkASSERT(src.colorType() == kRGBA_F32_SkColorType);
+
+    SkBitmap result;
+
+    result.allocPixels(SkImageInfo::Make(src.width(), src.height(),
+                                         kRG_1616_SkColorType,
+                                         kUnpremul_SkAlphaType));
+
+    float* pixels = (float*) src.getAddr(0, 0);
+    for (int y = 0; y < src.height(); ++y) {
+        for (int x = 0; x < src.width(); ++x) {
+            uint32_t u16 = SkScalarRoundToInt(pixels[1] * 65535.0f);
+            uint32_t v16 = SkScalarRoundToInt(pixels[2] * 65535.0f);
+
+            if (tenBitsPP) {
+                u16 &= 0xFFC0;
+                v16 &= 0xFFC0;
+            }
+
+            *result.getAddr32(x, y) = (v16 << 16) | u16;
+            pixels += 4;
+        }
+    }
+
+    return result;
+}
+
 // Recombine the separate planes into some YUV format
 static void create_YUV(const PlaneData& planes, YUVFormat yuvFormat,
                        SkBitmap resultBMs[], SkYUVAIndex yuvaIndices[4], bool opaque) {
@@ -640,7 +729,19 @@
             break;
         }
         case kP016_YUVFormat:     // fall through
-        case kP010_YUVFormat:     // fall through
+        case kP010_YUVFormat: {
+            resultBMs[nextLayer++] = make_single_channel_16(planes.fFull, 0,
+                                                            yuvFormat == kP010_YUVFormat);
+            resultBMs[nextLayer++] = make_two_channel_16(planes.fQuarter,
+                                                         yuvFormat == kP010_YUVFormat);
+
+            if (!opaque) {
+                resultBMs[nextLayer] = make_single_channel_16(planes.fFull, 3,
+                                                              yuvFormat == kP010_YUVFormat);
+            }
+            setup_yuv_indices(yuvFormat, !opaque, yuvaIndices);
+            return;
+        }
         case kNV12_YUVFormat: {
             SkBitmap uvQuarter = make_quarter_2_channel(planes.fYFull,
                                                         planes.fUQuarter,
@@ -693,7 +794,10 @@
     if (kAlpha_8_SkColorType == bm.colorType() || kGray_8_SkColorType == bm.colorType()) {
         SkASSERT(SkColorChannel::kA == channel || SkColorChannel::kR == channel);
         result = *bm.getAddr8(x, y);
-    } else if (kRG_88_SkColorType == bm.colorType()) {
+    } else if (kAlpha_16_SkColorType == bm.colorType()) {
+        SkASSERT(SkColorChannel::kA == channel);
+        result = (*bm.getAddr16(x, y) >> 8);
+    } else if (kRG_88_SkColorType == bm.colorType() || kRG_1616_SkColorType == bm.colorType()) {
         SkASSERT(SkColorChannel::kR == channel || SkColorChannel::kG == channel);
         SkColor c = bm.getColor(x, y);
 
@@ -931,40 +1035,6 @@
     canvas->drawString(rowLabel, 0, y, font, paint);
 }
 
-static void make_RG_1616(const GrCaps* caps,
-                         const SkBitmap& bm, YUVFormat yuvFormat,
-                         SkAutoTMalloc<uint8_t>* pixels,
-                         GrBackendFormat* format, size_t* rowBytes) {
-    SkASSERT(kP016_YUVFormat == yuvFormat || kP010_YUVFormat == yuvFormat);
-    SkASSERT(kRG_88_SkColorType == bm.colorType());     // uv stored in rg
-
-    uint16_t u16, v16;
-    *rowBytes = bm.width() * 2 * sizeof(uint16_t);
-    pixels->reset(*rowBytes * bm.height());
-    uint16_t* currPixel = (uint16_t*) pixels->get();
-    for (int y = 0; y < bm.height(); ++y) {
-        for (int x = 0; x < bm.width(); ++x) {
-            SkColor color = bm.getColor(x, y);
-
-            if (kP016_YUVFormat == yuvFormat) {
-                u16 = SkScalarRoundToInt((SkColorGetR(color) / 255.0f) * 65535.0f);
-                v16 = SkScalarRoundToInt((SkColorGetG(color) / 255.0f) * 65535.0f);
-            } else {
-                u16 = SkScalarRoundToInt((SkColorGetR(color) / 255.0f) * 1023.0f);
-                v16 = SkScalarRoundToInt((SkColorGetG(color) / 255.0f) * 1023.0f);
-                u16 <<= 6;
-                v16 <<= 6;
-            }
-
-            currPixel[0] = u16;
-            currPixel[1] = v16;
-            currPixel += 2;
-        }
-    }
-
-    *format = caps->getDefaultBackendFormat(GrColorType::kRG_1616, GrRenderable::kNo);
-}
-
 static void make_RGBA_16(const GrCaps* caps,
                          const SkBitmap& bm,
                          YUVFormat yuvFormat,
@@ -999,38 +1069,6 @@
     return;
 }
 
-static void make_R_16(const GrCaps* caps,
-                      const SkBitmap& bm,
-                      YUVFormat yuvFormat,
-                      SkAutoTMalloc<uint8_t>* pixels,
-                      GrBackendFormat* format,
-                      size_t* rowBytes) {
-    SkASSERT(kP016_YUVFormat == yuvFormat || kP010_YUVFormat == yuvFormat);
-    SkASSERT(kGray_8_SkColorType == bm.colorType() || kAlpha_8_SkColorType == bm.colorType());
-
-    uint16_t y16;
-    *rowBytes = sizeof(uint16_t) * bm.width();
-    pixels->reset(*rowBytes * bm.height());
-    uint16_t* currPixel = (uint16_t*) pixels->get();
-    for (int y = 0; y < bm.height(); ++y) {
-        for (int x = 0; x < bm.width(); ++x) {
-            uint8_t y8 = *bm.getAddr8(x, y);
-
-            if (kP016_YUVFormat == yuvFormat) {
-                y16 = SkScalarRoundToInt((y8 / 255.0f) * 65535.0f);
-            } else {
-                y16 = SkScalarRoundToInt((y8 / 255.0f) * 1023.0f);
-                y16 <<= 6;
-            }
-
-            currPixel[0] = y16;
-            currPixel += 1;
-        }
-    }
-
-    *format = caps->getDefaultBackendFormat(GrColorType::kR_16, GrRenderable::kNo);
-}
-
 static GrBackendTexture create_yuva_texture(GrContext* context, const SkBitmap& bm,
                                             SkYUVAIndex yuvaIndices[4], int texIndex,
                                             YUVFormat yuvFormat) {
@@ -1043,17 +1081,12 @@
     }
 
     if (format_uses_16_bpp(yuvFormat) || 2 == channelCount) {
-        // Due to the limitations of SkPixmap these cases need to be handled separately
-        const GrCaps* caps = context->priv().caps();
-        GrGpu* gpu = context->priv().getGpu();
-
-        SkAutoTMalloc<uint8_t> pixels;
-        GrBackendFormat format;
-        size_t rowBytes;
-
         if (2 == channelCount) {
             if (format_uses_16_bpp(yuvFormat)) {
-                make_RG_1616(caps, bm, yuvFormat, &pixels, &format, &rowBytes);
+                SkASSERT(kRG_1616_SkColorType == bm.colorType());
+
+                return context->priv().createBackendTexture(&bm.pixmap(), 1,
+                                                            GrRenderable::kNo, GrProtected::kNo);
             } else {
                 SkASSERT(kRG_88_SkColorType == bm.colorType());
 
@@ -1062,17 +1095,28 @@
             }
         } else {
             if (kRGBA_8888_SkColorType == bm.colorType()) {
+                // Due to the limitations of SkPixmap these cases need to be handled separately
+                const GrCaps* caps = context->priv().caps();
+                GrGpu* gpu = context->priv().getGpu();
+
+                SkAutoTMalloc<uint8_t> pixels;
+                GrBackendFormat format;
+                size_t rowBytes;
+
                 make_RGBA_16(caps, bm, yuvFormat, &pixels, &format, &rowBytes);
+
+                // TODO: SkColorType needs to be expanded to allow RGBA_16 to be done
+                // via GrContext::createBackendTexture
+                return gpu->createBackendTexture(bm.width(), bm.height(), format,
+                                                 GrMipMapped::kNo, GrRenderable::kNo,
+                                                 pixels, rowBytes, nullptr, GrProtected::kNo);
             } else {
-                make_R_16(caps, bm, yuvFormat, &pixels, &format, &rowBytes);
+                SkASSERT(kAlpha_16_SkColorType == bm.colorType());
+
+                return context->priv().createBackendTexture(&bm.pixmap(), 1,
+                                                            GrRenderable::kNo, GrProtected::kNo);
             }
         }
-
-        // TODO: SkColorType needs to be expanded to allow RG_1616, RGBA_16 and R_16 to be done
-        // via GrContext::createBackendTexture
-        return gpu->createBackendTexture(bm.width(), bm.height(), format,
-                                         GrMipMapped::kNo, GrRenderable::kNo,
-                                         pixels, rowBytes, nullptr, GrProtected::kNo);
     }
 
     return context->priv().createBackendTexture(&bm.pixmap(), 1,
diff --git a/include/core/SkImageInfo.h b/include/core/SkImageInfo.h
index b7e3353..9652a8a 100644
--- a/include/core/SkImageInfo.h
+++ b/include/core/SkImageInfo.h
@@ -86,7 +86,9 @@
     kRGBA_F16_SkColorType,     //!< pixel with half floats for red, green, blue, alpha; in 64-bit word
     kRGBA_F32_SkColorType,     //!< pixel using C float for red, green, blue, alpha; in 128-bit word
     kRG_88_SkColorType,        //<! pixel with 8 bits each for red, green; in 16-bit word
-    kLastEnum_SkColorType     = kRG_88_SkColorType,//!< last valid value
+    kAlpha_16_SkColorType,     //<! pixel with alpha in 16-bits
+    kRG_1616_SkColorType,      //<! pixel with 16 bits each for red, green; in 32-bit word
+    kLastEnum_SkColorType     = kRG_1616_SkColorType, //!< last valid value
 
 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
     kN32_SkColorType          = kBGRA_8888_SkColorType,//!< native ARGB 32-bit encoding
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 8b5c788..fb1fd46 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -247,7 +247,10 @@
      * use maxSurfaceSampleCountForColorType().
      */
     bool colorTypeSupportedAsSurface(SkColorType colorType) const {
-        if (kRG_88_SkColorType == colorType) {
+        if (kRG_88_SkColorType == colorType ||
+            kRG_1616_SkColorType == colorType ||
+            kAlpha_16_SkColorType == colorType ||
+            kGray_8_SkColorType == colorType) {
             return false;
         }
 
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index 53ac706..cc36958 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -61,7 +61,7 @@
     kRGBA_half_GrPixelConfig,
     kRGBA_half_Clamped_GrPixelConfig,
     kRGB_ETC1_GrPixelConfig,
-    kR_16_GrPixelConfig,
+    kAlpha_16_GrPixelConfig,
     kRG_1616_GrPixelConfig,
 
     // Experimental (for Y416 and mutant P016/P010)
@@ -847,7 +847,7 @@
         case kAlpha_half_GrPixelConfig:
         case kAlpha_half_as_Lum_GrPixelConfig:
         case kAlpha_half_as_Red_GrPixelConfig:
-        case kR_16_GrPixelConfig:
+        case kAlpha_16_GrPixelConfig:
             return 2;
         case kRGBA_8888_GrPixelConfig:
         case kRGB_888_GrPixelConfig:  // Assuming GPUs store this 4-byte aligned.
@@ -885,13 +885,13 @@
         case kGray_8_as_Lum_GrPixelConfig:
         case kGray_8_as_Red_GrPixelConfig:
         case kRGB_ETC1_GrPixelConfig:
-        case kR_16_GrPixelConfig:
         case kRG_1616_GrPixelConfig:
         case kRG_half_GrPixelConfig: // Experimental (for mutant P016/P010)
             return true;
         case kAlpha_8_GrPixelConfig:
         case kAlpha_8_as_Alpha_GrPixelConfig:
         case kAlpha_8_as_Red_GrPixelConfig:
+        case kAlpha_16_GrPixelConfig:
         case kRGBA_4444_GrPixelConfig:
         case kAlpha_half_GrPixelConfig:
         case kAlpha_half_as_Lum_GrPixelConfig:
@@ -915,6 +915,7 @@
         case kAlpha_8_GrPixelConfig:
         case kAlpha_8_as_Alpha_GrPixelConfig:
         case kAlpha_8_as_Red_GrPixelConfig:
+        case kAlpha_16_GrPixelConfig:
         case kAlpha_half_GrPixelConfig:
         case kAlpha_half_as_Lum_GrPixelConfig:
         case kAlpha_half_as_Red_GrPixelConfig:
@@ -936,7 +937,6 @@
         case kRGBA_half_GrPixelConfig:
         case kRGBA_half_Clamped_GrPixelConfig:
         case kRGB_ETC1_GrPixelConfig:
-        case kR_16_GrPixelConfig:
         case kRG_1616_GrPixelConfig:
         // Experimental (for Y416 and mutant P016/P010)
         case kRGBA_16161616_GrPixelConfig:
@@ -965,7 +965,7 @@
         case kSRGBA_8888_GrPixelConfig:
         case kRGBA_1010102_GrPixelConfig:
         case kRGB_ETC1_GrPixelConfig:
-        case kR_16_GrPixelConfig:
+        case kAlpha_16_GrPixelConfig:
         case kRG_1616_GrPixelConfig:
         case kRGBA_16161616_GrPixelConfig: // Experimental (for Y416)
             return false;
@@ -1056,8 +1056,8 @@
     kAlpha_F32xxx,
     kGray_8xxx,
 
-    kR_16,          // Not in SkColorType
-    kRG_1616,       // Not in SkColorType
+    kAlpha_16,
+    kRG_1616,
 
     // Experimental (for Y416 and mutant P016/P010)
     kRGBA_16161616, // Not in SkColorType
@@ -1089,8 +1089,8 @@
         case GrColorType::kAlpha_8xxx:       return kUnknown_SkColorType;
         case GrColorType::kAlpha_F32xxx:     return kUnknown_SkColorType;
         case GrColorType::kGray_8xxx:        return kUnknown_SkColorType;
-        case GrColorType::kR_16:             return kUnknown_SkColorType;
-        case GrColorType::kRG_1616:          return kUnknown_SkColorType;
+        case GrColorType::kAlpha_16:         return kAlpha_16_SkColorType;
+        case GrColorType::kRG_1616:          return kRG_1616_SkColorType;
         // Experimental (for Y416 and mutant P016/P010)
         case GrColorType::kRGBA_16161616:    return kUnknown_SkColorType;
         case GrColorType::kRG_F16:           return kUnknown_SkColorType;
@@ -1114,6 +1114,8 @@
         case kRGB_101010x_SkColorType:  return GrColorType::kUnknown;
         case kRGBA_F32_SkColorType:     return GrColorType::kRGBA_F32;
         case kRG_88_SkColorType:        return GrColorType::kRG_88;
+        case kAlpha_16_SkColorType:     return GrColorType::kAlpha_16;
+        case kRG_1616_SkColorType:      return GrColorType::kRG_1616;
     }
     SkUNREACHABLE;
 }
@@ -1145,7 +1147,7 @@
         case GrColorType::kAlpha_8xxx:       return kAlpha_SkColorTypeComponentFlag;
         case GrColorType::kAlpha_F32xxx:     return kAlpha_SkColorTypeComponentFlag;
         case GrColorType::kGray_8xxx:        return kGray_SkColorTypeComponentFlag;
-        case GrColorType::kR_16:             return kRed_SkColorTypeComponentFlag;
+        case GrColorType::kAlpha_16:         return kAlpha_SkColorTypeComponentFlag;
         case GrColorType::kRG_1616:          return kRed_SkColorTypeComponentFlag |
                                                     kGreen_SkColorTypeComponentFlag;
         // Experimental (for Y416 and mutant P016/P010)
@@ -1283,8 +1285,8 @@
             return GrColorTypeDesc::MakeAlpha(32, GrColorTypeEncoding::kFloat);
         case GrColorType::kGray_8xxx:
             return GrColorTypeDesc::MakeGray(8, GrColorTypeEncoding::kUnorm);
-        case GrColorType::kR_16:
-            return GrColorTypeDesc::MakeR(16, GrColorTypeEncoding::kUnorm);
+        case GrColorType::kAlpha_16:
+            return GrColorTypeDesc::MakeAlpha(16, GrColorTypeEncoding::kUnorm);
         case GrColorType::kRG_1616:
             return GrColorTypeDesc::MakeRG(16, GrColorTypeEncoding::kUnorm);
         case GrColorType::kRGBA_16161616:
@@ -1343,7 +1345,7 @@
         case GrColorType::kAlpha_8xxx:       return 4;
         case GrColorType::kAlpha_F32xxx:     return 16;
         case GrColorType::kGray_8xxx:        return 4;
-        case GrColorType::kR_16:             return 2;
+        case GrColorType::kAlpha_16:         return 2;
         case GrColorType::kRG_1616:          return 4;
         // Experimental (for Y416 and mutant P016/P010)
         case GrColorType::kRGBA_16161616:    return 8;
@@ -1401,8 +1403,8 @@
             return GrColorType::kGray_8;
         case kGray_8_as_Red_GrPixelConfig:
             return GrColorType::kGray_8;
-        case kR_16_GrPixelConfig:
-            return GrColorType::kR_16;
+        case kAlpha_16_GrPixelConfig:
+            return GrColorType::kAlpha_16;
         case kRG_1616_GrPixelConfig:
             return GrColorType::kRG_1616;
 
@@ -1435,7 +1437,7 @@
         case GrColorType::kAlpha_8xxx:       return kUnknown_GrPixelConfig;
         case GrColorType::kAlpha_F32xxx:     return kUnknown_GrPixelConfig;
         case GrColorType::kGray_8xxx:        return kUnknown_GrPixelConfig;
-        case GrColorType::kR_16:             return kR_16_GrPixelConfig;
+        case GrColorType::kAlpha_16:         return kAlpha_16_GrPixelConfig;
         case GrColorType::kRG_1616:          return kRG_1616_GrPixelConfig;
 
         // Experimental (for Y416 and mutant P016/P010)
@@ -1502,7 +1504,7 @@
         case kRGBA_half_GrPixelConfig:         return "RGBAHalf";
         case kRGBA_half_Clamped_GrPixelConfig: return "RGBAHalfClamped";
         case kRGB_ETC1_GrPixelConfig:          return "RGBETC1";
-        case kR_16_GrPixelConfig:              return "R16";
+        case kAlpha_16_GrPixelConfig:          return "Alpha16";
         case kRG_1616_GrPixelConfig:           return "RG1616";
         case kRGBA_16161616_GrPixelConfig:     return "RGBA16161616";
         case kRG_half_GrPixelConfig:           return "RGHalf";
@@ -1530,7 +1532,7 @@
         case GrColorType::kAlpha_8xxx:       return "kAlpha_8xxx";
         case GrColorType::kAlpha_F32xxx:     return "kAlpha_F32xxx";
         case GrColorType::kGray_8xxx:        return "kGray_8xxx";
-        case GrColorType::kR_16:             return "kR_16";
+        case GrColorType::kAlpha_16:         return "kAlpha_16";
         case GrColorType::kRG_1616:          return "kRG_1616";
         case GrColorType::kRGBA_16161616:    return "kRGBA_16161616";
         case GrColorType::kRG_F16:           return "kRG_F16";
diff --git a/include/private/SkImageInfoPriv.h b/include/private/SkImageInfoPriv.h
index 5c9e52e..8362df1 100644
--- a/include/private/SkImageInfoPriv.h
+++ b/include/private/SkImageInfoPriv.h
@@ -41,6 +41,8 @@
         case kRGBA_F16_SkColorType:         return kRGBA_SkColorTypeComponentFlags;
         case kRGBA_F32_SkColorType:         return kRGBA_SkColorTypeComponentFlags;
         case kRG_88_SkColorType:            return kRG_SkColorTypeComponentFlags;
+        case kAlpha_16_SkColorType:         return kAlpha_SkColorTypeComponentFlag;
+        case kRG_1616_SkColorType:          return kRG_SkColorTypeComponentFlags;
     }
     SkUNREACHABLE;
 }
@@ -76,6 +78,8 @@
         case kRGBA_F16_SkColorType:         return 3;
         case kRGBA_F32_SkColorType:         return 4;
         case kRG_88_SkColorType:            return 1;
+        case kAlpha_16_SkColorType:         return 1;
+        case kRG_1616_SkColorType:          return 2;
     }
     SkUNREACHABLE;
 }
diff --git a/modules/canvaskit/canvaskit_bindings.cpp b/modules/canvaskit/canvaskit_bindings.cpp
index 37f1059..7750908 100644
--- a/modules/canvaskit/canvaskit_bindings.cpp
+++ b/modules/canvaskit/canvaskit_bindings.cpp
@@ -1259,7 +1259,9 @@
         .value("Gray_8", SkColorType::kGray_8_SkColorType)
         .value("RGBA_F16", SkColorType::kRGBA_F16_SkColorType)
         .value("RGBA_F32", SkColorType::kRGBA_F32_SkColorType)
-        .value("RG_88", SkColorType::kRG_88_SkColorType);
+        .value("RG_88", SkColorType::kRG_88_SkColorType)
+        .value("Alpha_16", SkColorType::kAlpha_16_SkColorType)
+        .value("RG_1616", SkColorType::kRG_1616_SkColorType);
 
     enum_<SkPath::FillType>("FillType")
         .value("Winding",           SkPath::FillType::kWinding_FillType)
diff --git a/src/core/SkConvertPixels.cpp b/src/core/SkConvertPixels.cpp
index 4a9a851..0745eb7 100644
--- a/src/core/SkConvertPixels.cpp
+++ b/src/core/SkConvertPixels.cpp
@@ -84,9 +84,22 @@
             return false;
         }
 
+        case kAlpha_16_SkColorType: {
+            auto src16 = (const uint16_t*) src;
+            for (int y = 0; y < srcInfo.height(); y++) {
+                for (int x = 0; x < srcInfo.width(); x++) {
+                    dst[x] = src16[x] >> 8;
+                }
+                dst = SkTAddOffset<uint8_t>(dst, dstRB);
+                src16 = SkTAddOffset<const uint16_t>(src16, srcRB);
+            }
+            return true;
+        }
+
         case kGray_8_SkColorType:
         case kRGB_565_SkColorType:
         case kRG_88_SkColorType:
+        case kRG_1616_SkColorType:
         case kRGB_888x_SkColorType:
         case kRGB_101010x_SkColorType: {
             for (int y = 0; y < srcInfo.height(); ++y) {
diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp
index 9287f9d..471b004 100644
--- a/src/core/SkImageInfo.cpp
+++ b/src/core/SkImageInfo.cpp
@@ -26,6 +26,8 @@
         case kRGBA_F16_SkColorType:     return 8;
         case kRGBA_F32_SkColorType:     return 16;
         case kRG_88_SkColorType:        return 2;
+        case kAlpha_16_SkColorType:     return 2;
+        case kRG_1616_SkColorType:      return 4;
     }
     SkUNREACHABLE;
 }
@@ -67,7 +69,8 @@
         case kUnknown_SkColorType:
             alphaType = kUnknown_SkAlphaType;
             break;
-        case kAlpha_8_SkColorType:
+        case kAlpha_8_SkColorType:         // fall-through
+        case kAlpha_16_SkColorType:
             if (kUnpremul_SkAlphaType == alphaType) {
                 alphaType = kPremul_SkAlphaType;
             }
@@ -85,6 +88,7 @@
             break;
         case kGray_8_SkColorType:
         case kRG_88_SkColorType:
+        case kRG_1616_SkColorType:
         case kRGB_565_SkColorType:
         case kRGB_888x_SkColorType:
         case kRGB_101010x_SkColorType:
diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp
index 6694659..a678950 100644
--- a/src/core/SkMipMap.cpp
+++ b/src/core/SkMipMap.cpp
@@ -78,6 +78,52 @@
     }
 };
 
+struct ColorTypeFilter_88 {
+    typedef uint16_t Type;
+    static uint32_t Expand(uint16_t x) {
+        return (x & 0xFF) | ((x & ~0xFF) << 8);
+    }
+    static uint16_t Compact(uint32_t x) {
+        return (x & 0xFF) | ((x >> 8) & ~0xFF);
+    }
+};
+
+struct ColorTypeFilter_1616 {
+    typedef uint32_t Type;
+    static uint64_t Expand(uint32_t x) {
+        return (x & 0xFFFF) | ((x & ~0xFFFF) << 16);
+    }
+    static uint16_t Compact(uint64_t x) {
+        return (x & 0xFFFF) | ((x >> 16) & ~0xFFFF);
+    }
+};
+
+struct ColorTypeFilter_16 {
+    typedef uint16_t Type;
+    static uint32_t Expand(uint16_t x) {
+        return x;
+    }
+    static uint16_t Compact(uint32_t x) {
+        return (uint16_t) x;
+    }
+};
+
+struct ColorTypeFilter_1010102 {
+    typedef uint32_t Type;
+    static uint64_t Expand(uint64_t x) {
+        return (((x      ) & 0x3ff)      ) |
+               (((x >> 10) & 0x3ff) << 20) |
+               (((x >> 20) & 0x3ff) << 40) |
+               (((x >> 30) & 0x3  ) << 60);
+    }
+    static uint32_t Compact(uint64_t x) {
+        return (((x      ) & 0x3ff)      ) |
+               (((x >> 20) & 0x3ff) << 10) |
+               (((x >> 40) & 0x3ff) << 20) |
+               (((x >> 60) & 0x3  ) << 30);
+    }
+};
+
 template <typename T> T add_121(const T& a, const T& b, const T& c) {
     return a + b + b + c;
 }
@@ -380,6 +426,46 @@
             proc_3_2 = downsample_3_2<ColorTypeFilter_F16>;
             proc_3_3 = downsample_3_3<ColorTypeFilter_F16>;
             break;
+        case kRG_88_SkColorType:
+            proc_1_2 = downsample_1_2<ColorTypeFilter_88>;
+            proc_1_3 = downsample_1_3<ColorTypeFilter_88>;
+            proc_2_1 = downsample_2_1<ColorTypeFilter_88>;
+            proc_2_2 = downsample_2_2<ColorTypeFilter_88>;
+            proc_2_3 = downsample_2_3<ColorTypeFilter_88>;
+            proc_3_1 = downsample_3_1<ColorTypeFilter_88>;
+            proc_3_2 = downsample_3_2<ColorTypeFilter_88>;
+            proc_3_3 = downsample_3_3<ColorTypeFilter_88>;
+            break;
+        case kRG_1616_SkColorType:
+            proc_1_2 = downsample_1_2<ColorTypeFilter_1616>;
+            proc_1_3 = downsample_1_3<ColorTypeFilter_1616>;
+            proc_2_1 = downsample_2_1<ColorTypeFilter_1616>;
+            proc_2_2 = downsample_2_2<ColorTypeFilter_1616>;
+            proc_2_3 = downsample_2_3<ColorTypeFilter_1616>;
+            proc_3_1 = downsample_3_1<ColorTypeFilter_1616>;
+            proc_3_2 = downsample_3_2<ColorTypeFilter_1616>;
+            proc_3_3 = downsample_3_3<ColorTypeFilter_1616>;
+            break;
+        case kAlpha_16_SkColorType:
+            proc_1_2 = downsample_1_2<ColorTypeFilter_16>;
+            proc_1_3 = downsample_1_3<ColorTypeFilter_16>;
+            proc_2_1 = downsample_2_1<ColorTypeFilter_16>;
+            proc_2_2 = downsample_2_2<ColorTypeFilter_16>;
+            proc_2_3 = downsample_2_3<ColorTypeFilter_16>;
+            proc_3_1 = downsample_3_1<ColorTypeFilter_16>;
+            proc_3_2 = downsample_3_2<ColorTypeFilter_16>;
+            proc_3_3 = downsample_3_3<ColorTypeFilter_16>;
+            break;
+        case kRGBA_1010102_SkColorType:
+            proc_1_2 = downsample_1_2<ColorTypeFilter_1010102>;
+            proc_1_3 = downsample_1_3<ColorTypeFilter_1010102>;
+            proc_2_1 = downsample_2_1<ColorTypeFilter_1010102>;
+            proc_2_2 = downsample_2_2<ColorTypeFilter_1010102>;
+            proc_2_3 = downsample_2_3<ColorTypeFilter_1010102>;
+            proc_3_1 = downsample_3_1<ColorTypeFilter_1010102>;
+            proc_3_2 = downsample_3_2<ColorTypeFilter_1010102>;
+            proc_3_3 = downsample_3_3<ColorTypeFilter_1010102>;
+            break;
         default:
             return nullptr;
     }
diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp
index f4693c3..add2d60 100644
--- a/src/core/SkPixmap.cpp
+++ b/src/core/SkPixmap.cpp
@@ -101,6 +101,7 @@
             return 0;
         case kGray_8_SkColorType:
         case kRG_88_SkColorType:
+        case kRG_1616_SkColorType:
         case kRGB_565_SkColorType:
         case kRGB_888x_SkColorType:
         case kRGB_101010x_SkColorType:
@@ -108,6 +109,9 @@
         case kAlpha_8_SkColorType:
             value = static_cast<const uint8_t*>(srcPtr)[0] * (1.0f/255);
             break;
+        case kAlpha_16_SkColorType:
+            value = static_cast<const uint16_t*>(srcPtr)[0] * (1.0f/65535);
+            break;
         case kARGB_4444_SkColorType: {
             uint16_t u16 = static_cast<const uint16_t*>(srcPtr)[0];
             value = SkGetPackedA4444(u16) * (1.0f/15);
@@ -259,6 +263,10 @@
         case kAlpha_8_SkColorType: {
             return SkColorSetA(0, *this->addr8(x, y));
         }
+        case kAlpha_16_SkColorType: {
+            uint16_t value = *this->addr16(x, y);
+            return SkColorSetA(0, value * (255 / 65535.0f));
+        }
         case kRGB_565_SkColorType: {
             return SkPixel16ToColor(*this->addr16(x, y));
         }
@@ -273,6 +281,12 @@
                  | (uint32_t)( ((value >>  8) & 0xff) ) <<  8
                  | 0xff000000;
         }
+        case kRG_1616_SkColorType: {
+            uint32_t value = *this->addr32(x, y);
+            return (uint32_t)( ((value >>  0) & 0xffff) * (255/65535.0f) ) << 16
+                 | (uint32_t)( ((value >> 16) & 0xffff) * (255/65535.0f) ) <<  8
+                 | 0xff000000;
+        }
         case kRGB_888x_SkColorType: {
             uint32_t value = *this->addr32(x, y);
             return SkSwizzle_RB(value | 0xff000000);
@@ -364,9 +378,23 @@
             }
             return true;
         } break;
+        case kAlpha_16_SkColorType: {
+            unsigned a = 0xFFFF;
+            for (int y = 0; y < height; ++y) {
+                const uint16_t* row = this->addr16(0, y);
+                for (int x = 0; x < width; ++x) {
+                    a &= row[x];
+                }
+                if (0xFFFF != a) {
+                    return false;
+                }
+            }
+            return true;
+        } break;
         case kRGB_565_SkColorType:
         case kGray_8_SkColorType:
         case kRG_88_SkColorType:
+        case kRG_1616_SkColorType:
         case kRGB_888x_SkColorType:
         case kRGB_101010x_SkColorType:
             return true;
diff --git a/src/core/SkRasterPipeline.cpp b/src/core/SkRasterPipeline.cpp
index e316f88..2fe3e6f 100644
--- a/src/core/SkRasterPipeline.cpp
+++ b/src/core/SkRasterPipeline.cpp
@@ -166,9 +166,11 @@
         case kUnknown_SkColorType: SkASSERT(false); break;
 
         case kAlpha_8_SkColorType:      this->append(load_a8,      ctx); break;
+        case kAlpha_16_SkColorType:     this->append(load_a16,     ctx); break;
         case kRGB_565_SkColorType:      this->append(load_565,     ctx); break;
         case kARGB_4444_SkColorType:    this->append(load_4444,    ctx); break;
         case kRG_88_SkColorType:        this->append(load_rg88,    ctx); break;
+        case kRG_1616_SkColorType:      this->append(load_rg1616,  ctx); break;
         case kRGBA_8888_SkColorType:    this->append(load_8888,    ctx); break;
         case kRGBA_1010102_SkColorType: this->append(load_1010102, ctx); break;
         case kRGBA_F16Norm_SkColorType:
@@ -198,9 +200,11 @@
         case kUnknown_SkColorType: SkASSERT(false); break;
 
         case kAlpha_8_SkColorType:      this->append(load_a8_dst,      ctx); break;
+        case kAlpha_16_SkColorType:     this->append(load_a16_dst,     ctx); break;
         case kRGB_565_SkColorType:      this->append(load_565_dst,     ctx); break;
         case kARGB_4444_SkColorType:    this->append(load_4444_dst,    ctx); break;
         case kRG_88_SkColorType:        this->append(load_rg88_dst,    ctx); break;
+        case kRG_1616_SkColorType:      this->append(load_rg1616_dst,  ctx); break;
         case kRGBA_8888_SkColorType:    this->append(load_8888_dst,    ctx); break;
         case kRGBA_1010102_SkColorType: this->append(load_1010102_dst, ctx); break;
         case kRGBA_F16Norm_SkColorType:
@@ -230,9 +234,11 @@
         case kUnknown_SkColorType: SkASSERT(false); break;
 
         case kAlpha_8_SkColorType:      this->append(store_a8,      ctx); break;
+        case kAlpha_16_SkColorType:     this->append(store_a16,     ctx); break;
         case kRGB_565_SkColorType:      this->append(store_565,     ctx); break;
         case kARGB_4444_SkColorType:    this->append(store_4444,    ctx); break;
         case kRG_88_SkColorType:        this->append(store_rg88,    ctx); break;
+        case kRG_1616_SkColorType:      this->append(store_rg1616,  ctx); break;
         case kRGBA_8888_SkColorType:    this->append(store_8888,    ctx); break;
         case kRGBA_1010102_SkColorType: this->append(store_1010102, ctx); break;
         case kRGBA_F16Norm_SkColorType:
diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h
index 8e7dc6d..22f24b0 100644
--- a/src/core/SkRasterPipeline.h
+++ b/src/core/SkRasterPipeline.h
@@ -54,8 +54,8 @@
     M(load_rgf32)                   M(store_rgf32)                 \
     M(load_8888)   M(load_8888_dst) M(store_8888)  M(gather_8888)  \
     M(load_rg88)   M(load_rg88_dst) M(store_rg88)  M(gather_rg88)  \
-    M(load_a16)                     M(store_a16)                   \
-    M(load_rg1616)                  M(store_rg1616)                \
+    M(load_a16)    M(load_a16_dst)  M(store_a16)   M(gather_a16)   \
+    M(load_rg1616) M(load_rg1616_dst) M(store_rg1616) M(gather_rg1616) \
     M(load_16161616)                M(store_16161616)              \
     M(load_1010102) M(load_1010102_dst) M(store_1010102) M(gather_1010102) \
     M(alpha_to_gray) M(alpha_to_gray_dst) M(bt709_luminance_or_luma_to_alpha)         \
diff --git a/src/gpu/GrDataUtils.cpp b/src/gpu/GrDataUtils.cpp
index 91956e3..748455f 100644
--- a/src/gpu/GrDataUtils.cpp
+++ b/src/gpu/GrDataUtils.cpp
@@ -256,16 +256,16 @@
             sk_memset64((uint64_t *) dest, rgbaHalf, width * height);
             break;
         }
-        case kR_16_GrPixelConfig: {
-            uint16_t r16 = SkScalarRoundToInt(colorf.fR * 65535.0f);
-            sk_memset16((uint16_t*) dest, r16, width * height);
+        case kAlpha_16_GrPixelConfig: {
+            uint16_t a16 = SkScalarRoundToInt(colorf.fA * 65535.0f);
+            sk_memset16((uint16_t*) dest, a16, width * height);
             break;
         }
         case kRG_1616_GrPixelConfig: {
-            uint16_t r16 = SkScalarRoundToInt(colorf.fR * 65535.0f);
-            uint16_t g16 = SkScalarRoundToInt(colorf.fG * 65535.0f);
+            uint32_t r16 = SkScalarRoundToInt(colorf.fR * 65535.0f);
+            uint32_t g16 = SkScalarRoundToInt(colorf.fG * 65535.0f);
 
-            uint32_t rg1616 = r16 << 16 | g16;
+            uint32_t rg1616 = (g16 << 16) | r16;
 
             sk_memset32((uint32_t*) dest, rg1616, width * height);
             break;
@@ -369,6 +369,7 @@
     *isSRGB = false;
     switch (ct) {
         case GrColorType::kAlpha_8:          *load = SkRasterPipeline::load_a8;       break;
+        case GrColorType::kAlpha_16:         *load = SkRasterPipeline::load_a16;      break;
         case GrColorType::kBGR_565:          *load = SkRasterPipeline::load_565;      break;
         case GrColorType::kABGR_4444:        *load = SkRasterPipeline::load_4444;     break;
         case GrColorType::kRGBA_8888:        *load = SkRasterPipeline::load_8888;     break;
@@ -400,9 +401,6 @@
         case GrColorType::kGray_8xxx:       *load = SkRasterPipeline::load_8888;
                                              swizzle = GrSwizzle("rrr1");
                                              break;
-        case GrColorType::kR_16:             *load = SkRasterPipeline::load_a16;
-                                             swizzle = GrSwizzle("a001");
-                                             break;
         case GrColorType::kGray_8:           *load = SkRasterPipeline::load_a8;
                                              swizzle = GrSwizzle("aaa1");
                                              break;
@@ -426,6 +424,7 @@
     *isSRGB = false;
     switch (ct) {
         case GrColorType::kAlpha_8:          *store = SkRasterPipeline::store_a8;       break;
+        case GrColorType::kAlpha_16:         *store = SkRasterPipeline::store_a16;      break;
         case GrColorType::kBGR_565:          *store = SkRasterPipeline::store_565;      break;
         case GrColorType::kABGR_4444:        *store = SkRasterPipeline::store_4444;     break;
         case GrColorType::kRGBA_8888:        *store = SkRasterPipeline::store_8888;     break;
@@ -456,9 +455,6 @@
         case GrColorType::kAlpha_F32xxx:     *store = SkRasterPipeline::store_f32;
                                              swizzle = GrSwizzle("a000");
                                              break;
-        case GrColorType::kR_16:             swizzle = GrSwizzle("000r");
-                                             *store = SkRasterPipeline::store_a16;
-                                             break;
         case GrColorType::kBGRA_8888:        swizzle = GrSwizzle("bgra");
                                              *store = SkRasterPipeline::store_8888;
                                              break;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index af99ad8..41257f0 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -259,6 +259,10 @@
             return kRGBA_float_GrPixelConfig;
         case kRG_88_SkColorType:
             return kRG_88_GrPixelConfig;
+        case kRG_1616_SkColorType:
+            return kRG_1616_GrPixelConfig;
+        case kAlpha_16_SkColorType:
+            return kAlpha_16_GrPixelConfig;
     }
     SkASSERT(0);    // shouldn't get here
     return kUnknown_GrPixelConfig;
@@ -293,7 +297,6 @@
         case GrColorType::kRGB_888x:
         case GrColorType::kRG_88:
         case GrColorType::kBGRA_8888:
-        case GrColorType::kR_16:
         case GrColorType::kRG_1616:
         // Experimental (for Y416 and mutant P016/P010)
         case GrColorType::kRGBA_16161616:
@@ -312,6 +315,7 @@
         case GrColorType::kRGBA_F16_Clamped:
         case GrColorType::kAlpha_8:
         case GrColorType::kAlpha_8xxx:
+        case GrColorType::kAlpha_16:
         case GrColorType::kAlpha_F32xxx:
         case GrColorType::kGray_8xxx:
             return -1;
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 7bfaaca..0d13766 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2625,31 +2625,33 @@
             info.fColorTypeInfoCount = 1;
             info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
             int ctIdx = 0;
-            // Format: GR_GL_R16, Surface: kR_16
+            // Format: R16, Surface: kAlpha_16
             {
                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
-                ctInfo.fColorType = GrColorType::kR_16;
+                ctInfo.fColorType = GrColorType::kAlpha_16;
                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
-                this->setColorTypeFormat(GrColorType::kR_16, GrGLFormat::kR16);
+                ctInfo.fTextureSwizzle = GrSwizzle::RRRR();
+                ctInfo.fOutputSwizzle = GrSwizzle::AAAA();
+                this->setColorTypeFormat(GrColorType::kAlpha_16, GrGLFormat::kR16);
 
                 // External IO ColorTypes:
                 ctInfo.fExternalIOFormatCount = 2;
                 ctInfo.fExternalIOFormats.reset(
                         new ColorTypeInfo::ExternalIOFormats[ctInfo.fExternalIOFormatCount]());
                 int ioIdx = 0;
-                // Format: GR_GL_R16, Surface: kR_16, Data: kR_16
+                // Format: R16, Surface: kAlpha_16, Data: kAlpha_16
                 {
                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
-                    ioFormat.fColorType = GrColorType::kR_16;
+                    ioFormat.fColorType = GrColorType::kAlpha_16;
                     ioFormat.fExternalType = GR_GL_UNSIGNED_SHORT;
                     ioFormat.fExternalTexImageFormat = GR_GL_RED;
                     ioFormat.fExternalReadFormat = 0;
                 }
 
-                // Format: GR_GL_R16, Surface: kR_16, Data: kRGBA_8888
+                // Format: R16, Surface: kAlpha_16, Data: kAlpha_8xxx
                 {
                     auto& ioFormat = ctInfo.fExternalIOFormats[ioIdx++];
-                    ioFormat.fColorType = GrColorType::kRGBA_8888;
+                    ioFormat.fColorType = GrColorType::kAlpha_8xxx;
                     ioFormat.fExternalType = GR_GL_UNSIGNED_BYTE;
                     ioFormat.fExternalTexImageFormat = 0;
                     ioFormat.fExternalReadFormat = GR_GL_RGBA;
@@ -3987,9 +3989,9 @@
                 return kRGBA_float_GrPixelConfig;
             }
             break;
-        case GrColorType::kR_16:
+        case GrColorType::kAlpha_16:
             if (format == GrGLFormat::kR16) {
-                return kR_16_GrPixelConfig;
+                return kAlpha_16_GrPixelConfig;
             }
             break;
         case GrColorType::kRG_1616:
@@ -4051,7 +4053,7 @@
         case GrGLFormat::kRGB10_A2:     return GrColorType::kRGBA_1010102;
         case GrGLFormat::kLUMINANCE16F: // fall through
         case GrGLFormat::kR16F:         return GrColorType::kAlpha_F16;
-        case GrGLFormat::kR16:          return GrColorType::kR_16;
+        case GrGLFormat::kR16:          return GrColorType::kAlpha_16;
         case GrGLFormat::kRG16:         return GrColorType::kRG_1616;
         // Experimental (for Y416 and mutant P016/P010)
         case GrGLFormat::kRGBA16:       return GrColorType::kRGBA_16161616;
@@ -4143,7 +4145,7 @@
           GrBackendFormat::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_2D) },
         { GrColorType::kRGBA_F32,
           GrBackendFormat::MakeGL(GR_GL_RGBA32F, GR_GL_TEXTURE_2D) },
-        { GrColorType::kR_16,
+        { GrColorType::kAlpha_16,
           GrBackendFormat::MakeGL(GR_GL_R16, GR_GL_TEXTURE_2D) },
         { GrColorType::kRG_1616,
           GrBackendFormat::MakeGL(GR_GL_RG16, GR_GL_TEXTURE_2D) },
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 0917e79..3d09ad6 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -3505,7 +3505,7 @@
         case GrGLFormat::kRGBA4:                return kRGBA_4444_GrPixelConfig;
         case GrGLFormat::kRGBA32F:              return kRGBA_float_GrPixelConfig;
         case GrGLFormat::kRGBA16F:              return kRGBA_half_GrPixelConfig;
-        case GrGLFormat::kR16:                  return kR_16_GrPixelConfig;
+        case GrGLFormat::kR16:                  return kAlpha_16_GrPixelConfig;
         case GrGLFormat::kRG16:                 return kRG_1616_GrPixelConfig;
         case GrGLFormat::kRGBA16:               return kRGBA_16161616_GrPixelConfig;
         case GrGLFormat::kRG16F:                return kRG_half_GrPixelConfig;
diff --git a/src/gpu/mock/GrMockCaps.cpp b/src/gpu/mock/GrMockCaps.cpp
index 9d99954..6b2eee6 100644
--- a/src/gpu/mock/GrMockCaps.cpp
+++ b/src/gpu/mock/GrMockCaps.cpp
@@ -25,7 +25,7 @@
         { GrColorType::kRGBA_F16,        GrBackendFormat::MakeMock(GrColorType::kRGBA_F16)       },
         { GrColorType::kRGBA_F16_Clamped,GrBackendFormat::MakeMock(GrColorType::kRGBA_F16_Clamped)},
         { GrColorType::kRGBA_F32,        GrBackendFormat::MakeMock(GrColorType::kRGBA_F32)       },
-        { GrColorType::kR_16,            GrBackendFormat::MakeMock(GrColorType::kR_16)           },
+        { GrColorType::kAlpha_16,        GrBackendFormat::MakeMock(GrColorType::kAlpha_16)       },
         { GrColorType::kRG_1616,         GrBackendFormat::MakeMock(GrColorType::kRG_1616)        },
         { GrColorType::kRGBA_16161616,   GrBackendFormat::MakeMock(GrColorType::kRGBA_16161616)  },
         { GrColorType::kRG_F16,          GrBackendFormat::MakeMock(GrColorType::kRG_F16)         },
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
index b0d92c5..14cb2db 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -713,11 +713,13 @@
         info->fColorTypeInfoCount = 1;
         info->fColorTypeInfos.reset(new ColorTypeInfo[info->fColorTypeInfoCount]());
         int ctIdx = 0;
-        // Format: R16Unorm, Surface: kR_16
+        // Format: R16Unorm, Surface: kAlpha_16
         {
             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
-            ctInfo.fColorType = GrColorType::kR_16;
+            ctInfo.fColorType = GrColorType::kAlpha_16;
             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
+            ctInfo.fTextureSwizzle = GrSwizzle::RRRR();
+            ctInfo.fOutputSwizzle = GrSwizzle::AAAA();
         }
     }
 
@@ -808,7 +810,7 @@
     this->setColorType(GrColorType::kRGBA_F16,         { MTLPixelFormatRGBA16Float });
     this->setColorType(GrColorType::kRGBA_F16_Clamped, { MTLPixelFormatRGBA16Float });
     this->setColorType(GrColorType::kRGBA_F32,         { MTLPixelFormatRGBA32Float });
-    this->setColorType(GrColorType::kR_16,             { MTLPixelFormatR16Unorm });
+    this->setColorType(GrColorType::kAlpha_16,         { MTLPixelFormatR16Unorm });
     this->setColorType(GrColorType::kRG_1616,          { MTLPixelFormatRG16Unorm });
     this->setColorType(GrColorType::kRGBA_16161616,    { MTLPixelFormatRGBA16Unorm });
     this->setColorType(GrColorType::kRG_F16,           { MTLPixelFormatRG16Float });
@@ -913,9 +915,9 @@
                 return kRGBA_float_GrPixelConfig;
             }
             break;
-        case GrColorType::kR_16:
+        case GrColorType::kAlpha_16:
             if (MTLPixelFormatR16Unorm == format) {
-                return kR_16_GrPixelConfig;
+                return kAlpha_16_GrPixelConfig;
             }
             break;
         case GrColorType::kRG_1616:
@@ -968,7 +970,7 @@
         case MTLPixelFormatRGBA8Unorm:        return GrColorType::kRGBA_8888;
         case MTLPixelFormatBGRA8Unorm:        return GrColorType::kBGRA_8888;
         case MTLPixelFormatRGB10A2Unorm:      return GrColorType::kRGBA_1010102;
-        case MTLPixelFormatR16Unorm:          return GrColorType::kR_16;
+        case MTLPixelFormatR16Unorm:          return GrColorType::kAlpha_16;
         case MTLPixelFormatRG16Unorm:         return GrColorType::kRG_1616;
         // Experimental (for Y416 and mutant P016/P010)
         case MTLPixelFormatRGBA16Unorm:       return GrColorType::kRGBA_16161616;
@@ -1083,7 +1085,7 @@
         { GrColorType::kRGBA_F16,         GrBackendFormat::MakeMtl(MTLPixelFormatRGBA16Float)     },
         { GrColorType::kRGBA_F16_Clamped, GrBackendFormat::MakeMtl(MTLPixelFormatRGBA16Float)     },
         { GrColorType::kRGBA_F32,         GrBackendFormat::MakeMtl(MTLPixelFormatRGBA32Float)     },
-        { GrColorType::kR_16,             GrBackendFormat::MakeMtl(MTLPixelFormatR16Unorm)        },
+        { GrColorType::kAlpha_16,         GrBackendFormat::MakeMtl(MTLPixelFormatR16Unorm)        },
         { GrColorType::kRG_1616,          GrBackendFormat::MakeMtl(MTLPixelFormatRG16Unorm)       },
         { GrColorType::kRGBA_16161616,    GrBackendFormat::MakeMtl(MTLPixelFormatRGBA16Unorm)     },
         { GrColorType::kRG_F16,           GrBackendFormat::MakeMtl(MTLPixelFormatRG16Float)       },
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index 4915298..a0a4c21 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -617,7 +617,7 @@
         case MTLPixelFormatR16Float:        return kAlpha_half_GrPixelConfig;
         case MTLPixelFormatRGBA16Float:     return kRGBA_half_GrPixelConfig;
         case MTLPixelFormatRGBA32Float:     return kRGBA_float_GrPixelConfig;
-        case MTLPixelFormatR16Unorm:        return kR_16_GrPixelConfig;
+        case MTLPixelFormatR16Unorm:        return kAlpha_16_GrPixelConfig;
         case MTLPixelFormatRG16Unorm:       return kRG_1616_GrPixelConfig;
         case MTLPixelFormatRGBA16Unorm:     return kRGBA_16161616_GrPixelConfig;
         case MTLPixelFormatRG16Float:       return kRG_half_GrPixelConfig;
diff --git a/src/gpu/mtl/GrMtlUtil.mm b/src/gpu/mtl/GrMtlUtil.mm
index 85e01d2..62d6290 100644
--- a/src/gpu/mtl/GrMtlUtil.mm
+++ b/src/gpu/mtl/GrMtlUtil.mm
@@ -101,7 +101,7 @@
 #else
             return false;
 #endif
-        case kR_16_GrPixelConfig:
+        case kAlpha_16_GrPixelConfig:
             *format = MTLPixelFormatR16Unorm;
             return true;
         case kRG_1616_GrPixelConfig:
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 8881ed8..1ec7371 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -985,12 +985,14 @@
             info.fColorTypeInfoCount = 1;
             info.fColorTypeInfos.reset(new ColorTypeInfo[info.fColorTypeInfoCount]());
             int ctIdx = 0;
-            // Format: VK_FORMAT_R16_UNORM, Surface: kR_16
+            // Format: VK_FORMAT_R16_UNORM, Surface: kAlpha_16
             {
-                constexpr GrColorType ct = GrColorType::kR_16;
+                constexpr GrColorType ct = GrColorType::kAlpha_16;
                 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
                 ctInfo.fColorType = ct;
                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
+                ctInfo.fTextureSwizzle = GrSwizzle::RRRR();
+                ctInfo.fOutputSwizzle = GrSwizzle::AAAA();
             }
         }
     }
@@ -1117,7 +1119,7 @@
     this->setColorType(GrColorType::kRGBA_F16,         { VK_FORMAT_R16G16B16A16_SFLOAT });
     this->setColorType(GrColorType::kRGBA_F16_Clamped, { VK_FORMAT_R16G16B16A16_SFLOAT });
     this->setColorType(GrColorType::kRGBA_F32,         { VK_FORMAT_R32G32B32A32_SFLOAT });
-    this->setColorType(GrColorType::kR_16,             { VK_FORMAT_R16_UNORM });
+    this->setColorType(GrColorType::kAlpha_16,         { VK_FORMAT_R16_UNORM });
     this->setColorType(GrColorType::kRG_1616,          { VK_FORMAT_R16G16_UNORM });
     this->setColorType(GrColorType::kRGBA_16161616,    { VK_FORMAT_R16G16B16A16_UNORM });
     this->setColorType(GrColorType::kRG_F16,           { VK_FORMAT_R16G16_SFLOAT });
@@ -1525,9 +1527,9 @@
                 return kRGBA_float_GrPixelConfig;
             }
             break;
-        case GrColorType::kR_16:
+        case GrColorType::kAlpha_16:
             if (VK_FORMAT_R16_UNORM == format) {
-                return kR_16_GrPixelConfig;
+                return kAlpha_16_GrPixelConfig;
             }
             break;
         case GrColorType::kRG_1616:
@@ -1581,7 +1583,7 @@
         case VK_FORMAT_R8G8_UNORM:               return GrColorType::kRG_88;
         case VK_FORMAT_B8G8R8A8_UNORM:           return GrColorType::kBGRA_8888;
         case VK_FORMAT_A2B10G10R10_UNORM_PACK32: return GrColorType::kRGBA_1010102;
-        case VK_FORMAT_R16_UNORM:                return GrColorType::kR_16;
+        case VK_FORMAT_R16_UNORM:                return GrColorType::kAlpha_16;
         case VK_FORMAT_R16G16_UNORM:             return GrColorType::kRG_1616;
         // Experimental (for Y416 and mutant P016/P010)
         case VK_FORMAT_R16G16B16A16_UNORM:       return GrColorType::kRGBA_16161616;
@@ -1689,7 +1691,7 @@
         { GrColorType::kRGBA_F16,         GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_SFLOAT)  },
         { GrColorType::kRGBA_F16_Clamped, GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_SFLOAT)  },
         { GrColorType::kRGBA_F32,         GrBackendFormat::MakeVk(VK_FORMAT_R32G32B32A32_SFLOAT)  },
-        { GrColorType::kR_16,             GrBackendFormat::MakeVk(VK_FORMAT_R16_UNORM)            },
+        { GrColorType::kAlpha_16,         GrBackendFormat::MakeVk(VK_FORMAT_R16_UNORM)            },
         { GrColorType::kRG_1616,          GrBackendFormat::MakeVk(VK_FORMAT_R16G16_UNORM)         },
         { GrColorType::kRGBA_16161616,    GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_UNORM)   },
         { GrColorType::kRG_F16,           GrBackendFormat::MakeVk(VK_FORMAT_R16G16_SFLOAT)        },
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index c3f3f9a..10bc5ef 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -33,7 +33,7 @@
         case VK_FORMAT_R16G16B16A16_SFLOAT:       return GrColorType::kRGBA_F16 == colorType ||
                                                          GrColorType::kRGBA_F16_Clamped == colorType;
         case VK_FORMAT_R16_SFLOAT:                return GrColorType::kAlpha_F16 == colorType;
-        case VK_FORMAT_R16_UNORM:                 return GrColorType::kR_16 == colorType;
+        case VK_FORMAT_R16_UNORM:                 return GrColorType::kAlpha_16 == colorType;
         case VK_FORMAT_R16G16_UNORM:              return GrColorType::kRG_1616 == colorType;
         case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: return GrColorType::kRGB_888x == colorType;
         case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:  return GrColorType::kRGB_888x == colorType;
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp
index f848c81..2ba4c5f 100644
--- a/src/image/SkSurface_Raster.cpp
+++ b/src/image/SkSurface_Raster.cpp
@@ -42,7 +42,9 @@
         return false;
     }
 
-    if (info.colorType() == kRG_88_SkColorType) {
+    if (info.colorType() == kRG_88_SkColorType ||
+        info.colorType() == kRG_1616_SkColorType ||
+        info.colorType() == kAlpha_16_SkColorType) {
         return false;
     }
 
diff --git a/src/images/SkPngEncoder.cpp b/src/images/SkPngEncoder.cpp
index c902a73..79e9812 100644
--- a/src/images/SkPngEncoder.cpp
+++ b/src/images/SkPngEncoder.cpp
@@ -316,6 +316,8 @@
         case kAlpha_8_SkColorType:
             return transform_scanline_A8_to_GrayAlpha;
         case kRG_88_SkColorType:
+        case kRG_1616_SkColorType:
+        case kAlpha_16_SkColorType:
             return nullptr;
     }
     SkASSERT(false);
diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h
index 087e3e7..f43b556 100644
--- a/src/opts/SkRasterPipeline_opts.h
+++ b/src/opts/SkRasterPipeline_opts.h
@@ -2012,17 +2012,42 @@
     r = g = b = 0;
     a = from_short(load<U16>(ptr, tail));
 }
+STAGE(load_a16_dst, const SkRasterPipeline_MemoryCtx* ctx) {
+    auto ptr = ptr_at_xy<const uint16_t>(ctx, dx, dy);
+    dr = dg = db = 0.0f;
+    da = from_short(load<U16>(ptr, tail));
+}
+STAGE(gather_a16, const SkRasterPipeline_GatherCtx* ctx) {
+    const uint16_t* ptr;
+    U32 ix = ix_and_ptr(&ptr, ctx, r, g);
+    r = g = b = 0.0f;
+    a = from_short(gather(ptr, ix));
+}
 STAGE(store_a16, const SkRasterPipeline_MemoryCtx* ctx) {
     auto ptr = ptr_at_xy<uint16_t>(ctx, dx,dy);
 
     U16 px = pack(to_unorm(a, 65535));
     store(ptr, px, tail);
 }
+
 STAGE(load_rg1616, const SkRasterPipeline_MemoryCtx* ctx) {
     auto ptr = ptr_at_xy<const uint32_t>(ctx, dx,dy);
     b = 0; a = 1;
     from_1616(load<U32>(ptr, tail), &r,&g);
 }
+STAGE(load_rg1616_dst, const SkRasterPipeline_MemoryCtx* ctx) {
+    auto ptr = ptr_at_xy<const uint32_t>(ctx, dx, dy);
+    from_1616(load<U32>(ptr, tail), &dr, &dg);
+    db = 0;
+    da = 1;
+}
+STAGE(gather_rg1616, const SkRasterPipeline_GatherCtx* ctx) {
+    const uint32_t* ptr;
+    U32 ix = ix_and_ptr(&ptr, ctx, r, g);
+    from_1616(gather(ptr, ix), &r, &g);
+    b = 0;
+    a = 1;
+}
 STAGE(store_rg1616, const SkRasterPipeline_MemoryCtx* ctx) {
     auto ptr = ptr_at_xy<uint32_t>(ctx, dx,dy);
 
@@ -2030,6 +2055,7 @@
            | to_unorm(g, 65535) <<  16;
     store(ptr, px, tail);
 }
+
 STAGE(load_16161616, const SkRasterPipeline_MemoryCtx* ctx) {
     auto ptr = ptr_at_xy<const uint64_t>(ctx, dx,dy);
     from_16161616(load<U64>(ptr, tail), &r,&g, &b, &a);
@@ -4117,9 +4143,13 @@
     NOT_IMPLEMENTED(load_16161616)
     NOT_IMPLEMENTED(store_16161616)
     NOT_IMPLEMENTED(load_a16)
+    NOT_IMPLEMENTED(load_a16_dst)
     NOT_IMPLEMENTED(store_a16)
+    NOT_IMPLEMENTED(gather_a16)
     NOT_IMPLEMENTED(load_rg1616)
+    NOT_IMPLEMENTED(load_rg1616_dst)
     NOT_IMPLEMENTED(store_rg1616)
+    NOT_IMPLEMENTED(gather_rg1616)
     NOT_IMPLEMENTED(load_f16)
     NOT_IMPLEMENTED(load_f16_dst)
     NOT_IMPLEMENTED(store_f16)
diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp
index 8e39147..0f463a9 100644
--- a/src/shaders/SkImageShader.cpp
+++ b/src/shaders/SkImageShader.cpp
@@ -421,9 +421,11 @@
         void* ctx = gather;
         switch (info.colorType()) {
             case kAlpha_8_SkColorType:      p->append(SkRasterPipeline::gather_a8,      ctx); break;
+            case kAlpha_16_SkColorType:     p->append(SkRasterPipeline::gather_a16,     ctx); break;
             case kRGB_565_SkColorType:      p->append(SkRasterPipeline::gather_565,     ctx); break;
             case kARGB_4444_SkColorType:    p->append(SkRasterPipeline::gather_4444,    ctx); break;
             case kRG_88_SkColorType:        p->append(SkRasterPipeline::gather_rg88,    ctx); break;
+            case kRG_1616_SkColorType:      p->append(SkRasterPipeline::gather_rg1616,  ctx); break;
             case kRGBA_8888_SkColorType:    p->append(SkRasterPipeline::gather_8888,    ctx); break;
             case kRGBA_1010102_SkColorType: p->append(SkRasterPipeline::gather_1010102, ctx); break;
             case kRGBA_F16Norm_SkColorType:
diff --git a/tests/BackendAllocationTest.cpp b/tests/BackendAllocationTest.cpp
index 276b80c..31ea611 100644
--- a/tests/BackendAllocationTest.cpp
+++ b/tests/BackendAllocationTest.cpp
@@ -425,6 +425,8 @@
         { kRGBA_F16_SkColorType,     SkColors::kYellow        },
         { kRGBA_F32_SkColorType,     SkColors::kGray          },
         { kRG_88_SkColorType,        { .25f, .75f, 0, 0 }     },
+        { kRG_1616_SkColorType,      SkColors::kGreen         },
+        { kAlpha_16_SkColorType,     kTransCol                },
     };
 
     GR_STATIC_ASSERT(kLastEnum_SkColorType == SK_ARRAY_COUNT(combinations));
@@ -574,7 +576,7 @@
         { GrColorType::kAlpha_F16,        GR_GL_R16F,                 { 1.0f, 0, 0, 0.5f } },
         { GrColorType::kAlpha_F16,        GR_GL_LUMINANCE16F,         kGrayCol             },
 
-        { GrColorType::kR_16,             GR_GL_R16,                  SkColors::kRed       },
+        { GrColorType::kAlpha_16,         GR_GL_R16,                  kTransCol            },
         { GrColorType::kRG_1616,          GR_GL_RG16,                 SkColors::kYellow    },
 
         // Experimental (for Y416 and mutant P016/P010)
@@ -709,7 +711,7 @@
         { GrColorType::kRG_88,            VK_FORMAT_R8G8_UNORM,               { 1, 0.5f, 0, 1 }   },
         { GrColorType::kAlpha_F16,        VK_FORMAT_R16_SFLOAT,               { 1.0f, 0, 0, 0.5f }},
 
-        { GrColorType::kR_16,             VK_FORMAT_R16_UNORM,                SkColors::kRed      },
+        { GrColorType::kAlpha_16,         VK_FORMAT_R16_UNORM,                kTransCol           },
         { GrColorType::kRG_1616,          VK_FORMAT_R16G16_UNORM,             SkColors::kYellow   },
 
         // Experimental (for Y416 and mutant P016/P010)
@@ -774,6 +776,10 @@
                             SkASSERT(combo.fFormat == VK_FORMAT_R8_UNORM);
                             swizzle = GrSwizzle("aaaa");
                             break;
+                        case GrColorType::kAlpha_16:
+                            SkASSERT(combo.fFormat == VK_FORMAT_R16_UNORM);
+                            swizzle = GrSwizzle("aaaa");
+                            break;
                         case GrColorType::kABGR_4444:
                             if (combo.fFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16) {
                                 swizzle = GrSwizzle("bgra");
diff --git a/tests/BitmapTest.cpp b/tests/BitmapTest.cpp
index 259ab08..912641a 100644
--- a/tests/BitmapTest.cpp
+++ b/tests/BitmapTest.cpp
@@ -332,10 +332,12 @@
         { kRGB_565_SkColorType,     opaque },
         { kGray_8_SkColorType,      opaque },
         { kRG_88_SkColorType,       opaque },
+        { kRG_1616_SkColorType,     opaque },
         { kRGB_888x_SkColorType,    opaque },
         { kRGB_101010x_SkColorType, opaque },
 
         { kAlpha_8_SkColorType,     nearly },
+        { kAlpha_16_SkColorType,    nearly },
         { kRGBA_8888_SkColorType,   nearly },
         { kBGRA_8888_SkColorType,   nearly },
         { kRGBA_F16_SkColorType,    nearly_half },
diff --git a/tests/ExtendedSkColorTypeTests.cpp b/tests/ExtendedSkColorTypeTests.cpp
index c334ebf..af425e3 100644
--- a/tests/ExtendedSkColorTypeTests.cpp
+++ b/tests/ExtendedSkColorTypeTests.cpp
@@ -54,6 +54,7 @@
 
 static const TestCase gTests[] = {
     { kAlpha_8_SkColorType,      kPremul_SkAlphaType, kAlpha_SkColorTypeComponentFlag, true  },
+    { kAlpha_16_SkColorType,     kPremul_SkAlphaType, kAlpha_SkColorTypeComponentFlag, false },
     { kRGB_565_SkColorType,      kOpaque_SkAlphaType, kRGB_SkColorTypeComponentFlags,  true  },
     { kARGB_4444_SkColorType,    kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
     { kRGBA_8888_SkColorType,    kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
@@ -65,7 +66,8 @@
     { kRGBA_F16Norm_SkColorType, kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
     { kRGBA_F16_SkColorType,     kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
     { kRGBA_F32_SkColorType,     kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
-    { kRG_88_SkColorType,        kOpaque_SkAlphaType, kRG_SkColorTypeComponentFlags,   false }
+    { kRG_88_SkColorType,        kOpaque_SkAlphaType, kRG_SkColorTypeComponentFlags,   false },
+    { kRG_1616_SkColorType,      kOpaque_SkAlphaType, kRG_SkColorTypeComponentFlags,   false },
 };
 
 static void raster_tests(skiatest::Reporter* reporter, const TestCase& test) {
diff --git a/tests/MtlBackendAllocationTest.mm b/tests/MtlBackendAllocationTest.mm
index 81803d6..d620f61 100644
--- a/tests/MtlBackendAllocationTest.mm
+++ b/tests/MtlBackendAllocationTest.mm
@@ -66,7 +66,7 @@
         { GrColorType::kRG_88,            MTLPixelFormatRG8Unorm,        { 0.5f, 0.5f, 0, 1 } },
         { GrColorType::kAlpha_F16,        MTLPixelFormatR16Float,        { 1.0f, 0, 0, 0.5f } },
 
-        { GrColorType::kR_16,             MTLPixelFormatR16Unorm,        SkColors::kRed       },
+        { GrColorType::kAlpha_16,         MTLPixelFormatR16Unorm,        kTransCol            },
         { GrColorType::kRG_1616,          MTLPixelFormatRG16Unorm,       SkColors::kYellow    },
 
         // Experimental (for Y416 and mutant P016/P010)
diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp
index b1450a1..aae476f 100644
--- a/tests/ReadPixelsTest.cpp
+++ b/tests/ReadPixelsTest.cpp
@@ -624,9 +624,11 @@
     switch (ct) {
         case kUnknown_SkColorType:      return 0;
         case kAlpha_8_SkColorType:      return 8;
+        case kAlpha_16_SkColorType:     return 16;
         case kRGB_565_SkColorType:      return 5;
         case kARGB_4444_SkColorType:    return 4;
         case kRG_88_SkColorType:        return 8;
+        case kRG_1616_SkColorType:      return 16;
         case kRGBA_8888_SkColorType:    return 8;
         case kRGB_888x_SkColorType:     return 8;
         case kBGRA_8888_SkColorType:    return 8;
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 1de8163..e9b9490 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -97,92 +97,103 @@
 
         SkColorType colorType = static_cast<SkColorType>(ct);
         auto info = SkImageInfo::Make(kSize, kSize, colorType, kOpaque_SkAlphaType, nullptr);
-        bool can = context->colorTypeSupportedAsSurface(colorType);
-        auto surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 1, nullptr);
-        REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d",
-                        colorType, can, SkToBool(surf));
 
-        GrBackendTexture backendTex = context->createBackendTexture(
-                kSize, kSize, colorType,
-                SkColors::kTransparent, GrMipMapped::kNo, GrRenderable::kYes, GrProtected::kNo);
-        surf = SkSurface::MakeFromBackendTexture(context, backendTex,
-                                                 kTopLeft_GrSurfaceOrigin, 0, colorType, nullptr,
-                                                 nullptr);
-        REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d",
-                        colorType, can, SkToBool(surf));
+        {
+            bool can = context->colorTypeSupportedAsSurface(colorType);
+            auto surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 1, nullptr);
+            REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d",
+                            colorType, can, SkToBool(surf));
 
-        surf = SkSurface::MakeFromBackendTextureAsRenderTarget(context, backendTex,
-                                                               kTopLeft_GrSurfaceOrigin, 1,
-                                                               colorType, nullptr, nullptr);
-        REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d",
-                        colorType, can, SkToBool(surf));
+            GrBackendTexture backendTex = context->createBackendTexture(
+                    kSize, kSize, colorType,
+                    SkColors::kTransparent, GrMipMapped::kNo, GrRenderable::kYes, GrProtected::kNo);
+            surf = SkSurface::MakeFromBackendTexture(context, backendTex,
+                                                     kTopLeft_GrSurfaceOrigin, 0, colorType,
+                                                     nullptr, nullptr);
+            REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d",
+                            colorType, can, SkToBool(surf));
 
-        surf.reset();
-        context->flush();
-        context->deleteBackendTexture(backendTex);
+            surf = SkSurface::MakeFromBackendTextureAsRenderTarget(context, backendTex,
+                                                                   kTopLeft_GrSurfaceOrigin, 1,
+                                                                   colorType, nullptr, nullptr);
+            REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d",
+                            colorType, can, SkToBool(surf));
 
-        static constexpr int kSampleCnt = 2;
-
-        can = context->maxSurfaceSampleCountForColorType(colorType) >= kSampleCnt;
-        surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, kSampleCnt, nullptr);
-        REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d",
-                        colorType, can, SkToBool(surf));
-
-        backendTex = context->createBackendTexture(kSize, kSize, colorType,
-                                                   SkColors::kTransparent,
-                                                   GrMipMapped::kNo, GrRenderable::kYes,
-                                                   GrProtected::kNo);
-        surf = SkSurface::MakeFromBackendTexture(context, backendTex,
-                                                 kTopLeft_GrSurfaceOrigin, kSampleCnt, colorType,
-                                                 nullptr, nullptr);
-        REPORTER_ASSERT(reporter, can == SkToBool(surf),
-                        "colorTypeSupportedAsSurface:%d, surf:%d, ct:%d", can, SkToBool(surf),
-                        colorType);
-        // Ensure that the sample count stored on the resulting SkSurface is a valid value.
-        if (surf) {
-            auto* rtc = ((SkSurface_Gpu*)(surf.get()))->getDevice()->accessRenderTargetContext();
-            int storedCnt = rtc->numSamples();
-            int allowedCnt = context->priv().caps()->getRenderTargetSampleCount(
-                    storedCnt, backendTex.getBackendFormat());
-            REPORTER_ASSERT(reporter, storedCnt == allowedCnt,
-                            "Should store an allowed sample count (%d vs %d)", allowedCnt,
-                            storedCnt);
+            surf.reset();
+            context->flush();
+            context->deleteBackendTexture(backendTex);
         }
 
-        surf = SkSurface::MakeFromBackendTextureAsRenderTarget(context, backendTex,
-                                                               kTopLeft_GrSurfaceOrigin, kSampleCnt,
-                                                               colorType, nullptr, nullptr);
-        REPORTER_ASSERT(reporter, can == SkToBool(surf),
-                        "colorTypeSupportedAsSurface:%d, surf:%d, ct:%d", can, SkToBool(surf),
-                        colorType);
-        if (surf) {
-            auto* rtc = ((SkSurface_Gpu*)(surf.get()))->getDevice()->accessRenderTargetContext();
-            int storedCnt = rtc->numSamples();
-            int allowedCnt = context->priv().caps()->getRenderTargetSampleCount(
-                    storedCnt, backendTex.getBackendFormat());
-            REPORTER_ASSERT(reporter, storedCnt == allowedCnt,
-                            "Should store an allowed sample count (%d vs %d)", allowedCnt,
-                            storedCnt);
+        // The MSAA test only makes sense if the colorType is renderable to begin with.
+        if (context->colorTypeSupportedAsSurface(colorType)) {
+            static constexpr int kSampleCnt = 2;
+
+            bool can = context->maxSurfaceSampleCountForColorType(colorType) >= kSampleCnt;
+            auto surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, kSampleCnt,
+                                                    nullptr);
+            REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d",
+                            colorType, can, SkToBool(surf));
+
+            GrBackendTexture backendTex = context->createBackendTexture(
+                                                       kSize, kSize, colorType,
+                                                       SkColors::kTransparent,
+                                                       GrMipMapped::kNo, GrRenderable::kYes,
+                                                       GrProtected::kNo);
+            surf = SkSurface::MakeFromBackendTexture(context, backendTex,
+                                                     kTopLeft_GrSurfaceOrigin, kSampleCnt,
+                                                     colorType, nullptr, nullptr);
+            REPORTER_ASSERT(reporter, can == SkToBool(surf),
+                            "colorTypeSupportedAsSurface:%d, surf:%d, ct:%d", can, SkToBool(surf),
+                            colorType);
+            // Ensure that the sample count stored on the resulting SkSurface is a valid value.
+            if (surf) {
+                auto rtc = ((SkSurface_Gpu*)(surf.get()))->getDevice()->accessRenderTargetContext();
+                int storedCnt = rtc->numSamples();
+                int allowedCnt = context->priv().caps()->getRenderTargetSampleCount(
+                        storedCnt, backendTex.getBackendFormat());
+                REPORTER_ASSERT(reporter, storedCnt == allowedCnt,
+                                "Should store an allowed sample count (%d vs %d)", allowedCnt,
+                                storedCnt);
+            }
+
+            surf = SkSurface::MakeFromBackendTextureAsRenderTarget(context, backendTex,
+                                                                   kTopLeft_GrSurfaceOrigin,
+                                                                   kSampleCnt, colorType,
+                                                                   nullptr, nullptr);
+            REPORTER_ASSERT(reporter, can == SkToBool(surf),
+                            "colorTypeSupportedAsSurface:%d, surf:%d, ct:%d", can, SkToBool(surf),
+                            colorType);
+            if (surf) {
+                auto rtc = ((SkSurface_Gpu*)(surf.get()))->getDevice()->accessRenderTargetContext();
+                int storedCnt = rtc->numSamples();
+                int allowedCnt = context->priv().caps()->getRenderTargetSampleCount(
+                        storedCnt, backendTex.getBackendFormat());
+                REPORTER_ASSERT(reporter, storedCnt == allowedCnt,
+                                "Should store an allowed sample count (%d vs %d)", allowedCnt,
+                                storedCnt);
+            }
+
+            surf.reset();
+            context->flush();
+            context->deleteBackendTexture(backendTex);
         }
 
-        surf.reset();
-        context->flush();
-        context->deleteBackendTexture(backendTex);
+        {
+            auto* gpu = context->priv().getGpu();
 
-        auto* gpu = context->priv().getGpu();
-
-        GrBackendRenderTarget backendRenderTarget = gpu->createTestingOnlyBackendRenderTarget(
-                16, 16, SkColorTypeToGrColorType(colorType));
-        can = context->colorTypeSupportedAsSurface(colorType);
-        surf = SkSurface::MakeFromBackendRenderTarget(context, backendRenderTarget,
-                                                      kTopLeft_GrSurfaceOrigin, colorType, nullptr,
-                                                      nullptr);
-        REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d", colorType,
-                        can, SkToBool(surf));
-        surf.reset();
-        context->flush();
-        if (backendRenderTarget.isValid()) {
-            gpu->deleteTestingOnlyBackendRenderTarget(backendRenderTarget);
+            GrBackendRenderTarget backendRenderTarget = gpu->createTestingOnlyBackendRenderTarget(
+                    16, 16, SkColorTypeToGrColorType(colorType));
+            bool can = context->colorTypeSupportedAsSurface(colorType);
+            auto surf = SkSurface::MakeFromBackendRenderTarget(context, backendRenderTarget,
+                                                               kTopLeft_GrSurfaceOrigin, colorType,
+                                                               nullptr, nullptr);
+            REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d", colorType,
+                            can, SkToBool(surf));
+            surf.reset();
+            context->flush();
+            if (backendRenderTarget.isValid()) {
+                gpu->deleteTestingOnlyBackendRenderTarget(backendRenderTarget);
+            }
         }
     }
 }
@@ -208,6 +219,11 @@
         SkScopeExit freeTex([&backendTex, context] {
             context->deleteBackendTexture(backendTex);
         });
+
+        if (!context->colorTypeSupportedAsSurface(colorType)) {
+            continue;
+        }
+
         auto info = SkImageInfo::Make(kSize, kSize, colorType, kOpaque_SkAlphaType, nullptr);
         auto surf = SkSurface::MakeFromBackendTexture(context, backendTex,
                                                       kTopLeft_GrSurfaceOrigin, max,
diff --git a/tests/TransferPixelsTest.cpp b/tests/TransferPixelsTest.cpp
index e93ef80..6b21f30 100644
--- a/tests/TransferPixelsTest.cpp
+++ b/tests/TransferPixelsTest.cpp
@@ -435,7 +435,7 @@
                      GrColorType::kRGBA_F16,
                      GrColorType::kRGBA_F16_Clamped,
                      GrColorType::kRGBA_F32,
-                     GrColorType::kR_16,
+                     GrColorType::kAlpha_16,
                      GrColorType::kRG_1616,
                      GrColorType::kRGBA_16161616,
                      GrColorType::kRG_F16,
@@ -453,6 +453,7 @@
     for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
         for (auto colorType : {
                 GrColorType::kAlpha_8,
+                GrColorType::kAlpha_16,
                 GrColorType::kBGR_565,
                 GrColorType::kABGR_4444,
                 GrColorType::kRGBA_8888,
@@ -466,7 +467,6 @@
                 GrColorType::kRGBA_F16,
                 GrColorType::kRGBA_F16_Clamped,
                 GrColorType::kRGBA_F32,
-                GrColorType::kR_16,
                 GrColorType::kRG_1616,
                 GrColorType::kRGBA_16161616,
                 GrColorType::kRG_F16,
diff --git a/tools/HashAndEncode.cpp b/tools/HashAndEncode.cpp
index 21883088..90b5944 100644
--- a/tools/HashAndEncode.cpp
+++ b/tools/HashAndEncode.cpp
@@ -36,10 +36,12 @@
         case kRGBA_F32_SkColorType:     srcFmt = skcms_PixelFormat_RGBA_ffff;    break;
 
         case kRGB_888x_SkColorType:     srcFmt = skcms_PixelFormat_RGBA_8888;
-                                        srcAlpha = skcms_AlphaFormat_Opaque;       break;
+                                        srcAlpha = skcms_AlphaFormat_Opaque;     break;
         case kRGB_101010x_SkColorType:  srcFmt = skcms_PixelFormat_RGBA_1010102;
-                                        srcAlpha = skcms_AlphaFormat_Opaque;       break;
+                                        srcAlpha = skcms_AlphaFormat_Opaque;     break;
         case kRG_88_SkColorType:        return;
+        case kRG_1616_SkColorType:      return;
+        case kAlpha_16_SkColorType:     return;
     }
 
     skcms_ICCProfile srcProfile = *skcms_sRGB_profile();
diff --git a/tools/ToolUtils.cpp b/tools/ToolUtils.cpp
index 5f1a4c0..e629972 100644
--- a/tools/ToolUtils.cpp
+++ b/tools/ToolUtils.cpp
@@ -50,6 +50,7 @@
     switch (ct) {
         case kUnknown_SkColorType:      return "Unknown";
         case kAlpha_8_SkColorType:      return "Alpha_8";
+        case kAlpha_16_SkColorType:     return "Alpha_16";
         case kRGB_565_SkColorType:      return "RGB_565";
         case kARGB_4444_SkColorType:    return "ARGB_4444";
         case kRGBA_8888_SkColorType:    return "RGBA_8888";
@@ -62,6 +63,7 @@
         case kRGBA_F16_SkColorType:     return "RGBA_F16";
         case kRGBA_F32_SkColorType:     return "RGBA_F32";
         case kRG_88_SkColorType:        return "RG_88";
+        case kRG_1616_SkColorType:      return "RG_1616";
     }
     SkASSERT(false);
     return "unexpected colortype";
@@ -71,6 +73,7 @@
     switch (ct) {
         case kUnknown_SkColorType:      return "Unknown";
         case kAlpha_8_SkColorType:      return "A8";
+        case kAlpha_16_SkColorType:     return "A16";
         case kRGB_565_SkColorType:      return "565";
         case kARGB_4444_SkColorType:    return "4444";
         case kRGBA_8888_SkColorType:    return "8888";
@@ -83,6 +86,7 @@
         case kRGBA_F16_SkColorType:     return "F16";
         case kRGBA_F32_SkColorType:     return "F32";
         case kRG_88_SkColorType:        return "88";
+        case kRG_1616_SkColorType:      return "1616";
     }
     SkASSERT(false);
     return "unexpected colortype";