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
diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig
index 93df478..f255967 100644
--- a/libs/hwui/aconfig/hwui_flags.aconfig
+++ b/libs/hwui/aconfig/hwui_flags.aconfig
@@ -139,3 +139,10 @@
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 3848b5a..f58dcc6 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 @@
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(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 @@
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 @@
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 9bbca5b..8abe6a8 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -79,6 +79,9 @@
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 @@
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 f349ad9..29efd98 100644
--- a/libs/hwui/jni/Bitmap.cpp
+++ b/libs/hwui/jni/Bitmap.cpp
@@ -669,14 +669,20 @@
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 @@
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;