diff options
-rw-r--r-- | core/api/current.txt | 1 | ||||
-rw-r--r-- | core/jni/android/opengl/util.cpp | 6 | ||||
-rw-r--r-- | graphics/java/android/graphics/Bitmap.java | 48 | ||||
-rw-r--r-- | libs/hwui/HardwareBitmapUploader.cpp | 51 | ||||
-rw-r--r-- | libs/hwui/HardwareBitmapUploader.h | 2 | ||||
-rw-r--r-- | libs/hwui/apex/android_bitmap.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/hwui/ImageDecoder.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/jni/BitmapRegionDecoder.cpp | 11 | ||||
-rw-r--r-- | libs/hwui/jni/Graphics.cpp | 32 | ||||
-rw-r--r-- | libs/hwui/jni/GraphicsJNI.h | 21 | ||||
-rw-r--r-- | native/graphics/jni/imagedecoder.cpp | 8 |
11 files changed, 123 insertions, 66 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 78d4b4de5cc7..f4057e5e2b0d 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -15254,6 +15254,7 @@ package android.graphics { enum_constant @Deprecated public static final android.graphics.Bitmap.Config ARGB_4444; enum_constant public static final android.graphics.Bitmap.Config ARGB_8888; enum_constant public static final android.graphics.Bitmap.Config HARDWARE; + enum_constant public static final android.graphics.Bitmap.Config RGBA_1010102; enum_constant public static final android.graphics.Bitmap.Config RGBA_F16; enum_constant public static final android.graphics.Bitmap.Config RGB_565; } diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp index 82601baee914..d8522658d747 100644 --- a/core/jni/android/opengl/util.cpp +++ b/core/jni/android/opengl/util.cpp @@ -643,6 +643,8 @@ static bool checkInternalFormat(int32_t bitmapFormat, int internalformat, int ty return (type == GL_UNSIGNED_SHORT_5_6_5 && internalformat == GL_RGB); case ANDROID_BITMAP_FORMAT_RGBA_F16: return (type == GL_HALF_FLOAT && internalformat == GL_RGBA16F); + case ANDROID_BITMAP_FORMAT_RGBA_1010102: + return (type == GL_UNSIGNED_INT_2_10_10_10_REV && internalformat == GL_RGB10_A2); default: break; } @@ -676,6 +678,8 @@ static int getInternalFormat(int32_t bitmapFormat) { return GL_RGB; case ANDROID_BITMAP_FORMAT_RGBA_F16: return GL_RGBA16F; + case ANDROID_BITMAP_FORMAT_RGBA_1010102: + return GL_RGB10_A2; default: return -1; } @@ -693,6 +697,8 @@ static int getType(int32_t bitmapFormat) { return GL_UNSIGNED_SHORT_5_6_5; case ANDROID_BITMAP_FORMAT_RGBA_F16: return GL_HALF_FLOAT; + case ANDROID_BITMAP_FORMAT_RGBA_1010102: + return GL_UNSIGNED_INT_2_10_10_10_REV; default: return -1; } diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 055e5ad17def..857af11e4ca3 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -458,7 +458,7 @@ public final class Bitmap implements Parcelable { * No color information is stored. * With this configuration, each pixel requires 1 byte of memory. */ - ALPHA_8 (1), + ALPHA_8(1), /** * Each pixel is stored on 2 bytes and only the RGB channels are @@ -479,7 +479,7 @@ public final class Bitmap implements Parcelable { * short color = (R & 0x1f) << 11 | (G & 0x3f) << 5 | (B & 0x1f); * </pre> */ - RGB_565 (3), + RGB_565(3), /** * Each pixel is stored on 2 bytes. The three RGB color channels @@ -501,7 +501,7 @@ public final class Bitmap implements Parcelable { * it is advised to use {@link #ARGB_8888} instead. */ @Deprecated - ARGB_4444 (4), + ARGB_4444(4), /** * Each pixel is stored on 4 bytes. Each channel (RGB and alpha @@ -516,10 +516,10 @@ public final class Bitmap implements Parcelable { * int color = (A & 0xff) << 24 | (B & 0xff) << 16 | (G & 0xff) << 8 | (R & 0xff); * </pre> */ - ARGB_8888 (5), + ARGB_8888(5), /** - * Each pixels is stored on 8 bytes. Each channel (RGB and alpha + * Each pixel is stored on 8 bytes. Each channel (RGB and alpha * for translucency) is stored as a * {@link android.util.Half half-precision floating point value}. * @@ -531,7 +531,7 @@ public final class Bitmap implements Parcelable { * long color = (A & 0xffff) << 48 | (B & 0xffff) << 32 | (G & 0xffff) << 16 | (R & 0xffff); * </pre> */ - RGBA_F16 (6), + RGBA_F16(6), /** * Special configuration, when bitmap is stored only in graphic memory. @@ -540,13 +540,29 @@ public final class Bitmap implements Parcelable { * It is optimal for cases, when the only operation with the bitmap is to draw it on a * screen. */ - HARDWARE (7); + HARDWARE(7), + + /** + * Each pixel is stored on 4 bytes. Each RGB channel is stored with 10 bits of precision + * (1024 possible values). There is an additional alpha channel that is stored with 2 bits + * of precision (4 possible values). + * + * This configuration is suited for wide-gamut and HDR content which does not require alpha + * blending, such that the memory cost is the same as ARGB_8888 while enabling higher color + * precision. + * + * <p>Use this formula to pack into 32 bits:</p> + * <pre class="prettyprint"> + * int color = (A & 0x3) << 30 | (B & 0x3ff) << 20 | (G & 0x3ff) << 10 | (R & 0x3ff); + * </pre> + */ + RGBA_1010102(8); @UnsupportedAppUsage final int nativeInt; private static Config sConfigs[] = { - null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888, RGBA_F16, HARDWARE + null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888, RGBA_F16, HARDWARE, RGBA_1010102 }; Config(int ni) { @@ -1000,8 +1016,8 @@ public final class Bitmap implements Parcelable { * @param width The width of the bitmap * @param height The height of the bitmap * @param config The bitmap config to create. - * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to - * mark the bitmap as opaque. Doing so will clear the bitmap in black + * @param hasAlpha If the bitmap is ARGB_8888, RGBA_16F, or RGBA_1010102 this flag can be + * used to mark the bitmap as opaque. Doing so will clear the bitmap in black * instead of transparent. * * @throws IllegalArgumentException if the width or height are <= 0, or if @@ -1019,8 +1035,8 @@ public final class Bitmap implements Parcelable { * @param width The width of the bitmap * @param height The height of the bitmap * @param config The bitmap config to create. - * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to - * mark the bitmap as opaque. Doing so will clear the bitmap in black + * @param hasAlpha If the bitmap is ARGB_8888, RGBA_16F, or RGBA_1010102 this flag can be + * used to mark the bitmap as opaque. Doing so will clear the bitmap in black * instead of transparent. * @param colorSpace The color space of the bitmap. If the config is {@link Config#RGBA_F16} * and {@link ColorSpace.Named#SRGB sRGB} or @@ -1050,8 +1066,8 @@ public final class Bitmap implements Parcelable { * @param width The width of the bitmap * @param height The height of the bitmap * @param config The bitmap config to create. - * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to - * mark the bitmap as opaque. Doing so will clear the bitmap in black + * @param hasAlpha If the bitmap is ARGB_8888, RGBA_16F, or RGBA_1010102 this flag can be + * used to mark the bitmap as opaque. Doing so will clear the bitmap in black * instead of transparent. * * @throws IllegalArgumentException if the width or height are <= 0, or if @@ -1074,8 +1090,8 @@ public final class Bitmap implements Parcelable { * @param width The width of the bitmap * @param height The height of the bitmap * @param config The bitmap config to create. - * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to - * mark the bitmap as opaque. Doing so will clear the bitmap in black + * @param hasAlpha If the bitmap is ARGB_8888, RGBA_16F, or RGBA_1010102 this flag can be + * used to mark the bitmap as opaque. Doing so will clear the bitmap in black * instead of transparent. * @param colorSpace The color space of the bitmap. If the config is {@link Config#RGBA_F16} * and {@link ColorSpace.Named#SRGB sRGB} or diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp index db3a1081e32c..dd272cd5ff7d 100644 --- a/libs/hwui/HardwareBitmapUploader.cpp +++ b/libs/hwui/HardwareBitmapUploader.cpp @@ -287,29 +287,29 @@ private: std::mutex mVkLock; }; -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 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 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 @@ static FormatInfo determineFormat(const SkBitmap& skBitmap, bool usingGL) { 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 ad7a95a4fa03..34f43cd8a198 100644 --- a/libs/hwui/HardwareBitmapUploader.h +++ b/libs/hwui/HardwareBitmapUploader.h @@ -29,10 +29,12 @@ public: #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 3780ba072308..bc6bc456ba5a 100644 --- a/libs/hwui/apex/android_bitmap.cpp +++ b/libs/hwui/apex/android_bitmap.cpp @@ -57,6 +57,8 @@ static AndroidBitmapFormat getFormat(const SkImageInfo& info) { 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 @@ static SkColorType getColorType(AndroidBitmapFormat format) { 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 @@ int ABitmap_compress(const AndroidBitmapInfo* info, ADataSpace dataSpace, const 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 fc542c81a597..dd68f825b61d 100644 --- a/libs/hwui/hwui/ImageDecoder.cpp +++ b/libs/hwui/hwui/ImageDecoder.cpp @@ -159,6 +159,8 @@ bool ImageDecoder::setOutColorType(SkColorType colorType) { 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 4cc05ef6f13b..1c20415dcc8f 100644 --- a/libs/hwui/jni/BitmapRegionDecoder.cpp +++ b/libs/hwui/jni/BitmapRegionDecoder.cpp @@ -137,9 +137,16 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle, jint in 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 77f46beb2100..33669ac0a34e 100644 --- a/libs/hwui/jni/Graphics.cpp +++ b/libs/hwui/jni/Graphics.cpp @@ -365,6 +365,8 @@ jint GraphicsJNI::colorTypeToLegacyBitmapConfig(SkColorType colorType) { 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 @@ jint GraphicsJNI::colorTypeToLegacyBitmapConfig(SkColorType colorType) { 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 @@ AndroidBitmapFormat GraphicsJNI::getFormatFromConfig(JNIEnv* env, jobject jconfi 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 @@ jobject GraphicsJNI::getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format 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 ba407f2164de..085a905abaf8 100644 --- a/libs/hwui/jni/GraphicsJNI.h +++ b/libs/hwui/jni/GraphicsJNI.h @@ -34,16 +34,17 @@ public: // 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, - - kLastEnum_LegacyBitmapConfig = kHardware_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, + kRGBA_1010102_LegacyBitmapConfig = 8, + + kLastEnum_LegacyBitmapConfig = kRGBA_1010102_LegacyBitmapConfig }; static void setJavaVM(JavaVM* javaVM); diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp index a0f3098ad347..bb25274e3136 100644 --- a/native/graphics/jni/imagedecoder.cpp +++ b/native/graphics/jni/imagedecoder.cpp @@ -198,14 +198,16 @@ static SkColorType getColorType(AndroidBitmapFormat format) { return kGray_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; } } int AImageDecoder_setAndroidBitmapFormat(AImageDecoder* decoder, int32_t format) { - if (!decoder || format < ANDROID_BITMAP_FORMAT_NONE - || format > ANDROID_BITMAP_FORMAT_RGBA_F16) { + if (!decoder || format < ANDROID_BITMAP_FORMAT_NONE || + format > ANDROID_BITMAP_FORMAT_RGBA_1010102) { return ANDROID_IMAGE_DECODER_BAD_PARAMETER; } @@ -290,6 +292,8 @@ static AndroidBitmapFormat getFormat(SkColorType colorType) { 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; } |