diff options
-rw-r--r-- | graphics/java/android/graphics/Bitmap.java | 4 | ||||
-rw-r--r-- | libs/hwui/hwui/Bitmap.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/hwui/Bitmap.h | 8 | ||||
-rw-r--r-- | libs/hwui/jni/Bitmap.cpp | 26 | ||||
-rw-r--r-- | libs/hwui/jni/Bitmap.h | 7 | ||||
-rw-r--r-- | libs/hwui/jni/ScopedParcel.cpp | 10 | ||||
-rw-r--r-- | libs/hwui/jni/ScopedParcel.h | 4 |
7 files changed, 44 insertions, 21 deletions
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index dfded7321b2c..0c4ea79dd5be 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -102,6 +102,10 @@ public final class Bitmap implements Parcelable { private static volatile int sDefaultDensity = -1; + /** + * This id is not authoritative and can be duplicated if an ashmem bitmap is decoded from a + * parcel. + */ private long mId; /** diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp index b1550b0b6888..63a024b8e780 100644 --- a/libs/hwui/hwui/Bitmap.cpp +++ b/libs/hwui/hwui/Bitmap.cpp @@ -260,7 +260,7 @@ sk_sp<Bitmap> Bitmap::createFrom(AHardwareBuffer* hardwareBuffer, const SkImageI #endif sk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, size_t rowBytes, int fd, void* addr, - size_t size, bool readOnly) { + size_t size, bool readOnly, int64_t id) { #ifdef _WIN32 // ashmem not implemented on Windows return nullptr; #else @@ -279,7 +279,7 @@ sk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, size_t rowBytes, int f } } - sk_sp<Bitmap> bitmap(new Bitmap(addr, fd, size, info, rowBytes)); + sk_sp<Bitmap> bitmap(new Bitmap(addr, fd, size, info, rowBytes, id)); if (readOnly) { bitmap->setImmutable(); } @@ -334,7 +334,7 @@ Bitmap::Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info : SkPixelRef(info.width(), info.height(), address, rowBytes) , mInfo(validateAlpha(info)) , mPixelStorageType(PixelStorageType::Ashmem) - , mId(id != INVALID_BITMAP_ID ? id : getId(mPixelStorageType)) { + , mId(id != UNDEFINED_BITMAP_ID ? id : getId(mPixelStorageType)) { mPixelStorage.ashmem.address = address; mPixelStorage.ashmem.fd = fd; mPixelStorage.ashmem.size = mappedSize; diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h index 8abe6a8c445a..4e9bcf27c0ef 100644 --- a/libs/hwui/hwui/Bitmap.h +++ b/libs/hwui/hwui/Bitmap.h @@ -97,7 +97,7 @@ public: BitmapPalette palette); #endif static sk_sp<Bitmap> createFrom(const SkImageInfo& info, size_t rowBytes, int fd, void* addr, - size_t size, bool readOnly); + size_t size, bool readOnly, int64_t id); static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&); int rowBytesAsPixels() const { return rowBytes() >> mInfo.shiftPerPixel(); } @@ -183,15 +183,15 @@ public: static bool compress(const SkBitmap& bitmap, JavaCompressFormat format, int32_t quality, SkWStream* stream); -private: - static constexpr uint64_t INVALID_BITMAP_ID = 0u; + static constexpr uint64_t UNDEFINED_BITMAP_ID = 0u; +private: static sk_sp<Bitmap> allocateAshmemBitmap(size_t size, const SkImageInfo& i, size_t rowBytes); Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes); Bitmap(SkPixelRef& pixelRef, const SkImageInfo& info); Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info, size_t rowBytes, - uint64_t id = INVALID_BITMAP_ID); + uint64_t id = UNDEFINED_BITMAP_ID); #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration Bitmap(AHardwareBuffer* buffer, const SkImageInfo& info, size_t rowBytes, BitmapPalette palette); diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp index 29efd98b41d0..cfde0b28c0d5 100644 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -191,9 +191,8 @@ void reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info, info.width(), info.height(), isPremultiplied); } -jobject createBitmap(JNIEnv* env, Bitmap* bitmap, - int bitmapCreateFlags, jbyteArray ninePatchChunk, jobject ninePatchInsets, - int density) { +jobject createBitmap(JNIEnv* env, Bitmap* bitmap, int bitmapCreateFlags, jbyteArray ninePatchChunk, + jobject ninePatchInsets, int density, int64_t id) { static jmethodID gBitmap_constructorMethodID = GetMethodIDOrDie(env, gBitmap_class, "<init>", "(JJIIIZ[BLandroid/graphics/NinePatch$InsetStruct;Z)V"); @@ -208,10 +207,12 @@ jobject createBitmap(JNIEnv* env, Bitmap* bitmap, if (!isMutable) { bitmapWrapper->bitmap().setImmutable(); } + int64_t bitmapId = id != Bitmap::UNDEFINED_BITMAP_ID ? id : bitmap->getId(); jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID, - static_cast<jlong>(bitmap->getId()), reinterpret_cast<jlong>(bitmapWrapper), - bitmap->width(), bitmap->height(), density, - isPremultiplied, ninePatchChunk, ninePatchInsets, fromMalloc); + static_cast<jlong>(bitmapId), + reinterpret_cast<jlong>(bitmapWrapper), bitmap->width(), + bitmap->height(), density, isPremultiplied, ninePatchChunk, + ninePatchInsets, fromMalloc); if (env->ExceptionCheck() != 0) { ALOGE("*** Uncaught exception returned from Java call!\n"); @@ -759,6 +760,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { const int32_t height = p.readInt32(); const int32_t rowBytes = p.readInt32(); const int32_t density = p.readInt32(); + const int64_t sourceId = p.readInt64(); if (kN32_SkColorType != colorType && kRGBA_F16_SkColorType != colorType && @@ -815,7 +817,8 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { return STATUS_NO_MEMORY; } nativeBitmap = - Bitmap::createFrom(imageInfo, rowBytes, fd.release(), addr, size, !isMutable); + Bitmap::createFrom(imageInfo, rowBytes, fd.release(), addr, size, + !isMutable, sourceId); return STATUS_OK; }); @@ -831,15 +834,15 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { } return createBitmap(env, nativeBitmap.release(), getPremulBitmapCreateFlags(isMutable), nullptr, - nullptr, density); + nullptr, density, sourceId); #else jniThrowRuntimeException(env, "Cannot use parcels outside of Android"); return NULL; #endif } -static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, - jlong bitmapHandle, jint density, jobject parcel) { +static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, jlong bitmapHandle, jint density, + jobject parcel) { #ifdef __ANDROID__ // Layoutlib does not support parcel if (parcel == NULL) { ALOGD("------- writeToParcel null parcel\n"); @@ -870,6 +873,7 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, binder_status_t status; int fd = bitmapWrapper->bitmap().getAshmemFd(); if (fd >= 0 && p.allowFds() && bitmap.isImmutable()) { + p.writeInt64(bitmapWrapper->bitmap().getId()); #if DEBUG_PARCEL ALOGD("Bitmap.writeToParcel: transferring immutable bitmap's ashmem fd as " "immutable blob (fds %s)", @@ -889,7 +893,7 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, ALOGD("Bitmap.writeToParcel: copying bitmap into new blob (fds %s)", p.allowFds() ? "allowed" : "forbidden"); #endif - + p.writeInt64(Bitmap::UNDEFINED_BITMAP_ID); status = writeBlob(p.get(), bitmapWrapper->bitmap().getId(), bitmap); if (status) { doThrowRE(env, "Could not copy bitmap to parcel blob."); diff --git a/libs/hwui/jni/Bitmap.h b/libs/hwui/jni/Bitmap.h index 21a93f066d9b..c93246a972b6 100644 --- a/libs/hwui/jni/Bitmap.h +++ b/libs/hwui/jni/Bitmap.h @@ -18,6 +18,7 @@ #include <jni.h> #include <android/bitmap.h> +#include <hwui/Bitmap.h> struct SkImageInfo; @@ -33,9 +34,9 @@ enum BitmapCreateFlags { kBitmapCreateFlag_Premultiplied = 0x2, }; -jobject createBitmap(JNIEnv* env, Bitmap* bitmap, - int bitmapCreateFlags, jbyteArray ninePatchChunk = nullptr, - jobject ninePatchInsets = nullptr, int density = -1); +jobject createBitmap(JNIEnv* env, Bitmap* bitmap, int bitmapCreateFlags, + jbyteArray ninePatchChunk = nullptr, jobject ninePatchInsets = nullptr, + int density = -1, int64_t id = Bitmap::UNDEFINED_BITMAP_ID); Bitmap& toBitmap(jlong bitmapHandle); diff --git a/libs/hwui/jni/ScopedParcel.cpp b/libs/hwui/jni/ScopedParcel.cpp index b0f5423813b7..95e4e01d8df8 100644 --- a/libs/hwui/jni/ScopedParcel.cpp +++ b/libs/hwui/jni/ScopedParcel.cpp @@ -39,6 +39,16 @@ uint32_t ScopedParcel::readUint32() { return temp; } +int64_t ScopedParcel::readInt64() { + int64_t temp = 0; + // TODO: This behavior-matches what android::Parcel does + // but this should probably be better + if (AParcel_readInt64(mParcel, &temp) != STATUS_OK) { + temp = 0; + } + return temp; +} + float ScopedParcel::readFloat() { float temp = 0.; if (AParcel_readFloat(mParcel, &temp) != STATUS_OK) { diff --git a/libs/hwui/jni/ScopedParcel.h b/libs/hwui/jni/ScopedParcel.h index fd8d6a210f0f..f2f138fda43c 100644 --- a/libs/hwui/jni/ScopedParcel.h +++ b/libs/hwui/jni/ScopedParcel.h @@ -35,12 +35,16 @@ public: uint32_t readUint32(); + int64_t readInt64(); + float readFloat(); void writeInt32(int32_t value) { AParcel_writeInt32(mParcel, value); } void writeUint32(uint32_t value) { AParcel_writeUint32(mParcel, value); } + void writeInt64(int64_t value) { AParcel_writeInt64(mParcel, value); } + void writeFloat(float value) { AParcel_writeFloat(mParcel, value); } bool allowFds() const { return AParcel_getAllowFds(mParcel); } |