Add support for GL 565 and 4444 configs to test tools

Change-Id: I395e3387df44cf5370fef6ab73db73228225622f
Reviewed-on: https://skia-review.googlesource.com/23946
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 3ddc827..b701bcc 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -851,7 +851,8 @@
             }
             return new GPUSink(contextType, contextOverrides, gpuConfig->getSamples(),
                                gpuConfig->getUseDIText(), gpuConfig->getColorType(),
-                               sk_ref_sp(gpuConfig->getColorSpace()), FLAGS_gpu_threading);
+                               gpuConfig->getAlphaType(), sk_ref_sp(gpuConfig->getColorSpace()),
+                               FLAGS_gpu_threading);
         }
     }
 #endif
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 6c441d9..ad9752d 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -1300,15 +1300,17 @@
                  int samples,
                  bool diText,
                  SkColorType colorType,
+                 SkAlphaType alphaType,
                  sk_sp<SkColorSpace> colorSpace,
                  bool threaded)
-    : fContextType(ct)
-    , fContextOverrides(overrides)
-    , fSampleCount(samples)
-    , fUseDIText(diText)
-    , fColorType(colorType)
-    , fColorSpace(std::move(colorSpace))
-    , fThreaded(threaded) {}
+        : fContextType(ct)
+        , fContextOverrides(overrides)
+        , fSampleCount(samples)
+        , fUseDIText(diText)
+        , fColorType(colorType)
+        , fAlphaType(alphaType)
+        , fColorSpace(std::move(colorSpace))
+        , fThreaded(threaded) {}
 
 DEFINE_bool(drawOpClip, false, "Clip each GrDrawOp to its device bounds for testing.");
 
@@ -1319,9 +1321,8 @@
 
     GrContextFactory factory(grOptions);
     const SkISize size = src.size();
-    const SkImageInfo info =
-        SkImageInfo::Make(size.width(), size.height(), fColorType,
-                          kPremul_SkAlphaType, fColorSpace);
+    SkImageInfo info =
+            SkImageInfo::Make(size.width(), size.height(), fColorType, fAlphaType, fColorSpace);
 #if SK_SUPPORT_GPU
     GrContext* context = factory.getContextInfo(fContextType, fContextOverrides).grContext();
     const int maxDimension = context->caps()->maxTextureSize();
@@ -1348,6 +1349,12 @@
         canvas->getGrContext()->dumpCacheStats(log);
         canvas->getGrContext()->dumpGpuStats(log);
     }
+    if (info.colorType() == kRGB_565_SkColorType || info.colorType() == kARGB_4444_SkColorType) {
+        // We don't currently support readbacks into these formats on the GPU backend. Convert to
+        // 32 bit.
+        info = SkImageInfo::Make(size.width(), size.height(), kRGBA_8888_SkColorType,
+                                 kPremul_SkAlphaType, fColorSpace);
+    }
     dst->allocPixels(info);
     canvas->readPixels(*dst, 0, 0);
     if (FLAGS_abandonGpuContext) {
diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h
index 553eac0..f2e4ac2 100644
--- a/dm/DMSrcSink.h
+++ b/dm/DMSrcSink.h
@@ -305,8 +305,8 @@
 class GPUSink : public Sink {
 public:
     GPUSink(sk_gpu_test::GrContextFactory::ContextType,
-            sk_gpu_test::GrContextFactory::ContextOverrides,
-            int samples, bool diText, SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
+            sk_gpu_test::GrContextFactory::ContextOverrides, int samples, bool diText,
+            SkColorType colorType, SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace,
             bool threaded);
 
     Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
@@ -323,6 +323,7 @@
     int                                               fSampleCount;
     bool                                              fUseDIText;
     SkColorType                                       fColorType;
+    SkAlphaType                                       fAlphaType;
     sk_sp<SkColorSpace>                               fColorSpace;
     bool                                              fThreaded;
 };
diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp
index c5db7cb..cb2351e 100644
--- a/src/core/SkGpuBlurUtils.cpp
+++ b/src/core/SkGpuBlurUtils.cpp
@@ -223,9 +223,10 @@
 
     const GrPixelConfig config = srcProxy->config();
 
-    SkASSERT(kBGRA_8888_GrPixelConfig  == config || kRGBA_8888_GrPixelConfig  == config ||
+    SkASSERT(kBGRA_8888_GrPixelConfig == config || kRGBA_8888_GrPixelConfig == config ||
+             kRGBA_4444_GrPixelConfig == config || kRGB_565_GrPixelConfig == config ||
              kSRGBA_8888_GrPixelConfig == config || kSBGRA_8888_GrPixelConfig == config ||
-             kRGBA_half_GrPixelConfig  == config || kAlpha_8_GrPixelConfig    == config);
+             kRGBA_half_GrPixelConfig == config || kAlpha_8_GrPixelConfig == config);
 
     const int width = dstBounds.width();
     const int height = dstBounds.height();
diff --git a/tests/TestConfigParsing.cpp b/tests/TestConfigParsing.cpp
index 6a2607a..e24c019 100644
--- a/tests/TestConfigParsing.cpp
+++ b/tests/TestConfigParsing.cpp
@@ -119,7 +119,9 @@
         "glnarrow",
         "glnostencils",
         "mock",
-        "mtl"
+        "mtl",
+        "gl4444",
+        "gl565"
     });
 
     SkCommandLineConfigArray configs;
@@ -226,6 +228,14 @@
     REPORTER_ASSERT(reporter, configs[19]->asConfigGpu());
     REPORTER_ASSERT(reporter, configs[20]->asConfigGpu());
     REPORTER_ASSERT(reporter, configs[21]->asConfigGpu());
+    REPORTER_ASSERT(reporter, configs[45]->asConfigGpu()->getContextType() ==
+                              GrContextFactory::kGL_ContextType);
+    REPORTER_ASSERT(reporter, configs[45]->asConfigGpu()->getColorType() == kARGB_4444_SkColorType);
+    REPORTER_ASSERT(reporter, configs[45]->asConfigGpu()->getAlphaType() == kPremul_SkAlphaType);
+    REPORTER_ASSERT(reporter, configs[46]->asConfigGpu()->getContextType() ==
+                              GrContextFactory::kGL_ContextType);
+    REPORTER_ASSERT(reporter, configs[46]->asConfigGpu()->getColorType() == kRGB_565_SkColorType);
+    REPORTER_ASSERT(reporter, configs[46]->asConfigGpu()->getAlphaType() == kOpaque_SkAlphaType);
 #if SK_MESA
     REPORTER_ASSERT(reporter, configs[23]->asConfigGpu());
 #else
diff --git a/tools/flags/SkCommonFlagsConfig.cpp b/tools/flags/SkCommonFlagsConfig.cpp
index 3fb5cb9..03b3b96 100644
--- a/tools/flags/SkCommonFlagsConfig.cpp
+++ b/tools/flags/SkCommonFlagsConfig.cpp
@@ -55,6 +55,8 @@
     { "glesinst",              "gpu", "api=gles,inst=true" },
     { "glesinst4",             "gpu", "api=gles,inst=true,samples=4" },
     { "glesinstdit4",          "gpu", "api=gles,inst=true,samples=4,dit=true" },
+    { "gl4444",                "gpu", "api=gl,color=4444" },
+    { "gl565",                 "gpu", "api=gl,color=565" },
     { "glf16",                 "gpu", "api=gl,color=f16" },
     { "glsrgb",                "gpu", "api=gl,color=srgb" },
     { "glsrgbnl",              "gpu", "api=gl,color=srgbnl" },
@@ -151,6 +153,8 @@
     "\t    Select framebuffer color format.\n"
     "\t    Options:\n"
     "\t\t8888\t\t\tLinear 8888.\n"
+    "\t\t4444\t\t\tLinear 4444.\n"
+    "\t\t565\t\t\tLinear 565.\n"
     "\t\tf16{_gamut}\t\tLinear 16-bit floating point.\n"
     "\t\tsrgb{_gamut}\t\tsRGB 8888.\n"
     "\t  gamut\ttype: string\tdefault: srgb.\n"
@@ -195,7 +199,7 @@
 #if SK_SUPPORT_GPU
 SkCommandLineConfigGpu::SkCommandLineConfigGpu(
     const SkString& tag, const SkTArray<SkString>& viaParts, ContextType contextType, bool useNVPR,
-    bool useInstanced, bool useDIText, int samples, SkColorType colorType,
+    bool useInstanced, bool useDIText, int samples, SkColorType colorType, SkAlphaType alphaType,
     sk_sp<SkColorSpace> colorSpace, bool useStencilBuffers)
         : SkCommandLineConfig(tag, SkString("gpu"), viaParts)
         , fContextType(contextType)
@@ -203,6 +207,7 @@
         , fUseDIText(useDIText)
         , fSamples(samples)
         , fColorType(colorType)
+        , fAlphaType(alphaType)
         , fColorSpace(std::move(colorSpace)) {
     if (useNVPR) {
         fContextOverrides |= ContextOverrides::kRequireNVPRSupport;
@@ -320,11 +325,24 @@
 }
 static bool parse_option_gpu_color(const SkString& value,
                                    SkColorType* outColorType,
+                                   SkAlphaType* alphaType,
                                    sk_sp<SkColorSpace>* outColorSpace) {
+    // We always use premul unless the color type is 565.
+    *alphaType = kPremul_SkAlphaType;
+
     if (value.equals("8888")) {
         *outColorType = kRGBA_8888_SkColorType;
         *outColorSpace = nullptr;
         return true;
+    } else if (value.equals("4444")) {
+        *outColorType = kARGB_4444_SkColorType;
+        *outColorSpace = nullptr;
+        return true;
+    } else if (value.equals("565")) {
+        *outColorType = kRGB_565_SkColorType;
+        *alphaType = kOpaque_SkAlphaType;
+        *outColorSpace = nullptr;
+        return true;
     }
 
     SkTArray<SkString> commands;
@@ -397,6 +415,7 @@
     int samples = 0;
     bool seenColor = false;
     SkColorType colorType = kRGBA_8888_SkColorType;
+    SkAlphaType alphaType = kPremul_SkAlphaType;
     sk_sp<SkColorSpace> colorSpace = nullptr;
     bool seenUseStencils = false;
     bool useStencils = true;
@@ -428,7 +447,7 @@
             valueOk = parse_option_int(value, &samples);
             seenSamples = true;
         } else if (key.equals("color") && !seenColor) {
-            valueOk = parse_option_gpu_color(value, &colorType, &colorSpace);
+            valueOk = parse_option_gpu_color(value, &colorType, &alphaType, &colorSpace);
             seenColor = true;
         } else if (key.equals("stencils") && !seenUseStencils) {
             valueOk = parse_option_bool(value, &useStencils);
@@ -442,7 +461,7 @@
         return nullptr;
     }
     return new SkCommandLineConfigGpu(tag, vias, contextType, useNVPR, useInstanced, useDIText,
-                                      samples, colorType, colorSpace, useStencils);
+                                      samples, colorType, alphaType, colorSpace, useStencils);
 }
 #endif
 
diff --git a/tools/flags/SkCommonFlagsConfig.h b/tools/flags/SkCommonFlagsConfig.h
index a3c3b38..77f31c3 100644
--- a/tools/flags/SkCommonFlagsConfig.h
+++ b/tools/flags/SkCommonFlagsConfig.h
@@ -55,8 +55,8 @@
     typedef sk_gpu_test::GrContextFactory::ContextOverrides ContextOverrides;
     SkCommandLineConfigGpu(const SkString& tag, const SkTArray<SkString>& viaParts,
                            ContextType contextType, bool useNVPR, bool useInstanced, bool useDIText,
-                           int samples, SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
-                           bool useStencilBuffers);
+                           int samples, SkColorType colorType, SkAlphaType alphaType,
+                           sk_sp<SkColorSpace> colorSpace, bool useStencilBuffers);
     const SkCommandLineConfigGpu* asConfigGpu() const override { return this; }
     ContextType getContextType() const { return fContextType; }
     ContextOverrides getContextOverrides() const { return fContextOverrides; }
@@ -69,6 +69,7 @@
     bool getUseDIText() const { return fUseDIText; }
     int getSamples() const { return fSamples; }
     SkColorType getColorType() const { return fColorType; }
+    SkAlphaType getAlphaType() const { return fAlphaType; }
     SkColorSpace* getColorSpace() const { return fColorSpace.get(); }
 
   private:
@@ -77,6 +78,7 @@
     bool fUseDIText;
     int fSamples;
     SkColorType fColorType;
+    SkAlphaType fAlphaType;
     sk_sp<SkColorSpace> fColorSpace;
 };
 #endif
diff --git a/tools/skpbench/skpbench.cpp b/tools/skpbench/skpbench.cpp
index 20ba8b4..8898da2 100644
--- a/tools/skpbench/skpbench.cpp
+++ b/tools/skpbench/skpbench.cpp
@@ -300,8 +300,9 @@
     }
 
     // Create a render target.
-    SkImageInfo info = SkImageInfo::Make(width, height, config->getColorType(),
-                                         kPremul_SkAlphaType, sk_ref_sp(config->getColorSpace()));
+    SkImageInfo info =
+            SkImageInfo::Make(width, height, config->getColorType(), config->getAlphaType(),
+                              sk_ref_sp(config->getColorSpace()));
     uint32_t flags = config->getUseDIText() ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag : 0;
     SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
     sk_sp<SkSurface> surface =