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

Commit 2fc9b92d authored by Eric Miao's avatar Eric Miao
Browse files

Reapply "Keep source bitmap id for received ashmem bitmaps"

This CL reapply ag/32178426, which is reverted by ag/32677592.
This CL needs to be submitted together with ag/32743264.

Bug: 369619160
Bug: 406334585
Flag: NONE - revert of revert

This reverts commit 98987166.

Change-Id: Ic4ade6252b9a192f40d372755ea1b9d54eeea43b
parent cd4a17a2
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -103,12 +103,13 @@ 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;

    // source id of the bitmap where this bitmap was created from, e.g.
    // in the case of ashmem bitmap received, mSourceId is the mId of
    // the bitmap from the sender
    private long mSourceId = -1;

    /**
     * For backwards compatibility, allows the app layer to change the default
     * density when running old apps.
@@ -182,6 +183,7 @@ public final class Bitmap implements Parcelable {
        }

        mNativePtr = nativeBitmap;
        mSourceId = nativeGetSourceId(mNativePtr);
        final int allocationByteCount = getAllocationByteCount();
        getRegistry(fromMalloc, allocationByteCount).registerNativeAllocation(this, mNativePtr);

@@ -2594,6 +2596,8 @@ public final class Bitmap implements Parcelable {

    private static native Gainmap nativeExtractGainmap(long nativePtr);
    private static native void nativeSetGainmap(long bitmapPtr, long gainmapPtr);
    private static native long nativeGetSourceId(long nativePtr);
    private static native void nativeSetSourceId(long nativePtr, long sourceId);

    // ---------------- @CriticalNative -------------------

+2 −2
Original line number Diff line number Diff line
@@ -271,7 +271,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, int64_t id) {
                                 size_t size, bool readOnly) {
#ifdef _WIN32 // ashmem not implemented on Windows
     return nullptr;
#else
@@ -290,7 +290,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, id));
    sk_sp<Bitmap> bitmap(new Bitmap(addr, fd, size, info, rowBytes));
    if (readOnly) {
        bitmap->setImmutable();
    }
+8 −3
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ class PixelStorage;

typedef void (*FreeFunc)(void* addr, void* context);

static constexpr uint64_t UNDEFINED_BITMAP_ID = 0u;

class Bitmap : public SkPixelRef {
public:
    /* The allocate factories not only construct the Bitmap object but also allocate the
@@ -98,7 +100,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, int64_t id);
                                    size_t size, bool readOnly);
    static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&);

    int rowBytesAsPixels() const { return rowBytes() >> mInfo.shiftPerPixel(); }
@@ -112,6 +114,9 @@ public:
        return mId;
    }

    uint64_t getSourceId() const { return mSourceId; }
    void setSourceId(uint64_t sourceId) { mSourceId = sourceId; }

    void getSkBitmap(SkBitmap* outBitmap);

    SkBitmap getSkBitmap() {
@@ -184,8 +189,6 @@ public:

  static bool compress(const SkBitmap& bitmap, JavaCompressFormat format,
                       int32_t quality, SkWStream* stream);

    static constexpr uint64_t UNDEFINED_BITMAP_ID = 0u;
private:
    static sk_sp<Bitmap> allocateAshmemBitmap(size_t size, const SkImageInfo& i, size_t rowBytes);

@@ -241,6 +244,8 @@ private:
    sk_sp<SkImage> mImage;  // Cache is used only for HW Bitmaps with Skia pipeline.

    uint64_t mId;                // unique ID for this bitmap
    // source Id where this bitmap is orignated from
    uint64_t mSourceId = -1;
    static uint64_t getId(PixelStorageType type);

    // for tracing total number and memory usage of bitmaps
+23 −10
Original line number Diff line number Diff line
@@ -198,7 +198,7 @@ void reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info,
}

jobject createBitmap(JNIEnv* env, Bitmap* bitmap, int bitmapCreateFlags, jbyteArray ninePatchChunk,
                     jobject ninePatchInsets, int density, int64_t id) {
                     jobject ninePatchInsets, int density) {
    static jmethodID gBitmap_constructorMethodID =
        GetMethodIDOrDie(env, gBitmap_class,
            "<init>", "(JJIIIZ[BLandroid/graphics/NinePatch$InsetStruct;Z)V");
@@ -213,9 +213,8 @@ jobject createBitmap(JNIEnv* env, Bitmap* bitmap, int bitmapCreateFlags, jbyteAr
    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>(bitmapId),
                                 static_cast<jlong>(bitmap->getId()),
                                 reinterpret_cast<jlong>(bitmapWrapper), bitmap->width(),
                                 bitmap->height(), density, isPremultiplied, ninePatchChunk,
                                 ninePatchInsets, fromMalloc);
@@ -822,9 +821,8 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
                    ALOGW("mmap failed, error %d (%s)", err, strerror(err));
                    return STATUS_NO_MEMORY;
                }
                nativeBitmap =
                        Bitmap::createFrom(imageInfo, rowBytes, fd.release(), addr, size,
                        !isMutable, sourceId);
                nativeBitmap = Bitmap::createFrom(imageInfo, rowBytes, fd.release(),
                                                  addr, size, !isMutable);
                return STATUS_OK;
            });

@@ -839,8 +837,9 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
        return nullptr;
    }

    nativeBitmap->setSourceId(sourceId);
    return createBitmap(env, nativeBitmap.release(), getPremulBitmapCreateFlags(isMutable), nullptr,
                        nullptr, density, sourceId);
                        nullptr, density);
#else
    jniThrowRuntimeException(env, "Cannot use parcels outside of Linux");
    return NULL;
@@ -879,6 +878,7 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, jlong bitmapHandle, j

    auto bitmapWrapper = reinterpret_cast<BitmapWrapper*>(bitmapHandle);
    bitmapWrapper->getSkBitmap(&bitmap);
    uint64_t id = bitmapWrapper->bitmap().getId();

    p.writeInt32(shouldParcelAsMutable(bitmap, p.get()));
    p.writeInt32(bitmap.colorType());
@@ -893,12 +893,12 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, jlong bitmapHandle, j
    p.writeInt32(bitmap.height());
    p.writeInt32(bitmap.rowBytes());
    p.writeInt32(density);
    p.writeInt64(id);

    // Transfer the underlying ashmem region if we have one and it's immutable.
    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)",
@@ -918,8 +918,7 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, jlong bitmapHandle, j
    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);
    status = writeBlob(p.get(), id, bitmap);
    if (status) {
        doThrowRE(env, "Could not copy bitmap to parcel blob.");
        return JNI_FALSE;
@@ -1251,6 +1250,18 @@ static void Bitmap_setGainmap(JNIEnv*, jobject, jlong bitmapHandle, jlong gainma
    bitmapHolder->bitmap().setGainmap(sp<uirenderer::Gainmap>::fromExisting(gainmap));
}

static jlong Bitmap_getSourceId(JNIEnv*, jobject, jlong bitmapHandle) {
    LocalScopedBitmap bitmapHolder(bitmapHandle);
    return bitmapHolder.valid() ? bitmapHolder->bitmap().getSourceId() : UNDEFINED_BITMAP_ID;
}

static void Bitmap_setSourceId(JNIEnv*, jobject, jlong bitmapHandle, jlong sourceId) {
    LocalScopedBitmap bitmapHolder(bitmapHandle);
    if (bitmapHolder.valid()) {
        bitmapHolder->bitmap().setSourceId(sourceId);
    }
}

///////////////////////////////////////////////////////////////////////////////

static const JNINativeMethod gBitmapMethods[] = {
@@ -1303,6 +1314,8 @@ static const JNINativeMethod gBitmapMethods[] = {
        {"nativeSetImmutable", "(J)V", (void*)Bitmap_setImmutable},
        {"nativeExtractGainmap", "(J)Landroid/graphics/Gainmap;", (void*)Bitmap_extractGainmap},
        {"nativeSetGainmap", "(JJ)V", (void*)Bitmap_setGainmap},
        {"nativeGetSourceId", "(J)J", (void*)Bitmap_getSourceId},
        {"nativeSetSourceId", "(JJ)V", (void*)Bitmap_setSourceId},

        // ------------ @CriticalNative ----------------
        {"nativeIsImmutable", "(J)Z", (void*)Bitmap_isImmutable},
+2 −3
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@

#include <jni.h>
#include <android/bitmap.h>
#include <hwui/Bitmap.h>

struct SkImageInfo;

@@ -36,7 +35,7 @@ enum BitmapCreateFlags {

jobject createBitmap(JNIEnv* env, Bitmap* bitmap, int bitmapCreateFlags,
                    jbyteArray ninePatchChunk = nullptr, jobject ninePatchInsets = nullptr,
                     int density = -1, int64_t id = Bitmap::UNDEFINED_BITMAP_ID);
                    int density = -1);

Bitmap& toBitmap(jlong bitmapHandle);