Add RGBA half float texture format.

BUG=skia:3829

Review URL: https://codereview.chromium.org/1148243002
diff --git a/tests/FloatingPointTextureTest.cpp b/tests/FloatingPointTextureTest.cpp
index 69495b4..1adc744 100644
--- a/tests/FloatingPointTextureTest.cpp
+++ b/tests/FloatingPointTextureTest.cpp
@@ -23,32 +23,31 @@
 #include "SkHalf.h"
 
 static const int DEV_W = 100, DEV_H = 100;
-static const int FP_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 4/*RGBA*/;
-static const float kMaxIntegerRepresentableInSPFloatingPoint = 16777216;  // 2 ^ 24
-
 static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H);
 
-DEF_GPUTEST(FloatingPointTextureTest, reporter, factory) {
-    SkTDArray<float> controlPixelData, readBuffer;
-    controlPixelData.setCount(FP_CONTROL_ARRAY_SIZE);
-    readBuffer.setCount(FP_CONTROL_ARRAY_SIZE);
+template <typename T>
+void runFPTest(skiatest::Reporter* reporter, GrContextFactory* factory,
+               T min, T max, T epsilon, T maxInt, int arraySize, GrPixelConfig config) {
+    SkTDArray<T> controlPixelData, readBuffer;
+    controlPixelData.setCount(arraySize);
+    readBuffer.setCount(arraySize);
 
-    for (int i = 0; i < FP_CONTROL_ARRAY_SIZE; i += 4) {
-        controlPixelData[i + 0] = FLT_MIN;
-        controlPixelData[i + 1] = FLT_MAX;
-        controlPixelData[i + 2] = FLT_EPSILON;
-        controlPixelData[i + 3] = kMaxIntegerRepresentableInSPFloatingPoint;
+    for (int i = 0; i < arraySize; i += 4) {
+        controlPixelData[i + 0] = min;
+        controlPixelData[i + 1] = max;
+        controlPixelData[i + 2] = epsilon;
+        controlPixelData[i + 3] = maxInt;
     }
 
     for (int origin = 0; origin < 2; ++origin) {
         for (int glCtxType = 0; glCtxType < GrContextFactory::kGLContextTypeCnt; ++glCtxType) {
             GrSurfaceDesc desc;
-            desc.fFlags  = kRenderTarget_GrSurfaceFlag;
-            desc.fWidth  = DEV_W;
+            desc.fFlags = kRenderTarget_GrSurfaceFlag;
+            desc.fWidth = DEV_W;
             desc.fHeight = DEV_H;
-            desc.fConfig = kRGBA_float_GrPixelConfig;
+            desc.fConfig = config;
             desc.fOrigin = 0 == origin ?
-                kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
+            kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
 
             GrContextFactory::GLContextType type =
                 static_cast<GrContextFactory::GLContextType>(glCtxType);
@@ -56,7 +55,7 @@
                 continue;
             }
             GrContext* context = factory->get(type);
-            if (NULL == context){
+            if (NULL == context) {
                 continue;
             }
 
@@ -68,56 +67,35 @@
             }
             fpTexture->readPixels(0, 0, DEV_W, DEV_H, desc.fConfig, readBuffer.begin(), 0);
             REPORTER_ASSERT(reporter,
-                    0 == memcmp(readBuffer.begin(), controlPixelData.begin(), readBuffer.bytes()));
+                0 == memcmp(readBuffer.begin(), controlPixelData.begin(), readBuffer.bytes()));
         }
     }
 }
 
-static const int HALF_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 1 /*alpha-only*/;
+static const int FP_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 4/*RGBA*/;
+static const float kMaxIntegerRepresentableInSPFloatingPoint = 16777216;  // 2 ^ 24
 
-DEF_GPUTEST(HalfFloatTextureTest, reporter, factory) {
-    SkTDArray<SkHalf> controlPixelData, readBuffer;
-    controlPixelData.setCount(HALF_CONTROL_ARRAY_SIZE);
-    readBuffer.setCount(HALF_CONTROL_ARRAY_SIZE);
+DEF_GPUTEST(FloatingPointTextureTest, reporter, factory) {
+    runFPTest<float>(reporter, factory, FLT_MIN, FLT_MAX, FLT_EPSILON,
+                     kMaxIntegerRepresentableInSPFloatingPoint, 
+                     FP_CONTROL_ARRAY_SIZE, kRGBA_float_GrPixelConfig);
+}
 
-    for (int i = 0; i < HALF_CONTROL_ARRAY_SIZE; i += 4) {
-        controlPixelData[i + 0] = SK_HalfMin;
-        controlPixelData[i + 1] = SK_HalfMax;
-        controlPixelData[i + 2] = SK_HalfEpsilon;
-        controlPixelData[i + 3] = 0x6800;   // 2^11
-    }
+static const int HALF_ALPHA_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 1 /*alpha-only*/;
+static const SkHalf kMaxIntegerRepresentableInHalfFloatingPoint = 0x6800;  // 2 ^ 11
 
-    for (int origin = 0; origin < 2; ++origin) {
-        for (int glCtxType = 0; glCtxType < GrContextFactory::kGLContextTypeCnt; ++glCtxType) {
-            GrSurfaceDesc desc;
-            desc.fFlags  = kRenderTarget_GrSurfaceFlag;
-            desc.fWidth  = DEV_W;
-            desc.fHeight = DEV_H;
-            desc.fConfig = kAlpha_half_GrPixelConfig;
-            desc.fOrigin = 0 == origin ?
-                kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
+DEF_GPUTEST(HalfFloatAlphaTextureTest, reporter, factory) {
+    runFPTest<SkHalf>(reporter, factory, SK_HalfMin, SK_HalfMax, SK_HalfEpsilon,
+        kMaxIntegerRepresentableInHalfFloatingPoint,
+        HALF_ALPHA_CONTROL_ARRAY_SIZE, kAlpha_half_GrPixelConfig);
+}
 
-            GrContextFactory::GLContextType type =
-                static_cast<GrContextFactory::GLContextType>(glCtxType);
-            if (!GrContextFactory::IsRenderingGLContext(type)) {
-                continue;
-            }
-            GrContext* context = factory->get(type);
-            if (NULL == context){
-                continue;
-            }
+static const int HALF_RGBA_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 4 /*RGBA*/;
 
-            SkAutoTUnref<GrTexture> fpTexture(context->textureProvider()->createTexture(
-                desc, false, controlPixelData.begin(), 0));
-            // 16-bit floating point textures are NOT supported everywhere
-            if (NULL == fpTexture) {
-                continue;
-            }
-            fpTexture->readPixels(0, 0, DEV_W, DEV_H, desc.fConfig, readBuffer.begin(), 0);
-            REPORTER_ASSERT(reporter,
-                    0 == memcmp(readBuffer.begin(), controlPixelData.begin(), readBuffer.bytes()));
-        }
-    }
+DEF_GPUTEST(HalfFloatRGBATextureTest, reporter, factory) {
+    runFPTest<SkHalf>(reporter, factory, SK_HalfMin, SK_HalfMax, SK_HalfEpsilon,
+        kMaxIntegerRepresentableInHalfFloatingPoint,
+        HALF_RGBA_CONTROL_ARRAY_SIZE, kRGBA_half_GrPixelConfig);
 }
 
 #endif