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:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -22,6 +22,7 @@ LIBJNIGRAPHICS {
|
||||
AndroidBitmap_lockPixels;
|
||||
AndroidBitmap_unlockPixels;
|
||||
AndroidBitmap_compress; # introduced=30
|
||||
AndroidBitmap_getHardwareBuffer; #introduced=30
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user