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
This commit is contained in:
Leon Scroggins III
2020-01-19 19:27:16 -05:00
parent 380f3c9ae6
commit 84a2afcbfb
6 changed files with 62 additions and 8 deletions

View File

@@ -243,7 +243,8 @@ Bitmap* GraphicsJNI::getNativeBitmap(JNIEnv* env, jobject bitmap) {
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 @@ SkImageInfo GraphicsJNI::getBitmapInfo(JNIEnv* env, jobject bitmap, uint32_t* ou
if (outRowBytes) {
*outRowBytes = localBitmap->rowBytes();
}
if (isHardware) {
*isHardware = localBitmap->isHardware();
}
return localBitmap->info();
}

View File

@@ -62,7 +62,8 @@ public:
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);
/*

View File

@@ -78,7 +78,7 @@ static SkColorType getColorType(AndroidBitmapFormat format) {
}
}
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) {
}
}
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 @@ ABitmap* ABitmap_copy(ABitmap* srcBitmapHandle, AndroidBitmapFormat dstFormat) {
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 @@ ADataSpace ABitmap_getDataSpace(ABitmap* bitmapHandle) {
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 @@ int ABitmap_compress(const AndroidBitmapInfo* info, ADataSpace dataSpace, const
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;
}

View File

@@ -21,6 +21,8 @@
#include <jni.h>
#include <sys/cdefs.h>
struct AHardwareBuffer;
__BEGIN_DECLS
/**
@@ -62,6 +64,18 @@ jobject ABitmapConfig_getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat forma
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 @@ namespace graphics {
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

View File

@@ -76,6 +76,21 @@ int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap) {
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,

View File

@@ -22,6 +22,7 @@ LIBJNIGRAPHICS {
AndroidBitmap_lockPixels;
AndroidBitmap_unlockPixels;
AndroidBitmap_compress; # introduced=30
AndroidBitmap_getHardwareBuffer; #introduced=30
local:
*;
};