Expose 1010102 config for bitmap

Bug: 200307898
Test: CtsGraphicsTestCases
Change-Id: I33153e080292a95c0cc3d6edada8b274f0b06ac7
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp
index db3a108..dd272cd 100644
--- a/libs/hwui/HardwareBitmapUploader.cpp
+++ b/libs/hwui/HardwareBitmapUploader.cpp
@@ -287,29 +287,29 @@
     std::mutex mVkLock;
 };
 
+static bool checkSupport(AHardwareBuffer_Format format) {
+    AHardwareBuffer_Desc desc = {
+            .width = 1,
+            .height = 1,
+            .layers = 1,
+            .format = format,
+            .usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER | AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
+                     AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE,
+    };
+    UniqueAHardwareBuffer buffer = allocateAHardwareBuffer(desc);
+    return buffer != nullptr;
+}
+
 bool HardwareBitmapUploader::hasFP16Support() {
-    static std::once_flag sOnce;
-    static bool hasFP16Support = false;
-
-    // Gralloc shouldn't let us create a USAGE_HW_TEXTURE if GLES is unable to consume it, so
-    // we don't need to double-check the GLES version/extension.
-    std::call_once(sOnce, []() {
-        AHardwareBuffer_Desc desc = {
-                .width = 1,
-                .height = 1,
-                .layers = 1,
-                .format = AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT,
-                .usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
-                         AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
-                         AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE,
-        };
-        UniqueAHardwareBuffer buffer = allocateAHardwareBuffer(desc);
-        hasFP16Support = buffer != nullptr;
-    });
-
+    static bool hasFP16Support = checkSupport(AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT);
     return hasFP16Support;
 }
 
+bool HardwareBitmapUploader::has1010102Support() {
+    static bool has101012Support = checkSupport(AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM);
+    return has101012Support;
+}
+
 static FormatInfo determineFormat(const SkBitmap& skBitmap, bool usingGL) {
     FormatInfo formatInfo;
     switch (skBitmap.info().colorType()) {
@@ -350,6 +350,19 @@
             formatInfo.type = GL_UNSIGNED_BYTE;
             formatInfo.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
             break;
+        case kRGBA_1010102_SkColorType:
+            formatInfo.isSupported = HardwareBitmapUploader::has1010102Support();
+            if (formatInfo.isSupported) {
+                formatInfo.type = GL_UNSIGNED_INT_2_10_10_10_REV;
+                formatInfo.bufferFormat = AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
+                formatInfo.vkFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
+            } else {
+                formatInfo.type = GL_UNSIGNED_BYTE;
+                formatInfo.bufferFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+                formatInfo.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
+            }
+            formatInfo.format = GL_RGBA;
+            break;
         default:
             ALOGW("unable to create hardware bitmap of colortype: %d", skBitmap.info().colorType());
             formatInfo.valid = false;
diff --git a/libs/hwui/HardwareBitmapUploader.h b/libs/hwui/HardwareBitmapUploader.h
index ad7a95a..34f43cd 100644
--- a/libs/hwui/HardwareBitmapUploader.h
+++ b/libs/hwui/HardwareBitmapUploader.h
@@ -29,10 +29,12 @@
 
 #ifdef __ANDROID__
     static bool hasFP16Support();
+    static bool has1010102Support();
 #else
     static bool hasFP16Support() {
         return true;
     }
+    static bool has1010102Support() { return true; }
 #endif
 };
 
diff --git a/libs/hwui/apex/android_bitmap.cpp b/libs/hwui/apex/android_bitmap.cpp
index 3780ba0..bc6bc45 100644
--- a/libs/hwui/apex/android_bitmap.cpp
+++ b/libs/hwui/apex/android_bitmap.cpp
@@ -57,6 +57,8 @@
             return ANDROID_BITMAP_FORMAT_A_8;
         case kRGBA_F16_SkColorType:
             return ANDROID_BITMAP_FORMAT_RGBA_F16;
+        case kRGBA_1010102_SkColorType:
+            return ANDROID_BITMAP_FORMAT_RGBA_1010102;
         default:
             return ANDROID_BITMAP_FORMAT_NONE;
     }
@@ -74,6 +76,8 @@
             return kAlpha_8_SkColorType;
         case ANDROID_BITMAP_FORMAT_RGBA_F16:
             return kRGBA_F16_SkColorType;
+        case ANDROID_BITMAP_FORMAT_RGBA_1010102:
+            return kRGBA_1010102_SkColorType;
         default:
             return kUnknown_SkColorType;
     }
@@ -249,6 +253,9 @@
         case ANDROID_BITMAP_FORMAT_RGBA_F16:
             colorType = kRGBA_F16_SkColorType;
             break;
+        case ANDROID_BITMAP_FORMAT_RGBA_1010102:
+            colorType = kRGBA_1010102_SkColorType;
+            break;
         default:
             return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
     }
diff --git a/libs/hwui/hwui/ImageDecoder.cpp b/libs/hwui/hwui/ImageDecoder.cpp
index fc542c8..dd68f82 100644
--- a/libs/hwui/hwui/ImageDecoder.cpp
+++ b/libs/hwui/hwui/ImageDecoder.cpp
@@ -159,6 +159,8 @@
             break;
         case kRGBA_F16_SkColorType:
             break;
+        case kRGBA_1010102_SkColorType:
+            break;
         default:
             return false;
     }
diff --git a/libs/hwui/jni/BitmapRegionDecoder.cpp b/libs/hwui/jni/BitmapRegionDecoder.cpp
index 4cc05ef..1c20415 100644
--- a/libs/hwui/jni/BitmapRegionDecoder.cpp
+++ b/libs/hwui/jni/BitmapRegionDecoder.cpp
@@ -137,9 +137,16 @@
 
     auto* brd = reinterpret_cast<skia::BitmapRegionDecoder*>(brdHandle);
     SkColorType decodeColorType = brd->computeOutputColorType(colorType);
-    if (decodeColorType == kRGBA_F16_SkColorType && isHardware &&
+
+    if (isHardware) {
+        if (decodeColorType == kRGBA_F16_SkColorType &&
             !uirenderer::HardwareBitmapUploader::hasFP16Support()) {
-        decodeColorType = kN32_SkColorType;
+            decodeColorType = kN32_SkColorType;
+        }
+        if (decodeColorType == kRGBA_1010102_SkColorType &&
+            !uirenderer::HardwareBitmapUploader::has1010102Support()) {
+            decodeColorType = kN32_SkColorType;
+        }
     }
 
     // Set up the pixel allocator
diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp
index 77f46be..33669ac 100644
--- a/libs/hwui/jni/Graphics.cpp
+++ b/libs/hwui/jni/Graphics.cpp
@@ -365,6 +365,8 @@
             return kRGB_565_LegacyBitmapConfig;
         case kAlpha_8_SkColorType:
             return kA8_LegacyBitmapConfig;
+        case kRGBA_1010102_SkColorType:
+            return kRGBA_1010102_LegacyBitmapConfig;
         case kUnknown_SkColorType:
         default:
             break;
@@ -374,14 +376,10 @@
 
 SkColorType GraphicsJNI::legacyBitmapConfigToColorType(jint legacyConfig) {
     const uint8_t gConfig2ColorType[] = {
-        kUnknown_SkColorType,
-        kAlpha_8_SkColorType,
-        kUnknown_SkColorType, // Previously kIndex_8_SkColorType,
-        kRGB_565_SkColorType,
-        kARGB_4444_SkColorType,
-        kN32_SkColorType,
-        kRGBA_F16_SkColorType,
-        kN32_SkColorType
+            kUnknown_SkColorType,  kAlpha_8_SkColorType,
+            kUnknown_SkColorType,  // Previously kIndex_8_SkColorType,
+            kRGB_565_SkColorType,  kARGB_4444_SkColorType, kN32_SkColorType,
+            kRGBA_F16_SkColorType, kN32_SkColorType,       kRGBA_1010102_SkColorType,
     };
 
     if (legacyConfig < 0 || legacyConfig > kLastEnum_LegacyBitmapConfig) {
@@ -399,15 +397,12 @@
     jint javaConfigId = env->GetIntField(jconfig, gBitmapConfig_nativeInstanceID);
 
     const AndroidBitmapFormat config2BitmapFormat[] = {
-        ANDROID_BITMAP_FORMAT_NONE,
-        ANDROID_BITMAP_FORMAT_A_8,
-        ANDROID_BITMAP_FORMAT_NONE, // Previously Config.Index_8
-        ANDROID_BITMAP_FORMAT_RGB_565,
-        ANDROID_BITMAP_FORMAT_RGBA_4444,
-        ANDROID_BITMAP_FORMAT_RGBA_8888,
-        ANDROID_BITMAP_FORMAT_RGBA_F16,
-        ANDROID_BITMAP_FORMAT_NONE // Congfig.HARDWARE
-    };
+            ANDROID_BITMAP_FORMAT_NONE,        ANDROID_BITMAP_FORMAT_A_8,
+            ANDROID_BITMAP_FORMAT_NONE,  // Previously Config.Index_8
+            ANDROID_BITMAP_FORMAT_RGB_565,     ANDROID_BITMAP_FORMAT_RGBA_4444,
+            ANDROID_BITMAP_FORMAT_RGBA_8888,   ANDROID_BITMAP_FORMAT_RGBA_F16,
+            ANDROID_BITMAP_FORMAT_NONE,  // Congfig.HARDWARE
+            ANDROID_BITMAP_FORMAT_RGBA_1010102};
     return config2BitmapFormat[javaConfigId];
 }
 
@@ -430,6 +425,9 @@
       case ANDROID_BITMAP_FORMAT_RGBA_F16:
         configId = kRGBA_16F_LegacyBitmapConfig;
         break;
+      case ANDROID_BITMAP_FORMAT_RGBA_1010102:
+          configId = kRGBA_1010102_LegacyBitmapConfig;
+          break;
       default:
         break;
     }
diff --git a/libs/hwui/jni/GraphicsJNI.h b/libs/hwui/jni/GraphicsJNI.h
index ba407f2..085a905 100644
--- a/libs/hwui/jni/GraphicsJNI.h
+++ b/libs/hwui/jni/GraphicsJNI.h
@@ -34,16 +34,17 @@
     // This enum must keep these int values, to match the int values
     // in the java Bitmap.Config enum.
     enum LegacyBitmapConfig {
-        kNo_LegacyBitmapConfig          = 0,
-        kA8_LegacyBitmapConfig          = 1,
-        kIndex8_LegacyBitmapConfig      = 2,
-        kRGB_565_LegacyBitmapConfig     = 3,
-        kARGB_4444_LegacyBitmapConfig   = 4,
-        kARGB_8888_LegacyBitmapConfig   = 5,
-        kRGBA_16F_LegacyBitmapConfig    = 6,
-        kHardware_LegacyBitmapConfig    = 7,
+        kNo_LegacyBitmapConfig = 0,
+        kA8_LegacyBitmapConfig = 1,
+        kIndex8_LegacyBitmapConfig = 2,
+        kRGB_565_LegacyBitmapConfig = 3,
+        kARGB_4444_LegacyBitmapConfig = 4,
+        kARGB_8888_LegacyBitmapConfig = 5,
+        kRGBA_16F_LegacyBitmapConfig = 6,
+        kHardware_LegacyBitmapConfig = 7,
+        kRGBA_1010102_LegacyBitmapConfig = 8,
 
-        kLastEnum_LegacyBitmapConfig = kHardware_LegacyBitmapConfig
+        kLastEnum_LegacyBitmapConfig = kRGBA_1010102_LegacyBitmapConfig
     };
 
     static void setJavaVM(JavaVM* javaVM);