summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2019-11-08 08:50:58 -0500
committerDerek Sollenberger <djsollen@google.com>2019-11-21 12:49:20 -0500
commit6c41ab13d0734dc1d154f5fd3f05e922e3a1e4f0 (patch)
treea1b37ec5156c9ec6911dc49c86b229c624d1a3d8
parent17c36347cc929a5dd40558fe14eeea14676253b4 (diff)
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
-rwxr-xr-xcore/jni/android/graphics/Bitmap.cpp89
-rw-r--r--core/jni/android/graphics/Bitmap.h9
-rw-r--r--core/jni/android/graphics/Graphics.cpp4
-rw-r--r--core/jni/android/graphics/GraphicsJNI.h3
-rw-r--r--core/jni/android/graphics/apex/android_bitmap.cpp66
-rw-r--r--core/jni/android/graphics/apex/include/android/graphics/bitmap.h19
-rw-r--r--native/graphics/jni/bitmap.cpp18
7 files changed, 97 insertions, 111 deletions
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 0487e139d264..2dec4b399e57 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -223,104 +223,39 @@ 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);
+} // namespace bitmap
- 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;
- }
-}
+} // namespace android
-void* lockPixels(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);
- if (!localBitmap->valid()) return nullptr;
-
- SkPixelRef& pixelRef = localBitmap->bitmap();
- if (!pixelRef.pixels()) {
- return nullptr;
- }
- pixelRef.ref();
- return pixelRef.pixels();
+ return localBitmap.valid() ? &localBitmap->bitmap() : nullptr;
}
-bool unlockPixels(JNIEnv* env, jobject bitmap) {
+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 (!localBitmap->valid()) return false;
-
- SkPixelRef& pixelRef = localBitmap->bitmap();
- pixelRef.notifyPixelsChanged();
- pixelRef.unref();
- return true;
+ if (outRowBytes) {
+ *outRowBytes = localBitmap->rowBytes();
+ }
+ return localBitmap->info();
}
-} // namespace bitmap
-
-} // namespace android
-
-using namespace android;
-using namespace android::bitmap;
-
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 59adbb207a0c..73eca3aa8ef8 100644
--- a/core/jni/android/graphics/Bitmap.h
+++ b/core/jni/android/graphics/Bitmap.h
@@ -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
*/
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index bc1cc09506ad..aa209cb3899e 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -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) {
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 6e7d9e736c0a..99034edaadf7 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -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);
/*
diff --git a/core/jni/android/graphics/apex/android_bitmap.cpp b/core/jni/android/graphics/apex/android_bitmap.cpp
index a328def87908..90cc98699827 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 @@ 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();
}
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 dea55172b3bb..f231eeddb7e2 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 @@ __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) {}
diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp
index ff14832a2f0f..1aebeaf1e7e8 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 @@ 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;
}