diff options
author | 2024-10-16 14:47:28 -0700 | |
---|---|---|
committer | 2024-10-24 11:02:39 -0700 | |
commit | 9b0d370c263cab2b9c16ec1b59ad749ee44af16f (patch) | |
tree | 28d8b002edaf2d1b3be76613af3402d9133cd912 | |
parent | 7112c6e2a785a415033112525569d52b3c2d06fd (diff) |
Allow more information in bitmap ashmem filenames
Bug: 369619160
Flag: com.android.graphics.hwui.flags.bitmap_ashmem_long_name
This CL allows more information in bitmap ashmem filenames, e.g.
$ adb shell lsof | grep 'ashmem.*bitmap'
system_server 1505 system mem unknown /dev/ashmem/bitmap/writeblob-id_173400011-472x472-size_891136-com.google.android.googlequicksearchbox:search (deleted)
system_server 1505 system mem unknown /dev/ashmem/bitmap/allocate-id_273400014-126x126-size_63504-com.google.android.googlequicksearchbox:search (deleted)
system_server 1505 system mem unknown /dev/ashmem/bitmap/allocate-id_247000010-50x63-size_12600-com.android.phone (deleted)
ndroid.systemui 2155 u0_a238 mem unknown /dev/ashmem/bitmap/writeblob-id_173400011-472x472-size_891136-com.google.android.googlequicksearchbox:search (deleted)
ndroid.systemui 2155 u0_a238 mem unknown /dev/ashmem/bitmap/allocate-id_214800058-192x192-size_147456-com.google.android.as (deleted)
The long filename will tell us:
* callsite - where the ashmem bitmap is created, `allocate` means
in Bitmap::allocateAshmemBitmap where an ashmem backed bitmap is
directly allocated, or `writeblob` in writeBlob() where existing
bitmap is turned to an ashmem backed one
* id - unique to the bitmap, this can also be used to associated to
the bitmap in a heapdump with the same `mId` field
* dimension - width x height
* size - size of the bitmap in bytes
* origin - the process where the bitmap was created
Change-Id: I7bbb7003d0a0abe62e2008bd708760b6f4e2f8b6
-rw-r--r-- | libs/hwui/aconfig/hwui_flags.aconfig | 7 | ||||
-rw-r--r-- | libs/hwui/hwui/Bitmap.cpp | 35 | ||||
-rw-r--r-- | libs/hwui/hwui/Bitmap.h | 8 | ||||
-rw-r--r-- | libs/hwui/jni/Bitmap.cpp | 13 |
4 files changed, 54 insertions, 9 deletions
diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig index 93df47853769..f2559677c325 100644 --- a/libs/hwui/aconfig/hwui_flags.aconfig +++ b/libs/hwui/aconfig/hwui_flags.aconfig @@ -139,3 +139,10 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "bitmap_ashmem_long_name" + namespace: "core_graphics" + description: "Whether to have more information in ashmem filenames for bitmaps" + bug: "369619160" +} diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp index 3848b5a1e281..f58dcc6509ea 100644 --- a/libs/hwui/hwui/Bitmap.cpp +++ b/libs/hwui/hwui/Bitmap.cpp @@ -15,6 +15,7 @@ */ #include "Bitmap.h" +#include <android-base/file.h> #include "HardwareBitmapUploader.h" #include "Properties.h" #ifdef __ANDROID__ // Layoutlib does not support render thread @@ -57,6 +58,15 @@ #include <atomic> #include <limits> +#ifdef __ANDROID__ +#include <com_android_graphics_hwui_flags.h> +namespace hwui_flags = com::android::graphics::hwui::flags; +#else +namespace hwui_flags { +constexpr bool bitmap_ashmem_long_name() { return false; } +} +#endif + namespace android { #ifdef __ANDROID__ @@ -140,6 +150,20 @@ static sk_sp<Bitmap> allocateBitmap(SkBitmap* bitmap, AllocPixelRef alloc) { return wrapper; } +std::string Bitmap::getAshmemId(const char* tag, uint64_t bitmapId, + int width, int height, size_t size) { + if (!hwui_flags::bitmap_ashmem_long_name()) { + return "bitmap"; + } + static std::string sCmdline = [] { + std::string temp; + android::base::ReadFileToString("/proc/self/cmdline", &temp); + return temp; + }(); + return std::format("bitmap/{}-id_{}-{}x{}-size_{}-{}", + tag, bitmapId, width, height, size, sCmdline); +} + sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap) { return allocateBitmap(bitmap, &Bitmap::allocateAshmemBitmap); } @@ -147,7 +171,9 @@ sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap) { sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(size_t size, const SkImageInfo& info, size_t rowBytes) { #ifdef __ANDROID__ // Create new ashmem region with read/write priv - int fd = ashmem_create_region("bitmap", size); + uint64_t id = getId(PixelStorageType::Ashmem); + auto ashmemId = getAshmemId("allocate", id, info.width(), info.height(), size); + int fd = ashmem_create_region(ashmemId.c_str(), size); if (fd < 0) { return nullptr; } @@ -163,7 +189,7 @@ sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(size_t size, const SkImageInfo& info, close(fd); return nullptr; } - return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes)); + return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes, id)); #else return Bitmap::allocateHeapBitmap(size, info, rowBytes); #endif @@ -301,11 +327,12 @@ Bitmap::Bitmap(SkPixelRef& pixelRef, const SkImageInfo& info) traceBitmapCreate(); } -Bitmap::Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info, size_t rowBytes) +Bitmap::Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info, + size_t rowBytes, uint64_t id) : SkPixelRef(info.width(), info.height(), address, rowBytes) , mInfo(validateAlpha(info)) , mPixelStorageType(PixelStorageType::Ashmem) - , mId(getId(mPixelStorageType)) { + , mId(id != INVALID_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 9bbca5bc7378..8abe6a8c445a 100644 --- a/libs/hwui/hwui/Bitmap.h +++ b/libs/hwui/hwui/Bitmap.h @@ -79,6 +79,9 @@ public: static sk_sp<Bitmap> allocateHeapBitmap(const SkImageInfo& info); static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& i, size_t rowBytes); + static std::string getAshmemId(const char* tag, uint64_t bitmapId, + int width, int height, size_t size); + /* The createFrom factories construct a new Bitmap object by wrapping the already allocated * memory that is provided as an input param. */ @@ -181,11 +184,14 @@ public: static bool compress(const SkBitmap& bitmap, JavaCompressFormat format, int32_t quality, SkWStream* stream); private: + static constexpr uint64_t INVALID_BITMAP_ID = 0u; + 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); + Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info, size_t rowBytes, + uint64_t id = INVALID_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 f349ad915933..29efd98b41d0 100644 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -669,14 +669,20 @@ static binder_status_t writeBlobFromFd(AParcel* parcel, int32_t size, int fd) { return STATUS_OK; } -static binder_status_t writeBlob(AParcel* parcel, const int32_t size, const void* data, bool immutable) { +static binder_status_t writeBlob(AParcel* parcel, uint64_t bitmapId, const SkBitmap& bitmap) { + const size_t size = bitmap.computeByteSize(); + const void* data = bitmap.getPixels(); + const bool immutable = bitmap.isImmutable(); + if (size <= 0 || data == nullptr) { return STATUS_NOT_ENOUGH_DATA; } binder_status_t error = STATUS_OK; if (shouldUseAshmem(parcel, size)) { // Create new ashmem region with read/write priv - base::unique_fd fd(ashmem_create_region("bitmap", size)); + auto ashmemId = Bitmap::getAshmemId("writeblob", bitmapId, + bitmap.width(), bitmap.height(), size); + base::unique_fd fd(ashmem_create_region(ashmemId.c_str(), size)); if (fd.get() < 0) { return STATUS_NO_MEMORY; } @@ -884,8 +890,7 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, p.allowFds() ? "allowed" : "forbidden"); #endif - size_t size = bitmap.computeByteSize(); - status = writeBlob(p.get(), size, bitmap.getPixels(), bitmap.isImmutable()); + status = writeBlob(p.get(), bitmapWrapper->bitmap().getId(), bitmap); if (status) { doThrowRE(env, "Could not copy bitmap to parcel blob."); return JNI_FALSE; |