Ensure GL & Gralloc both support FP16 before using it

Change-Id: I3bda750b6011d9a69969fc938a230c2445ee8dae
Merged-In: Id8a53885178d698c7b2fd6fc5ea8d4e36ce2ef15
Fixes: 77973662
Test: builds & CTS passes
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index d732a46..013591f 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -266,6 +266,26 @@
     GLuint mTexture = 0;
 };
 
+static bool isFP16Supported(const sk_sp<GrContext>& grContext) {
+    static std::once_flag sOnceFlag;
+    static bool supported = false;
+
+    std::call_once(sOnceFlag, [](const sk_sp<GrContext>& grContext) {
+        if (!grContext->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig)) {
+            supported = false;
+            return;
+        }
+
+        sp<GraphicBuffer> buffer = new GraphicBuffer(1, 1, PIXEL_FORMAT_RGBA_FP16,
+                GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER |
+                        GraphicBuffer::USAGE_SW_READ_NEVER, "tempFp16Buffer");
+        status_t error = buffer->initCheck();
+        supported = !error;
+    }, grContext);
+
+    return supported;
+}
+
 sk_sp<Bitmap> SkiaOpenGLPipeline::allocateHardwareBitmap(renderthread::RenderThread& renderThread,
                                                          SkBitmap& skBitmap) {
     renderThread.eglManager().initialize();
@@ -287,7 +307,7 @@
             type = GL_UNSIGNED_BYTE;
             break;
         case kRGBA_F16_SkColorType:
-            isSupported = grContext->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig);
+            isSupported = isFP16Supported(grContext);
             if (isSupported) {
                 type = GL_HALF_FLOAT;
                 pixelFormat = PIXEL_FORMAT_RGBA_FP16;