summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--graphics/java/android/graphics/Bitmap.java4
-rw-r--r--libs/hwui/hwui/Bitmap.cpp6
-rw-r--r--libs/hwui/hwui/Bitmap.h8
-rw-r--r--libs/hwui/jni/Bitmap.cpp26
-rw-r--r--libs/hwui/jni/Bitmap.h7
-rw-r--r--libs/hwui/jni/ScopedParcel.cpp10
-rw-r--r--libs/hwui/jni/ScopedParcel.h4
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); }