Support premul/unpremul of F16 during read/writePixels

Added PremulOutput and UnpremulOutput FP helpers. These are used
(rather than GrConfigConversionEffect) when working with FP16
textures (and will also be used for other configs that can't be
round-tripped via rounding).

BUG=skia:5853

Change-Id: I101592c26c4f0b379d5e5a8678ef7b2f08e6ad56
Reviewed-on: https://skia-review.googlesource.com/9980
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/include/gpu/GrColor.h b/include/gpu/GrColor.h
index 64368b9..ad66523 100644
--- a/include/gpu/GrColor.h
+++ b/include/gpu/GrColor.h
@@ -259,6 +259,15 @@
         float a = fRGBA[3];
         return GrColor4f(fRGBA[0] * a, fRGBA[1] * a, fRGBA[2] * a, a);
     }
+
+    GrColor4f unpremul() const {
+        float a = fRGBA[3];
+        if (a <= 0.0f) {
+            return GrColor4f(0.0f, 0.0f, 0.0f, 0.0f);
+        }
+        float invAlpha = 1.0f / a;
+        return GrColor4f(fRGBA[0] * invAlpha, fRGBA[1] * invAlpha, fRGBA[2] * invAlpha, a);
+    }
 };
 
 /**
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 57500cd..678add7 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -432,9 +432,9 @@
     /** Called before either of the above two functions to determine the appropriate fragment
         processors for conversions. */
     void testPMConversionsIfNecessary(uint32_t flags);
-    /** Returns true if we've already determined that createPMtoUPMEffect and createUPMToPMEffect
-        will fail. In such cases fall back to SW conversion. */
-    bool didFailPMUPMConversionTest() const;
+    /** Returns true if we've determined that createPMtoUPMEffect and createUPMToPMEffect will
+        succeed for the passed in config. Otherwise we fall back to SW conversion. */
+    bool validPMUPMConversionExists(GrPixelConfig) const;
 
     /**
      * A callback similar to the above for use by the TextBlobCache
diff --git a/include/gpu/GrFragmentProcessor.h b/include/gpu/GrFragmentProcessor.h
index 55dc08f..faf17c1 100644
--- a/include/gpu/GrFragmentProcessor.h
+++ b/include/gpu/GrFragmentProcessor.h
@@ -56,6 +56,18 @@
     static sk_sp<GrFragmentProcessor> PremulInput(sk_sp<GrFragmentProcessor>);
 
     /**
+     *  Returns a fragment processor that calls the passed in fragment processor, and then premuls
+     *  the output.
+     */
+    static sk_sp<GrFragmentProcessor> PremulOutput(sk_sp<GrFragmentProcessor>);
+
+    /**
+     *  Returns a fragment processor that calls the passed in fragment processor, and then unpremuls
+     *  the output.
+     */
+    static sk_sp<GrFragmentProcessor> UnpremulOutput(sk_sp<GrFragmentProcessor>);
+
+    /**
      * Returns a fragment processor that runs the passed in array of fragment processors in a
      * series. The original input is passed to the first, the first's output is passed to the
      * second, etc. The output of the returned processor is the output of the last processor of the