summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}