Consolidate NDK and APEX implementations
the NDK APIs are implemented in terms of the APEX APIs to reduce the number of different implementations serving the same fundamental purpose. Bug: 137655431 Test: CtsGraphicsTestCases Change-Id: Idc7b85403a7e546843b9c1d822acc0a1e740059a
This commit is contained in:
@@ -223,97 +223,11 @@ void toSkBitmap(jlong bitmapHandle, SkBitmap* outBitmap) {
|
||||
bitmap->getSkBitmap(outBitmap);
|
||||
}
|
||||
|
||||
Bitmap& toBitmap(JNIEnv* env, jobject bitmap) {
|
||||
SkASSERT(env);
|
||||
SkASSERT(bitmap);
|
||||
SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
|
||||
jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
|
||||
LocalScopedBitmap localBitmap(bitmapHandle);
|
||||
return localBitmap->bitmap();
|
||||
}
|
||||
|
||||
Bitmap& toBitmap(jlong bitmapHandle) {
|
||||
LocalScopedBitmap localBitmap(bitmapHandle);
|
||||
return localBitmap->bitmap();
|
||||
}
|
||||
|
||||
void imageInfo(JNIEnv* env, jobject bitmap, AndroidBitmapInfo* info) {
|
||||
jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
|
||||
LocalScopedBitmap localBitmap(bitmapHandle);
|
||||
|
||||
const SkImageInfo& imageInfo = localBitmap->info();
|
||||
info->width = imageInfo.width();
|
||||
info->height = imageInfo.height();
|
||||
info->stride = localBitmap->rowBytes();
|
||||
info->flags = 0;
|
||||
switch (imageInfo.colorType()) {
|
||||
case kN32_SkColorType:
|
||||
info->format = ANDROID_BITMAP_FORMAT_RGBA_8888;
|
||||
break;
|
||||
case kRGB_565_SkColorType:
|
||||
info->format = ANDROID_BITMAP_FORMAT_RGB_565;
|
||||
break;
|
||||
case kARGB_4444_SkColorType:
|
||||
info->format = ANDROID_BITMAP_FORMAT_RGBA_4444;
|
||||
break;
|
||||
case kAlpha_8_SkColorType:
|
||||
info->format = ANDROID_BITMAP_FORMAT_A_8;
|
||||
break;
|
||||
case kRGBA_F16_SkColorType:
|
||||
info->format = ANDROID_BITMAP_FORMAT_RGBA_F16;
|
||||
break;
|
||||
default:
|
||||
info->format = ANDROID_BITMAP_FORMAT_NONE;
|
||||
break;
|
||||
}
|
||||
switch (imageInfo.alphaType()) {
|
||||
case kUnknown_SkAlphaType:
|
||||
LOG_ALWAYS_FATAL("Bitmap has no alpha type");
|
||||
break;
|
||||
case kOpaque_SkAlphaType:
|
||||
info->flags |= ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE;
|
||||
break;
|
||||
case kPremul_SkAlphaType:
|
||||
info->flags |= ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
|
||||
break;
|
||||
case kUnpremul_SkAlphaType:
|
||||
info->flags |= ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void* lockPixels(JNIEnv* env, jobject bitmap) {
|
||||
SkASSERT(env);
|
||||
SkASSERT(bitmap);
|
||||
SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
|
||||
jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
|
||||
|
||||
LocalScopedBitmap localBitmap(bitmapHandle);
|
||||
if (!localBitmap->valid()) return nullptr;
|
||||
|
||||
SkPixelRef& pixelRef = localBitmap->bitmap();
|
||||
if (!pixelRef.pixels()) {
|
||||
return nullptr;
|
||||
}
|
||||
pixelRef.ref();
|
||||
return pixelRef.pixels();
|
||||
}
|
||||
|
||||
bool unlockPixels(JNIEnv* env, jobject bitmap) {
|
||||
SkASSERT(env);
|
||||
SkASSERT(bitmap);
|
||||
SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
|
||||
jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
|
||||
|
||||
LocalScopedBitmap localBitmap(bitmapHandle);
|
||||
if (!localBitmap->valid()) return false;
|
||||
|
||||
SkPixelRef& pixelRef = localBitmap->bitmap();
|
||||
pixelRef.notifyPixelsChanged();
|
||||
pixelRef.unref();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace bitmap
|
||||
|
||||
} // namespace android
|
||||
@@ -321,6 +235,27 @@ bool unlockPixels(JNIEnv* env, jobject bitmap) {
|
||||
using namespace android;
|
||||
using namespace android::bitmap;
|
||||
|
||||
Bitmap* GraphicsJNI::getNativeBitmap(JNIEnv* env, jobject bitmap) {
|
||||
SkASSERT(env);
|
||||
SkASSERT(bitmap);
|
||||
SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
|
||||
jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
|
||||
LocalScopedBitmap localBitmap(bitmapHandle);
|
||||
return localBitmap.valid() ? &localBitmap->bitmap() : nullptr;
|
||||
}
|
||||
|
||||
SkImageInfo GraphicsJNI::getBitmapInfo(JNIEnv* env, jobject bitmap, uint32_t* outRowBytes) {
|
||||
SkASSERT(env);
|
||||
SkASSERT(bitmap);
|
||||
SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
|
||||
jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
|
||||
LocalScopedBitmap localBitmap(bitmapHandle);
|
||||
if (outRowBytes) {
|
||||
*outRowBytes = localBitmap->rowBytes();
|
||||
}
|
||||
return localBitmap->info();
|
||||
}
|
||||
|
||||
bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride,
|
||||
int x, int y, int width, int height, SkBitmap* dstBitmap) {
|
||||
const jint* array = env->GetIntArrayElements(srcColors, NULL);
|
||||
|
||||
@@ -38,17 +38,8 @@ jobject createBitmap(JNIEnv* env, Bitmap* bitmap,
|
||||
int bitmapCreateFlags, jbyteArray ninePatchChunk = nullptr,
|
||||
jobject ninePatchInsets = nullptr, int density = -1);
|
||||
|
||||
|
||||
Bitmap& toBitmap(JNIEnv* env, jobject bitmap);
|
||||
Bitmap& toBitmap(jlong bitmapHandle);
|
||||
|
||||
// NDK access
|
||||
void imageInfo(JNIEnv* env, jobject bitmap, AndroidBitmapInfo* info);
|
||||
// Returns a pointer to the pixels or nullptr if the bitmap is not valid
|
||||
void* lockPixels(JNIEnv* env, jobject bitmap);
|
||||
// Returns true if unlocked, false if the bitmap is no longer valid (destroyed)
|
||||
bool unlockPixels(JNIEnv* env, jobject bitmap);
|
||||
|
||||
/** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in
|
||||
sync with isPremultiplied
|
||||
*/
|
||||
|
||||
@@ -342,10 +342,6 @@ SkColorType GraphicsJNI::legacyBitmapConfigToColorType(jint legacyConfig) {
|
||||
return static_cast<SkColorType>(gConfig2ColorType[legacyConfig]);
|
||||
}
|
||||
|
||||
void GraphicsJNI::getSkBitmap(JNIEnv* env, jobject bitmap, SkBitmap* outBitmap) {
|
||||
bitmap::toBitmap(env, bitmap).getSkBitmap(outBitmap);
|
||||
}
|
||||
|
||||
AndroidBitmapFormat GraphicsJNI::getFormatFromConfig(JNIEnv* env, jobject jconfig) {
|
||||
ALOG_ASSERT(env);
|
||||
if (NULL == jconfig) {
|
||||
|
||||
@@ -61,7 +61,8 @@ public:
|
||||
static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
|
||||
|
||||
static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
|
||||
static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap);
|
||||
static android::Bitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
|
||||
static SkImageInfo getBitmapInfo(JNIEnv*, jobject bitmap, uint32_t* outRowBytes);
|
||||
static SkRegion* getNativeRegion(JNIEnv*, jobject region);
|
||||
|
||||
/*
|
||||
|
||||
@@ -14,19 +14,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "Bitmap"
|
||||
#include <log/log.h>
|
||||
|
||||
#include "android/graphics/bitmap.h"
|
||||
#include "Bitmap.h"
|
||||
#include "TypeCast.h"
|
||||
#include "GraphicsJNI.h"
|
||||
|
||||
#include <GraphicsJNI.h>
|
||||
#include <hwui/Bitmap.h>
|
||||
|
||||
using namespace android;
|
||||
|
||||
ABitmap* ABitmap_acquireBitmapFromJava(JNIEnv* env, jobject bitmapObj) {
|
||||
Bitmap& bitmap = android::bitmap::toBitmap(env, bitmapObj);
|
||||
bitmap.ref();
|
||||
return TypeCast::toABitmap(&bitmap);
|
||||
Bitmap* bitmap = GraphicsJNI::getNativeBitmap(env, bitmapObj);
|
||||
if (bitmap) {
|
||||
bitmap->ref();
|
||||
return TypeCast::toABitmap(bitmap);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ABitmap_acquireRef(ABitmap* bitmap) {
|
||||
@@ -37,8 +43,8 @@ void ABitmap_releaseRef(ABitmap* bitmap) {
|
||||
SkSafeUnref(TypeCast::toBitmap(bitmap));
|
||||
}
|
||||
|
||||
static AndroidBitmapFormat getFormat(Bitmap* bitmap) {
|
||||
switch (bitmap->colorType()) {
|
||||
static AndroidBitmapFormat getFormat(const SkImageInfo& info) {
|
||||
switch (info.colorType()) {
|
||||
case kN32_SkColorType:
|
||||
return ANDROID_BITMAP_FORMAT_RGBA_8888;
|
||||
case kRGB_565_SkColorType:
|
||||
@@ -71,6 +77,20 @@ static SkColorType getColorType(AndroidBitmapFormat format) {
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t getInfoFlags(const SkImageInfo& info) {
|
||||
switch (info.alphaType()) {
|
||||
case kUnknown_SkAlphaType:
|
||||
LOG_ALWAYS_FATAL("Bitmap has no alpha type");
|
||||
break;
|
||||
case kOpaque_SkAlphaType:
|
||||
return ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE;
|
||||
case kPremul_SkAlphaType:
|
||||
return ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
|
||||
case kUnpremul_SkAlphaType:
|
||||
return ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL;
|
||||
}
|
||||
}
|
||||
|
||||
ABitmap* ABitmap_copy(ABitmap* srcBitmapHandle, AndroidBitmapFormat dstFormat) {
|
||||
SkColorType dstColorType = getColorType(dstFormat);
|
||||
if (srcBitmapHandle && dstColorType != kUnknown_SkColorType) {
|
||||
@@ -87,15 +107,25 @@ ABitmap* ABitmap_copy(ABitmap* srcBitmapHandle, AndroidBitmapFormat dstFormat) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static AndroidBitmapInfo getInfo(const SkImageInfo& imageInfo, uint32_t rowBytes) {
|
||||
AndroidBitmapInfo info;
|
||||
info.width = imageInfo.width();
|
||||
info.height = imageInfo.height();
|
||||
info.stride = rowBytes;
|
||||
info.format = getFormat(imageInfo);
|
||||
info.flags = getInfoFlags(imageInfo);
|
||||
return info;
|
||||
}
|
||||
|
||||
AndroidBitmapInfo ABitmap_getInfo(ABitmap* bitmapHandle) {
|
||||
Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
|
||||
return getInfo(bitmap->info(), bitmap->rowBytes());
|
||||
}
|
||||
|
||||
AndroidBitmapInfo info;
|
||||
info.width = bitmap->width();
|
||||
info.height = bitmap->height();
|
||||
info.stride = bitmap->rowBytes();
|
||||
info.format = getFormat(bitmap);
|
||||
return info;
|
||||
AndroidBitmapInfo ABitmap_getInfoFromJava(JNIEnv* env, jobject bitmapObj) {
|
||||
uint32_t rowBytes = 0;
|
||||
SkImageInfo imageInfo = GraphicsJNI::getBitmapInfo(env, bitmapObj, &rowBytes);
|
||||
return getInfo(imageInfo, rowBytes);
|
||||
}
|
||||
|
||||
void* ABitmap_getPixels(ABitmap* bitmapHandle) {
|
||||
@@ -107,9 +137,17 @@ void* ABitmap_getPixels(ABitmap* bitmapHandle) {
|
||||
}
|
||||
|
||||
AndroidBitmapFormat ABitmapConfig_getFormatFromConfig(JNIEnv* env, jobject bitmapConfigObj) {
|
||||
return GraphicsJNI::getFormatFromConfig(env, bitmapConfigObj);
|
||||
return GraphicsJNI::getFormatFromConfig(env, bitmapConfigObj);
|
||||
}
|
||||
|
||||
jobject ABitmapConfig_getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format) {
|
||||
return GraphicsJNI::getConfigFromFormat(env, format);
|
||||
return GraphicsJNI::getConfigFromFormat(env, format);
|
||||
}
|
||||
|
||||
void ABitmap_notifyPixelsChanged(ABitmap* bitmapHandle) {
|
||||
Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle);
|
||||
if (bitmap->isImmutable()) {
|
||||
ALOGE("Attempting to modify an immutable Bitmap!");
|
||||
}
|
||||
return bitmap->notifyPixelsChanged();
|
||||
}
|
||||
|
||||
@@ -27,6 +27,20 @@ __BEGIN_DECLS
|
||||
*/
|
||||
typedef struct ABitmap ABitmap;
|
||||
|
||||
/**
|
||||
* Retrieve bitmapInfo for the provided java bitmap even if it has been recycled. In the case of a
|
||||
* recycled bitmap the values contained in the bitmap before it was recycled are returned.
|
||||
*
|
||||
* NOTE: This API does not need to remain as an APEX API if/when we pull libjnigraphics into the
|
||||
* UI module.
|
||||
*/
|
||||
AndroidBitmapInfo ABitmap_getInfoFromJava(JNIEnv* env, jobject bitmapObj);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return ptr to an opaque handle to the native bitmap or null if the java bitmap has been recycled
|
||||
* or does not exist.
|
||||
*/
|
||||
ABitmap* ABitmap_acquireBitmapFromJava(JNIEnv* env, jobject bitmapObj);
|
||||
|
||||
ABitmap* ABitmap_copy(ABitmap* srcBitmap, AndroidBitmapFormat dstFormat);
|
||||
@@ -37,6 +51,7 @@ void ABitmap_releaseRef(ABitmap* bitmap);
|
||||
AndroidBitmapInfo ABitmap_getInfo(ABitmap* bitmap);
|
||||
|
||||
void* ABitmap_getPixels(ABitmap* bitmap);
|
||||
void ABitmap_notifyPixelsChanged(ABitmap* bitmap);
|
||||
|
||||
AndroidBitmapFormat ABitmapConfig_getFormatFromConfig(JNIEnv* env, jobject bitmapConfigObj);
|
||||
jobject ABitmapConfig_getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format);
|
||||
@@ -88,10 +103,12 @@ namespace graphics {
|
||||
mBitmap = nullptr;
|
||||
}
|
||||
|
||||
const ABitmap* get() const { return mBitmap; }
|
||||
ABitmap* get() const { return mBitmap; }
|
||||
|
||||
AndroidBitmapInfo getInfo() const { return ABitmap_getInfo(mBitmap); }
|
||||
void* getPixels() const { return ABitmap_getPixels(mBitmap); }
|
||||
void notifyPixelsChanged() const { ABitmap_notifyPixelsChanged(mBitmap); }
|
||||
|
||||
private:
|
||||
// takes ownership of the provided ABitmap
|
||||
Bitmap(ABitmap* bitmap) : mBitmap(bitmap) {}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <android/bitmap.h>
|
||||
#include <android/graphics/Bitmap.h>
|
||||
#include <android/graphics/bitmap.h>
|
||||
|
||||
int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
|
||||
AndroidBitmapInfo* info) {
|
||||
@@ -24,7 +24,7 @@ int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
|
||||
}
|
||||
|
||||
if (info) {
|
||||
android::bitmap::imageInfo(env, jbitmap, info);
|
||||
*info = ABitmap_getInfoFromJava(env, jbitmap);
|
||||
}
|
||||
return ANDROID_BITMAP_RESULT_SUCCESS;
|
||||
}
|
||||
@@ -34,11 +34,15 @@ int AndroidBitmap_lockPixels(JNIEnv* env, jobject jbitmap, void** addrPtr) {
|
||||
return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
void* addr = android::bitmap::lockPixels(env, jbitmap);
|
||||
android::graphics::Bitmap bitmap(env, jbitmap);
|
||||
void* addr = bitmap.isValid() ? bitmap.getPixels() : nullptr;
|
||||
|
||||
if (!addr) {
|
||||
return ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
|
||||
}
|
||||
|
||||
ABitmap_acquireRef(bitmap.get());
|
||||
|
||||
if (addrPtr) {
|
||||
*addrPtr = addr;
|
||||
}
|
||||
@@ -50,9 +54,13 @@ int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap) {
|
||||
return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
bool unlocked = android::bitmap::unlockPixels(env, jbitmap);
|
||||
if (!unlocked) {
|
||||
android::graphics::Bitmap bitmap(env, jbitmap);
|
||||
|
||||
if (!bitmap.isValid()) {
|
||||
return ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
|
||||
}
|
||||
|
||||
bitmap.notifyPixelsChanged();
|
||||
ABitmap_releaseRef(bitmap.get());
|
||||
return ANDROID_BITMAP_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user