Merge "Consolidate NDK and APEX implementations"
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 0487e13..2dec4b3 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -223,97 +223,11 @@
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 @@
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);
diff --git a/core/jni/android/graphics/Bitmap.h b/core/jni/android/graphics/Bitmap.h
index 59adbb2..73eca3a 100644
--- a/core/jni/android/graphics/Bitmap.h
+++ b/core/jni/android/graphics/Bitmap.h
@@ -38,17 +38,8 @@
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
*/
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index bc1cc09..aa209cb 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -342,10 +342,6 @@
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) {
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 6e7d9e7..99034ed 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -61,7 +61,8 @@
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);
/*
diff --git a/core/jni/android/graphics/apex/android_bitmap.cpp b/core/jni/android/graphics/apex/android_bitmap.cpp
index a328def..90cc986 100644
--- a/core/jni/android/graphics/apex/android_bitmap.cpp
+++ b/core/jni/android/graphics/apex/android_bitmap.cpp
@@ -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 @@
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 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 @@
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 @@
}
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();
}
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 dea5517..f231eed 100644
--- a/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
+++ b/core/jni/android/graphics/apex/include/android/graphics/bitmap.h
@@ -27,6 +27,20 @@
*/
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 @@
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 @@
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) {}
diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp
index ff14832..1aebeaf 100644
--- a/native/graphics/jni/bitmap.cpp
+++ b/native/graphics/jni/bitmap.cpp
@@ -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 @@
}
if (info) {
- android::bitmap::imageInfo(env, jbitmap, info);
+ *info = ABitmap_getInfoFromJava(env, jbitmap);
}
return ANDROID_BITMAP_RESULT_SUCCESS;
}
@@ -34,11 +34,15 @@
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 @@
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;
}