Add internal bitmap api for creating immutable ashmem backed bitmaps.
Bug 21037890
Change-Id: I827e83dd75e301e7d93ead5efdd744f0d8435ae5
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 7bd5af1..04b9a95 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -719,6 +719,21 @@
getPremulBitmapCreateFlags(isMutable));
}
+static jobject Bitmap_copyAshmem(JNIEnv* env, jobject, jlong srcHandle) {
+ SkBitmap src;
+ reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src);
+ SkBitmap result;
+
+ AshmemPixelAllocator allocator(env);
+ if (!src.copyTo(&result, &allocator)) {
+ return NULL;
+ }
+ Bitmap* bitmap = allocator.getStorageObjAndReset();
+ bitmap->peekAtPixelRef()->setImmutable();
+ jobject ret = GraphicsJNI::createBitmap(env, bitmap, getPremulBitmapCreateFlags(false));
+ return ret;
+}
+
static void Bitmap_destructor(JNIEnv* env, jobject, jlong bitmapHandle) {
LocalScopedBitmap bitmap(bitmapHandle);
bitmap->detachFromJava();
@@ -1267,6 +1282,8 @@
(void*)Bitmap_creator },
{ "nativeCopy", "(JIZ)Landroid/graphics/Bitmap;",
(void*)Bitmap_copy },
+ { "nativeCopyAshmem", "(J)Landroid/graphics/Bitmap;",
+ (void*)Bitmap_copyAshmem },
{ "nativeDestructor", "(J)V", (void*)Bitmap_destructor },
{ "nativeRecycle", "(J)Z", (void*)Bitmap_recycle },
{ "nativeReconfigure", "(JIIIIZ)V", (void*)Bitmap_reconfigure },
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 028a385..ff22ef3 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -674,6 +674,25 @@
////////////////////////////////////////////////////////////////////////////////
+AshmemPixelAllocator::AshmemPixelAllocator(JNIEnv *env) {
+ LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&mJavaVM) != JNI_OK,
+ "env->GetJavaVM failed");
+}
+
+AshmemPixelAllocator::~AshmemPixelAllocator() {
+ if (mStorage) {
+ mStorage->detachFromJava();
+ }
+}
+
+bool AshmemPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
+ JNIEnv* env = vm2env(mJavaVM);
+ mStorage = GraphicsJNI::allocateAshmemPixelRef(env, bitmap, ctable);
+ return mStorage != nullptr;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
static jclass make_globalref(JNIEnv* env, const char classname[])
{
jclass c = env->FindClass(classname);
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 4f72118..1938e85 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -144,6 +144,23 @@
android::Bitmap* mStorage = nullptr;
};
+class AshmemPixelAllocator : public SkBitmap::Allocator {
+public:
+ AshmemPixelAllocator(JNIEnv* env);
+ ~AshmemPixelAllocator();
+ virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable);
+ android::Bitmap* getStorageObjAndReset() {
+ android::Bitmap* result = mStorage;
+ mStorage = NULL;
+ return result;
+ };
+
+private:
+ JavaVM* mJavaVM;
+ android::Bitmap* mStorage = nullptr;
+};
+
+
enum JNIAccess {
kRO_JNIAccess,
kRW_JNIAccess
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 2d8b0b2..a999b71 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -558,6 +558,22 @@
}
/**
+ * Creates a new immutable bitmap backed by ashmem which can efficiently
+ * be passed between processes.
+ *
+ * @hide
+ */
+ public Bitmap createAshmemBitmap() {
+ checkRecycled("Can't copy a recycled bitmap");
+ Bitmap b = nativeCopyAshmem(mFinalizer.mNativeBitmap);
+ if (b != null) {
+ b.setPremultiplied(mRequestPremultiplied);
+ b.mDensity = mDensity;
+ }
+ return b;
+ }
+
+ /**
* Creates a new bitmap, scaled from an existing bitmap, when possible. If the
* specified width and height are the same as the current width and height of
* the source bitmap, the source bitmap is returned and no new bitmap is
@@ -1636,6 +1652,7 @@
int nativeConfig, boolean mutable);
private static native Bitmap nativeCopy(long nativeSrcBitmap, int nativeConfig,
boolean isMutable);
+ private static native Bitmap nativeCopyAshmem(long nativeSrcBitmap);
private static native void nativeDestructor(long nativeBitmap);
private static native boolean nativeRecycle(long nativeBitmap);
private static native void nativeReconfigure(long nativeBitmap, int width, int height,