From 5a190b19bb2c51dac5c1ddfc78fc0b53a5ff121e Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Tue, 18 Feb 2020 13:52:18 -0500 Subject: [PATCH] Add Bitmap#getHardwareBuffer Bug: 148155907 Bug: 135299581 Test: TODO Hidden for now. We'd like to make it an SDK API eventually (b/148155907). Internal code is currently calling createGraphicBufferHandle. This is not something we plan to expose from the UI rendering module, so add a method to get a HardwareBuffer instead. This is something we were already planning to add. It seems that clients of createGraphicBufferHandle really wanted a Parcelable to pass the HARDWARE Bitmap to another thread. This should satisfy that use case. Change-Id: Id701f7c7eab37830cd7d2cdb929cbe6ba4eca119 --- core/jni/android/graphics/Bitmap.cpp | 26 ++++++++++++++++++++-- graphics/java/android/graphics/Bitmap.java | 14 ++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index ec6e71d9f11f4..130322aaaa459 100755 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -19,10 +19,10 @@ #include #ifdef __ANDROID__ // Layoutlib does not support graphic buffer, parcel or render thread -#include -#include #include +#include #include +#include #endif #include "core_jni_helpers.h" @@ -1029,6 +1029,9 @@ static jobject Bitmap_copyPreserveInternalConfig(JNIEnv* env, jobject, jlong bit #ifdef __ANDROID__ // Layoutlib does not support graphic buffer typedef AHardwareBuffer* (*AHB_from_HB)(JNIEnv*, jobject); AHB_from_HB AHardwareBuffer_fromHardwareBuffer; + +typedef jobject (*AHB_to_HB)(JNIEnv*, AHardwareBuffer*); +AHB_to_HB AHardwareBuffer_toHardwareBuffer; #endif static jobject Bitmap_wrapHardwareBufferBitmap(JNIEnv* env, jobject, jobject hardwareBuffer, @@ -1060,6 +1063,19 @@ static jobject Bitmap_createGraphicBufferHandle(JNIEnv* env, jobject, jlong bitm #endif } +static jobject Bitmap_getHardwareBuffer(JNIEnv* env, jobject, jlong bitmapPtr) { +#ifdef __ANDROID__ // Layoutlib does not support graphic buffer + LocalScopedBitmap bitmapHandle(bitmapPtr); + LOG_ALWAYS_FATAL_IF(!bitmapHandle->isHardware(), + "Hardware config is only supported config in Bitmap_getHardwareBuffer"); + + Bitmap& bitmap = bitmapHandle->bitmap(); + return AHardwareBuffer_toHardwareBuffer(env, bitmap.hardwareBuffer()); +#else + return NULL; +#endif +} + static jboolean Bitmap_isImmutable(CRITICAL_JNI_PARAMS_COMMA jlong bitmapHandle) { LocalScopedBitmap bitmapHolder(bitmapHandle); if (!bitmapHolder.valid()) return JNI_FALSE; @@ -1126,6 +1142,8 @@ static const JNINativeMethod gBitmapMethods[] = { (void*) Bitmap_wrapHardwareBufferBitmap }, { "nativeCreateGraphicBufferHandle", "(J)Landroid/graphics/GraphicBuffer;", (void*) Bitmap_createGraphicBufferHandle }, + { "nativeGetHardwareBuffer", "(J)Landroid/hardware/HardwareBuffer;", + (void*) Bitmap_getHardwareBuffer }, { "nativeComputeColorSpace", "(J)Landroid/graphics/ColorSpace;", (void*)Bitmap_computeColorSpace }, { "nativeSetColorSpace", "(JJ)V", (void*)Bitmap_setColorSpace }, { "nativeIsSRGB", "(J)Z", (void*)Bitmap_isSRGB }, @@ -1150,6 +1168,10 @@ int register_android_graphics_Bitmap(JNIEnv* env) (AHB_from_HB)dlsym(handle_, "AHardwareBuffer_fromHardwareBuffer"); LOG_ALWAYS_FATAL_IF(AHardwareBuffer_fromHardwareBuffer == nullptr, "Failed to find required symbol AHardwareBuffer_fromHardwareBuffer!"); + + AHardwareBuffer_toHardwareBuffer = (AHB_to_HB)dlsym(handle_, "AHardwareBuffer_toHardwareBuffer"); + LOG_ALWAYS_FATAL_IF(AHardwareBuffer_toHardwareBuffer == nullptr, + " Failed to find required symbol AHardwareBuffer_toHardwareBuffer!"); #endif return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods, NELEM(gBitmapMethods)); diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 9c2e95fab4553..c1e7a360fcc5f 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -2243,6 +2243,19 @@ public final class Bitmap implements Parcelable { return nativeCreateGraphicBufferHandle(mNativePtr); } + /** + * @return {@link HardwareBuffer} which is internally used by hardware bitmap + * + * Note: the HardwareBuffer does *not* have an associated {@link ColorSpace}. + * To render this object the same as its rendered with this Bitmap, you + * should also call {@link getColorSpace}. + * + * @hide + */ + public HardwareBuffer getHardwareBuffer() { + return nativeGetHardwareBuffer(mNativePtr); + } + //////////// native methods private static native Bitmap nativeCreate(int[] colors, int offset, @@ -2308,6 +2321,7 @@ public final class Bitmap implements Parcelable { private static native Bitmap nativeWrapHardwareBufferBitmap(HardwareBuffer buffer, long nativeColorSpace); private static native GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap); + private static native HardwareBuffer nativeGetHardwareBuffer(long nativeBitmap); private static native ColorSpace nativeComputeColorSpace(long nativePtr); private static native void nativeSetColorSpace(long nativePtr, long nativeColorSpace); private static native boolean nativeIsSRGB(long nativePtr);