Update NDK methods for HARDWARE Bitmaps
Bug: 135133301
Test: I2c1e58c41e49c72fb4bdbc64989da103885d34bf
_getInfo now sets a bit in AndroidBitmapInfo.flags to indicate whether
the Bitmap has Config.HARDWARE.
For a HARDWARE Bitmap, its AHardwareBuffer can now be retrieved with
AndroidBitmap_getHardwareBuffer. Call AHardwareBuffer_acquire on the
buffer so it will not be deleted while the client is using it.
Change-Id: I9240c1928c1478053ecf7c252443a33dbd6fd6db
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 5937283..32a7cf3 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -243,7 +243,8 @@
return localBitmap.valid() ? &localBitmap->bitmap() : nullptr;
}
-SkImageInfo GraphicsJNI::getBitmapInfo(JNIEnv* env, jobject bitmap, uint32_t* outRowBytes) {
+SkImageInfo GraphicsJNI::getBitmapInfo(JNIEnv* env, jobject bitmap, uint32_t* outRowBytes,
+ bool* isHardware) {
SkASSERT(env);
SkASSERT(bitmap);
SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
@@ -252,6 +253,9 @@
if (outRowBytes) {
*outRowBytes = localBitmap->rowBytes();
}
+ if (isHardware) {
+ *isHardware = localBitmap->isHardware();
+ }
return localBitmap->info();
}
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 99034ed..1e49765 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -62,7 +62,8 @@
static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
static android::Bitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
- static SkImageInfo getBitmapInfo(JNIEnv*, jobject bitmap, uint32_t* outRowBytes);
+ static SkImageInfo getBitmapInfo(JNIEnv*, jobject bitmap, uint32_t* outRowBytes,
+ bool* isHardware);
static SkRegion* getNativeRegion(JNIEnv*, jobject region);
/*
diff --git a/core/jni/android/graphics/apex/android_bitmap.cpp b/core/jni/android/graphics/apex/android_bitmap.cpp
index b8e04a7..01a4d9b 100644
--- a/core/jni/android/graphics/apex/android_bitmap.cpp
+++ b/core/jni/android/graphics/apex/android_bitmap.cpp
@@ -78,7 +78,7 @@
}
}
-static uint32_t getInfoFlags(const SkImageInfo& info) {
+static uint32_t getAlphaFlags(const SkImageInfo& info) {
switch (info.alphaType()) {
case kUnknown_SkAlphaType:
LOG_ALWAYS_FATAL("Bitmap has no alpha type");
@@ -92,6 +92,14 @@
}
}
+static uint32_t getInfoFlags(const SkImageInfo& info, bool isHardware) {
+ uint32_t flags = getAlphaFlags(info);
+ if (isHardware) {
+ flags |= ANDROID_BITMAP_FLAGS_IS_HARDWARE;
+ }
+ return flags;
+}
+
ABitmap* ABitmap_copy(ABitmap* srcBitmapHandle, AndroidBitmapFormat dstFormat) {
SkColorType dstColorType = getColorType(dstFormat);
if (srcBitmapHandle && dstColorType != kUnknown_SkColorType) {
@@ -108,19 +116,19 @@
return nullptr;
}
-static AndroidBitmapInfo getInfo(const SkImageInfo& imageInfo, uint32_t rowBytes) {
+static AndroidBitmapInfo getInfo(const SkImageInfo& imageInfo, uint32_t rowBytes, bool isHardware) {
AndroidBitmapInfo info;
info.width = imageInfo.width();
info.height = imageInfo.height();
info.stride = rowBytes;
info.format = getFormat(imageInfo);
- info.flags = getInfoFlags(imageInfo);
+ info.flags = getInfoFlags(imageInfo, isHardware);
return info;
}
AndroidBitmapInfo ABitmap_getInfo(ABitmap* bitmapHandle) {
Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
- return getInfo(bitmap->info(), bitmap->rowBytes());
+ return getInfo(bitmap->info(), bitmap->rowBytes(), bitmap->isHardware());
}
namespace {
@@ -219,8 +227,9 @@
AndroidBitmapInfo ABitmap_getInfoFromJava(JNIEnv* env, jobject bitmapObj) {
uint32_t rowBytes = 0;
- SkImageInfo imageInfo = GraphicsJNI::getBitmapInfo(env, bitmapObj, &rowBytes);
- return getInfo(imageInfo, rowBytes);
+ bool isHardware = false;
+ SkImageInfo imageInfo = GraphicsJNI::getBitmapInfo(env, bitmapObj, &rowBytes, &isHardware);
+ return getInfo(imageInfo, rowBytes, isHardware);
}
void* ABitmap_getPixels(ABitmap* bitmapHandle) {
@@ -378,3 +387,12 @@
return ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
}
}
+
+AHardwareBuffer* ABitmap_getHardwareBuffer(ABitmap* bitmapHandle) {
+ Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
+ AHardwareBuffer* buffer = bitmap->hardwareBuffer();
+ if (buffer) {
+ AHardwareBuffer_acquire(buffer);
+ }
+ return buffer;
+}
diff --git a/core/jni/android/graphics/apex/include/android/graphics/bitmap.h b/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
index 683851d..02ec655 100644
--- a/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
+++ b/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
@@ -21,6 +21,8 @@
#include <jni.h>
#include <sys/cdefs.h>
+struct AHardwareBuffer;
+
__BEGIN_DECLS
/**
@@ -62,6 +64,18 @@
int ABitmap_compress(const AndroidBitmapInfo* info, ADataSpace dataSpace, const void* pixels,
AndroidBitmapCompressFormat format, int32_t quality, void* userContext,
AndroidBitmap_compress_write_fn);
+/**
+ * Retrieve the native object associated with a HARDWARE Bitmap.
+ *
+ * Client must not modify it while a Bitmap is wrapping it.
+ *
+ * @param bitmap Handle to an android.graphics.Bitmap.
+ * @return on success, a pointer to the
+ * AHardwareBuffer associated with bitmap. This acquires
+ * a reference on the buffer, and the client must call
+ * AHardwareBuffer_release when finished with it.
+ */
+AHardwareBuffer* ABitmap_getHardwareBuffer(ABitmap* bitmap);
__END_DECLS
@@ -116,6 +130,7 @@
ADataSpace getDataSpace() const { return ABitmap_getDataSpace(mBitmap); }
void* getPixels() const { return ABitmap_getPixels(mBitmap); }
void notifyPixelsChanged() const { ABitmap_notifyPixelsChanged(mBitmap); }
+ AHardwareBuffer* getHardwareBuffer() const { return ABitmap_getHardwareBuffer(mBitmap); }
private:
// takes ownership of the provided ABitmap
diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp
index ea8a521..4f21ccb 100644
--- a/native/graphics/jni/bitmap.cpp
+++ b/native/graphics/jni/bitmap.cpp
@@ -76,6 +76,21 @@
return ANDROID_BITMAP_RESULT_SUCCESS;
}
+int AndroidBitmap_getHardwareBuffer(JNIEnv* env, jobject jbitmap, AHardwareBuffer** outBuffer) {
+ if (NULL == env || NULL == jbitmap || NULL == outBuffer) {
+ return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
+ }
+
+ android::graphics::Bitmap bitmap(env, jbitmap);
+
+ if (!bitmap.isValid()) {
+ return ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
+ }
+
+ *outBuffer = bitmap.getHardwareBuffer();
+ return *outBuffer == NULL ? ANDROID_BITMAP_RESULT_BAD_PARAMETER : ANDROID_BITMAP_RESULT_SUCCESS;
+}
+
int AndroidBitmap_compress(const AndroidBitmapInfo* info,
int32_t dataSpace,
const void* pixels,
diff --git a/native/graphics/jni/libjnigraphics.map.txt b/native/graphics/jni/libjnigraphics.map.txt
index 6843e7a..2e6c966 100644
--- a/native/graphics/jni/libjnigraphics.map.txt
+++ b/native/graphics/jni/libjnigraphics.map.txt
@@ -22,6 +22,7 @@
AndroidBitmap_lockPixels;
AndroidBitmap_unlockPixels;
AndroidBitmap_compress; # introduced=30
+ AndroidBitmap_getHardwareBuffer; #introduced=30
local:
*;
};