From da6c8ffcc594493c3936f83255efccdbf964cd21 Mon Sep 17 00:00:00 2001 From: sergeyv Date: Tue, 22 Nov 2016 18:28:54 -0800 Subject: [PATCH] Introduce Bitmap.Config.Hardware with @hide annotation Test: HardwareBitmapTests bug:30999911 Change-Id: Iaa0e18842704cb6bcd483c63a095dcb22baaf5e0 --- core/jni/android/graphics/BitmapFactory.cpp | 15 ++++++++++++--- core/jni/android/graphics/BitmapRegionDecoder.cpp | 7 ++++++- core/jni/android/graphics/Graphics.cpp | 13 ++++++++++++- core/jni/android/graphics/GraphicsJNI.h | 2 ++ graphics/java/android/graphics/Bitmap.java | 10 ++++++++-- 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index 1ded2c5a99826..2923f94fb7f7c 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -235,6 +235,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding int sampleSize = 1; bool onlyDecodeSize = false; SkColorType prefColorType = kN32_SkColorType; + bool isHardware = false; bool isMutable = false; float scale = 1.0f; bool requireUnpremultiplied = false; @@ -260,6 +261,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding jobject jconfig = env->GetObjectField(options, gOptions_configFieldID); prefColorType = GraphicsJNI::getNativeBitmapColorType(env, jconfig); + isHardware = GraphicsJNI::isHardwareConfig(env, jconfig); isMutable = env->GetBooleanField(options, gOptions_mutableFieldID); requireUnpremultiplied = !env->GetBooleanField(options, gOptions_premultipliedFieldID); javaBitmap = env->GetObjectField(options, gOptions_bitmapFieldID); @@ -352,9 +354,10 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding decodeAllocator = &scaleCheckingAllocator; } else if (javaBitmap != nullptr) { decodeAllocator = &recyclingAllocator; - } else if (willScale) { - // This will allocate pixels using a HeapAllocator, since there will be an extra - // scaling step. + } else if (willScale || isHardware) { + // This will allocate pixels using a HeapAllocator, + // for scale case: there will be an extra scaling step. + // for hardware case: there will be extra swizzling & upload to gralloc step. decodeAllocator = &heapAllocator; } else { decodeAllocator = &defaultAllocator; @@ -539,6 +542,12 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding if (isMutable) bitmapCreateFlags |= android::bitmap::kBitmapCreateFlag_Mutable; if (isPremultiplied) bitmapCreateFlags |= android::bitmap::kBitmapCreateFlag_Premultiplied; + if (isHardware) { + sk_sp hardwareBitmap = Bitmap::allocateHardwareBitmap(outputBitmap); + return bitmap::createBitmap(env, hardwareBitmap.release(), bitmapCreateFlags, + ninePatchChunk, ninePatchInsets, -1); + } + // now create the java bitmap return bitmap::createBitmap(env, defaultAllocator.getStorageObjAndReset(), bitmapCreateFlags, ninePatchChunk, ninePatchInsets, -1); diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp index 115ee72806af8..3b2d5d2c4409b 100644 --- a/core/jni/android/graphics/BitmapRegionDecoder.cpp +++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp @@ -131,12 +131,13 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle, jint in SkColorType colorType = kN32_SkColorType; bool requireUnpremul = false; jobject javaBitmap = NULL; - + bool isHardware = false; // Update the default options with any options supplied by the client. if (NULL != options) { sampleSize = env->GetIntField(options, gOptions_sampleSizeFieldID); jobject jconfig = env->GetObjectField(options, gOptions_configFieldID); colorType = GraphicsJNI::getNativeBitmapColorType(env, jconfig); + isHardware = GraphicsJNI::isHardwareConfig(env, jconfig); requireUnpremul = !env->GetBooleanField(options, gOptions_premultipliedFieldID); javaBitmap = env->GetObjectField(options, gOptions_bitmapFieldID); // The Java options of ditherMode and preferQualityOverSpeed are deprecated. We will @@ -202,6 +203,10 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle, jint in if (!requireUnpremul) { bitmapCreateFlags |= android::bitmap::kBitmapCreateFlag_Premultiplied; } + if (isHardware) { + sk_sp hardwareBitmap = Bitmap::allocateHardwareBitmap(bitmap); + return bitmap::createBitmap(env, hardwareBitmap.release(), bitmapCreateFlags); + } return android::bitmap::createBitmap(env, heapAlloc.getStorageObjAndReset(), bitmapCreateFlags); } diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index 322eed5729406..e740428131be4 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -297,8 +297,9 @@ enum LegacyBitmapConfig { kRGB_565_LegacyBitmapConfig = 3, kARGB_4444_LegacyBitmapConfig = 4, kARGB_8888_LegacyBitmapConfig = 5, + kHardware_LegacyBitmapConfig = 6, - kLastEnum_LegacyBitmapConfig = kARGB_8888_LegacyBitmapConfig + kLastEnum_LegacyBitmapConfig = kHardware_LegacyBitmapConfig }; jint GraphicsJNI::colorTypeToLegacyBitmapConfig(SkColorType colorType) { @@ -327,6 +328,7 @@ SkColorType GraphicsJNI::legacyBitmapConfigToColorType(jint legacyConfig) { kIndex_8_SkColorType, kRGB_565_SkColorType, kARGB_4444_SkColorType, + kN32_SkColorType, kN32_SkColorType }; @@ -355,6 +357,15 @@ SkColorType GraphicsJNI::getNativeBitmapColorType(JNIEnv* env, jobject jconfig) return legacyBitmapConfigToColorType(c); } +bool GraphicsJNI::isHardwareConfig(JNIEnv* env, jobject jconfig) { + SkASSERT(env); + if (NULL == jconfig) { + return false; + } + int c = env->GetIntField(jconfig, gBitmapConfig_nativeInstanceID); + return c == kHardware_LegacyBitmapConfig; +} + android::Canvas* GraphicsJNI::getNativeCanvas(JNIEnv* env, jobject canvas) { SkASSERT(env); SkASSERT(canvas); diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h index aaa8db91a4b9f..ced9939774a94 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -68,6 +68,8 @@ public: */ static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig); + static bool isHardwareConfig(JNIEnv* env, jobject jconfig); + static jobject createRegion(JNIEnv* env, SkRegion* region); static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap); diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index e628cf8af89da..756087c75db0d 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -463,12 +463,18 @@ public final class Bitmap implements Parcelable { * This configuration is very flexible and offers the best * quality. It should be used whenever possible. */ - ARGB_8888 (5); + ARGB_8888 (5), + + + /** + * @hide + */ + HARDWARE (6); final int nativeInt; private static Config sConfigs[] = { - null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888 + null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888, HARDWARE }; Config(int ni) {