Add HardwareBuffer support to Bitmaps
This adds a new public constructor to Bitmap to allow passing in a HardwareBuffer to back the Bitmap. Currently, the format of the HardwareBuffer must be RGBA_8888. One-Pager: https://docs.google.com/document/d/1n72X-gJZhjeajp4FIQwsGPKFiHBSeWYjC6fkXYe_bS0/edit?usp=sharing Bug: 116713113 Test: manual - ran CTS tests Change-Id: Ic437825138eafea526326e6cf300f116867ba29e
This commit is contained in:
@@ -24,6 +24,7 @@ import android.annotation.Size;
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.annotation.WorkerThread;
|
||||
import android.content.res.ResourcesImpl;
|
||||
import android.hardware.HardwareBuffer;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.StrictMode;
|
||||
@@ -723,6 +724,48 @@ public final class Bitmap implements Parcelable {
|
||||
return nativeCreateHardwareBitmap(graphicBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a hardware bitmap backed by a {@link HardwareBuffer}.
|
||||
*
|
||||
* <p>The passed HardwareBuffer's usage flags must contain
|
||||
* {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE}.
|
||||
*
|
||||
* <p>The bitmap will keep a reference to the buffer so that callers can safely close the
|
||||
* HardwareBuffer without affecting the Bitmap. However the HardwareBuffer must not be
|
||||
* modified while a wrapped Bitmap is accessing it. Doing so will result in undefined behavior.
|
||||
*
|
||||
* @param hardwareBuffer The HardwareBuffer to wrap.
|
||||
* @param colorSpace The color space of the bitmap. Must be a {@link ColorSpace.Rgb} colorspace.
|
||||
* If null, SRGB is assumed.
|
||||
* @return A bitmap wrapping the buffer, or null if there was a problem creating the bitmap.
|
||||
* @throws IllegalArgumentException if the HardwareBuffer has an invalid usage, or an invalid
|
||||
* colorspace is given.
|
||||
*/
|
||||
@Nullable
|
||||
public static Bitmap wrapHardwareBuffer(@NonNull HardwareBuffer hardwareBuffer,
|
||||
@Nullable ColorSpace colorSpace) {
|
||||
if ((hardwareBuffer.getUsage() & HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE) == 0) {
|
||||
throw new IllegalArgumentException("usage flags must contain USAGE_GPU_SAMPLED_IMAGE.");
|
||||
}
|
||||
int format = hardwareBuffer.getFormat();
|
||||
ColorSpace.Rgb rgb = null;
|
||||
if (colorSpace != null) {
|
||||
if (!(colorSpace instanceof ColorSpace.Rgb)) {
|
||||
throw new IllegalArgumentException("colorSpace must be an RGB color space");
|
||||
}
|
||||
rgb = (ColorSpace.Rgb) colorSpace;
|
||||
} else {
|
||||
rgb = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB);
|
||||
}
|
||||
ColorSpace.Rgb.TransferParameters parameters = rgb.getTransferParameters();
|
||||
if (parameters == null) {
|
||||
throw new IllegalArgumentException("colorSpace must use an ICC "
|
||||
+ "parametric transfer function");
|
||||
}
|
||||
ColorSpace.Rgb d50 = (ColorSpace.Rgb) ColorSpace.adapt(rgb, ColorSpace.ILLUMINANT_D50);
|
||||
return nativeWrapHardwareBufferBitmap(hardwareBuffer, d50.getTransform(), parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new bitmap, scaled from an existing bitmap, when possible. If the
|
||||
* specified width and height are the same as the current width and height of
|
||||
@@ -2118,6 +2161,9 @@ public final class Bitmap implements Parcelable {
|
||||
private static native int nativeGetAllocationByteCount(long nativeBitmap);
|
||||
private static native Bitmap nativeCopyPreserveInternalConfig(long nativeBitmap);
|
||||
private static native Bitmap nativeCreateHardwareBitmap(GraphicBuffer buffer);
|
||||
private static native Bitmap nativeWrapHardwareBufferBitmap(HardwareBuffer buffer,
|
||||
@Size(9) float[] xyzD50,
|
||||
ColorSpace.Rgb.TransferParameters p);
|
||||
private static native GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap);
|
||||
private static native boolean nativeGetColorSpace(long nativePtr, float[] xyz, float[] params);
|
||||
private static native boolean nativeIsSRGB(long nativePtr);
|
||||
|
||||
Reference in New Issue
Block a user