diff options
-rwxr-xr-x | core/jni/android/graphics/Bitmap.cpp | 89 | ||||
-rw-r--r-- | core/jni/android/graphics/Bitmap.h | 9 | ||||
-rw-r--r-- | core/jni/android/graphics/Graphics.cpp | 4 | ||||
-rw-r--r-- | core/jni/android/graphics/GraphicsJNI.h | 3 | ||||
-rw-r--r-- | core/jni/android/graphics/apex/android_bitmap.cpp | 66 | ||||
-rw-r--r-- | core/jni/android/graphics/apex/include/android/graphics/bitmap.h | 19 | ||||
-rw-r--r-- | native/graphics/jni/bitmap.cpp | 18 |
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; } |