Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b0d370c authored by Eric Miao's avatar Eric Miao
Browse files

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
parent 7112c6e2
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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"
}
+31 −4
Original line number Diff line number Diff line
@@ -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;
+7 −1
Original line number Diff line number Diff line
@@ -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);
+9 −4
Original line number Diff line number Diff line
@@ -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;