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

Commit a72a7ffe authored by Leon Scroggins III's avatar Leon Scroggins III
Browse files

Expose Bitmap#getHardwareBuffer

Bug: 148155907
Bug: 150395371
Test: I652101b6a4b3d9de4e77a316ba0436ce466f3620

Bitmap already has a method to create a Bitmap from a HardwareBuffer,
and the NDK allows doing the reverse. This updates the SDK to allow
retrieving the HardwareBuffer, too.

Update the docs to match wrapHardwareBuffer regarding modifications.

Throw an Exception if called on a non-HARDWARE Bitmap, which is
friendlier than the crash that previously happened on the hidden API
(and the one it replaced).

Change-Id: I408cff708efa76f89e0c4c6dae16f19166ffe74d
parent b2550115
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -14061,6 +14061,7 @@ package android.graphics {
    method public android.graphics.Bitmap.Config getConfig();
    method public int getDensity();
    method public int getGenerationId();
    method @NonNull public android.hardware.HardwareBuffer getHardwareBuffer();
    method public int getHeight();
    method public byte[] getNinePatchChunk();
    method @ColorInt public int getPixel(int, int);
+23 −5
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import dalvik.annotation.optimization.CriticalNative;
import libcore.util.NativeAllocationRegistry;

import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
@@ -85,6 +86,7 @@ public final class Bitmap implements Parcelable {
    private int mWidth;
    @UnsupportedAppUsage
    private int mHeight;
    private WeakReference<HardwareBuffer> mHardwareBuffer;
    private boolean mRecycled;

    private ColorSpace mColorSpace;
@@ -366,6 +368,7 @@ public final class Bitmap implements Parcelable {
            nativeRecycle(mNativePtr);
            mNinePatchChunk = null;
            mRecycled = true;
            mHardwareBuffer = null;
        }
    }

@@ -748,7 +751,12 @@ public final class Bitmap implements Parcelable {
        if (colorSpace == null) {
            colorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
        }
        return nativeWrapHardwareBufferBitmap(hardwareBuffer, colorSpace.getNativeInstance());
        Bitmap bitmap = nativeWrapHardwareBufferBitmap(hardwareBuffer,
                colorSpace.getNativeInstance());
        if (bitmap != null) {
            bitmap.mHardwareBuffer = new WeakReference<HardwareBuffer>(hardwareBuffer);
        }
        return bitmap;
    }

    /**
@@ -2244,12 +2252,22 @@ public final class Bitmap implements Parcelable {
     *
     * Note: the HardwareBuffer does *not* have an associated {@link ColorSpace}.
     * To render this object the same as its rendered with this Bitmap, you
     * should also call {@link getColorSpace}.
     * should also call {@link #getColorSpace()}.</p>
     *
     * @hide
     * Must not be modified while a wrapped Bitmap is accessing it. Doing so will
     * result in undefined behavior.</p>
     *
     * @throws IllegalStateException if the bitmap's config is not {@link Config#HARDWARE}
     * or if the bitmap has been recycled.
     */
    public HardwareBuffer getHardwareBuffer() {
        return nativeGetHardwareBuffer(mNativePtr);
    public @NonNull HardwareBuffer getHardwareBuffer() {
        checkRecycled("Can't getHardwareBuffer from a recycled bitmap");
        HardwareBuffer hardwareBuffer = mHardwareBuffer == null ? null : mHardwareBuffer.get();
        if (hardwareBuffer == null) {
            hardwareBuffer = nativeGetHardwareBuffer(mNativePtr);
            mHardwareBuffer = new WeakReference<HardwareBuffer>(hardwareBuffer);
        }
        return hardwareBuffer;
    }

    //////////// native methods
+5 −2
Original line number Diff line number Diff line
@@ -1196,13 +1196,16 @@ static jobject Bitmap_wrapHardwareBufferBitmap(JNIEnv* env, jobject, jobject har
static jobject Bitmap_getHardwareBuffer(JNIEnv* env, jobject, jlong bitmapPtr) {
#ifdef __ANDROID__ // Layoutlib does not support graphic buffer
    LocalScopedBitmap bitmapHandle(bitmapPtr);
    LOG_ALWAYS_FATAL_IF(!bitmapHandle->isHardware(),
    if (!bitmapHandle->isHardware()) {
        jniThrowException(env, "java/lang/IllegalStateException",
            "Hardware config is only supported config in Bitmap_getHardwareBuffer");
        return nullptr;
    }

    Bitmap& bitmap = bitmapHandle->bitmap();
    return AHardwareBuffer_toHardwareBuffer(env, bitmap.hardwareBuffer());
#else
    return NULL;
    return nullptr;
#endif
}