diff options
author | 2024-10-15 12:22:01 -0700 | |
---|---|---|
committer | 2024-10-24 11:02:14 -0700 | |
commit | 7112c6e2a785a415033112525569d52b3c2d06fd (patch) | |
tree | 841bb3e2d286f16f18fc55c60aae33779caa4b6f | |
parent | 6ae0cc564d7daa0343cb4aacd6ba786f0a711150 (diff) |
Add an ID field to `class Bitmap`
Bug: 369619160
Flag: NONE no public API change
To be able to better reason about bitmaps, we added a private mId
field to `class Bitmap`. This allows the same ID to be used in
heapdump and in log/debugging code for better association.
Change-Id: I5f775167266c87428c717014fa01cb73c59a44c9
-rw-r--r-- | graphics/java/android/graphics/Bitmap.java | 7 | ||||
-rw-r--r-- | libs/hwui/hwui/Bitmap.cpp | 36 | ||||
-rw-r--r-- | libs/hwui/hwui/Bitmap.h | 15 | ||||
-rw-r--r-- | libs/hwui/jni/Bitmap.cpp | 5 |
4 files changed, 51 insertions, 12 deletions
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 461a5aec27ec..dfded7321b2c 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -102,6 +102,8 @@ public final class Bitmap implements Parcelable { private static volatile int sDefaultDensity = -1; + private long mId; + /** * For backwards compatibility, allows the app layer to change the default * density when running old apps. @@ -152,18 +154,19 @@ public final class Bitmap implements Parcelable { Bitmap(long nativeBitmap, int width, int height, int density, boolean requestPremultiplied, byte[] ninePatchChunk, NinePatch.InsetStruct ninePatchInsets) { - this(nativeBitmap, width, height, density, requestPremultiplied, ninePatchChunk, + this(0, nativeBitmap, width, height, density, requestPremultiplied, ninePatchChunk, ninePatchInsets, true); } // called from JNI and Bitmap_Delegate. - Bitmap(long nativeBitmap, int width, int height, int density, + Bitmap(long id, long nativeBitmap, int width, int height, int density, boolean requestPremultiplied, byte[] ninePatchChunk, NinePatch.InsetStruct ninePatchInsets, boolean fromMalloc) { if (nativeBitmap == 0) { throw new RuntimeException("internal error: native bitmap is 0"); } + mId = id; mWidth = width; mHeight = height; mRequestPremultiplied = requestPremultiplied; diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp index b73380e38fd1..3848b5a1e281 100644 --- a/libs/hwui/hwui/Bitmap.cpp +++ b/libs/hwui/hwui/Bitmap.cpp @@ -54,6 +54,7 @@ #include <SkPngEncoder.h> #include <SkWebpEncoder.h> +#include <atomic> #include <limits> namespace android { @@ -86,6 +87,28 @@ static uint64_t AHardwareBuffer_getAllocationSize(AHardwareBuffer* aHardwareBuff } #endif +// generate an ID for this Bitmap, id is a 64-bit integer of 3 parts: +// 0000xxxxxx - the lower 6 decimal digits is a monotonically increasing number +// 000x000000 - the 7th decimal digit is the storage type (see PixelStorageType) +// xxx0000000 - the 8th decimal digit and above is the current pid +// +// e.g. 43231000076 - means this bitmap is the 76th bitmap created, has the +// storage type of 'Heap', and is created in a process with pid 4323. +// +// NOTE: +// 1) the monotonic number could increase beyond 1000,000 and wrap around, which +// only happens when more than 1,000,000 bitmaps have been created over time. +// This could result in two IDs being the same despite being really rare. +// 2) the IDs are intentionally represented in decimal to make it easier to +// reason and associate with numbers shown in heap dump (mostly in decimal) +// and PIDs shown in different tools (mostly in decimal as well). +uint64_t Bitmap::getId(PixelStorageType type) { + static std::atomic<uint64_t> idCounter{0}; + return (idCounter.fetch_add(1) % 1000000) + + static_cast<uint64_t>(type) * 1000000 + + static_cast<uint64_t>(getpid()) * 10000000; +} + bool Bitmap::computeAllocationSize(size_t rowBytes, int height, size_t* size) { return 0 <= height && height <= std::numeric_limits<size_t>::max() && !__builtin_mul_overflow(rowBytes, (size_t)height, size) && @@ -261,7 +284,8 @@ void Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes) { Bitmap::Bitmap(void* address, size_t size, const SkImageInfo& info, size_t rowBytes) : SkPixelRef(info.width(), info.height(), address, rowBytes) , mInfo(validateAlpha(info)) - , mPixelStorageType(PixelStorageType::Heap) { + , mPixelStorageType(PixelStorageType::Heap) + , mId(getId(mPixelStorageType)) { mPixelStorage.heap.address = address; mPixelStorage.heap.size = size; traceBitmapCreate(); @@ -270,7 +294,8 @@ Bitmap::Bitmap(void* address, size_t size, const SkImageInfo& info, size_t rowBy Bitmap::Bitmap(SkPixelRef& pixelRef, const SkImageInfo& info) : SkPixelRef(info.width(), info.height(), pixelRef.pixels(), pixelRef.rowBytes()) , mInfo(validateAlpha(info)) - , mPixelStorageType(PixelStorageType::WrappedPixelRef) { + , mPixelStorageType(PixelStorageType::WrappedPixelRef) + , mId(getId(mPixelStorageType)) { pixelRef.ref(); mPixelStorage.wrapped.pixelRef = &pixelRef; traceBitmapCreate(); @@ -279,7 +304,8 @@ Bitmap::Bitmap(SkPixelRef& pixelRef, const SkImageInfo& info) Bitmap::Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info, size_t rowBytes) : SkPixelRef(info.width(), info.height(), address, rowBytes) , mInfo(validateAlpha(info)) - , mPixelStorageType(PixelStorageType::Ashmem) { + , mPixelStorageType(PixelStorageType::Ashmem) + , mId(getId(mPixelStorageType)) { mPixelStorage.ashmem.address = address; mPixelStorage.ashmem.fd = fd; mPixelStorage.ashmem.size = mappedSize; @@ -293,7 +319,8 @@ Bitmap::Bitmap(AHardwareBuffer* buffer, const SkImageInfo& info, size_t rowBytes , mInfo(validateAlpha(info)) , mPixelStorageType(PixelStorageType::Hardware) , mPalette(palette) - , mPaletteGenerationId(getGenerationID()) { + , mPaletteGenerationId(getGenerationID()) + , mId(getId(mPixelStorageType)) { mPixelStorage.hardware.buffer = buffer; mPixelStorage.hardware.size = AHardwareBuffer_getAllocationSize(buffer); AHardwareBuffer_acquire(buffer); @@ -578,6 +605,7 @@ void Bitmap::setGainmap(sp<uirenderer::Gainmap>&& gainmap) { } std::mutex Bitmap::mLock{}; + size_t Bitmap::mTotalBitmapBytes = 0; size_t Bitmap::mTotalBitmapCount = 0; diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h index 3d55d859ed5f..9bbca5bc7378 100644 --- a/libs/hwui/hwui/Bitmap.h +++ b/libs/hwui/hwui/Bitmap.h @@ -37,10 +37,10 @@ class SkWStream; namespace android { enum class PixelStorageType { - WrappedPixelRef, - Heap, - Ashmem, - Hardware, + WrappedPixelRef = 0, + Heap = 1, + Ashmem = 2, + Hardware = 3, }; // TODO: Find a better home for this. It's here because hwui/Bitmap is exported and CanvasTransform @@ -104,6 +104,10 @@ public: void setColorSpace(sk_sp<SkColorSpace> colorSpace); void setAlphaType(SkAlphaType alphaType); + uint64_t getId() const { + return mId; + } + void getSkBitmap(SkBitmap* outBitmap); SkBitmap getSkBitmap() { @@ -229,6 +233,9 @@ private: sk_sp<SkImage> mImage; // Cache is used only for HW Bitmaps with Skia pipeline. + uint64_t mId; // unique ID for this bitmap + static uint64_t getId(PixelStorageType type); + // for tracing total number and memory usage of bitmaps static std::mutex mLock; static size_t mTotalBitmapBytes; diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp index 010c4e8dfb3a..f349ad915933 100644 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -196,7 +196,7 @@ jobject createBitmap(JNIEnv* env, Bitmap* bitmap, int density) { static jmethodID gBitmap_constructorMethodID = GetMethodIDOrDie(env, gBitmap_class, - "<init>", "(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;Z)V"); + "<init>", "(JJIIIZ[BLandroid/graphics/NinePatch$InsetStruct;Z)V"); bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable; bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied; @@ -209,7 +209,8 @@ jobject createBitmap(JNIEnv* env, Bitmap* bitmap, bitmapWrapper->bitmap().setImmutable(); } jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID, - reinterpret_cast<jlong>(bitmapWrapper), bitmap->width(), bitmap->height(), density, + static_cast<jlong>(bitmap->getId()), reinterpret_cast<jlong>(bitmapWrapper), + bitmap->width(), bitmap->height(), density, isPremultiplied, ninePatchChunk, ninePatchInsets, fromMalloc); if (env->ExceptionCheck() != 0) { |