All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.android.hardware.HardwareBuffer Maven / Gradle / Ivy

Go to download

A library jar that provides APIs for Applications written for the Google Android Platform.

There is a newer version: 15-robolectric-12650502
Show newest version
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware;

import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.LongDef;
import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.graphics.GraphicBuffer;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;

import dalvik.annotation.optimization.FastNative;
import dalvik.system.CloseGuard;

import libcore.util.NativeAllocationRegistry;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * HardwareBuffer wraps a native AHardwareBuffer object, which is a low-level object
 * representing a memory buffer accessible by various hardware units. HardwareBuffer allows sharing
 * buffers across different application processes. In particular, HardwareBuffers may be mappable
 * to memory accessibly to various hardware systems, such as the GPU, a sensor or context hub, or
 * other auxiliary processing units.
 *
 * For more information, see the NDK documentation for AHardwareBuffer.
 */
public final class HardwareBuffer implements Parcelable, AutoCloseable {
    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "RGB", "BLOB", "D_", "DS_", "S_" }, value = {
            RGBA_8888,
            RGBA_FP16,
            RGBA_1010102,
            RGBX_8888,
            RGB_888,
            RGB_565,
            BLOB,
            D_16,
            D_24,
            DS_24UI8,
            D_FP32,
            DS_FP32UI8,
            S_UI8,
    })
    public @interface Format {
    }

    @Format
    /** Format: 8 bits each red, green, blue, alpha */
    public static final int RGBA_8888    = 1;
    /** Format: 8 bits each red, green, blue, alpha, alpha is always 0xFF */
    public static final int RGBX_8888    = 2;
    /** Format: 8 bits each red, green, blue, no alpha */
    public static final int RGB_888      = 3;
    /** Format: 5 bits each red and blue, 6 bits green, no alpha */
    public static final int RGB_565      = 4;
    /** Format: 16 bits each red, green, blue, alpha */
    public static final int RGBA_FP16    = 0x16;
    /** Format: 10 bits each red, green, blue, 2 bits alpha */
    public static final int RGBA_1010102 = 0x2b;
    /** Format: opaque format used for raw data transfer; must have a height of 1 */
    public static final int BLOB         = 0x21;
    /** Format: 16 bits depth */
    public static final int D_16         = 0x30;
    /** Format: 24 bits depth */
    public static final int D_24         = 0x31;
    /** Format: 24 bits depth, 8 bits stencil */
    public static final int DS_24UI8     = 0x32;
    /** Format: 32 bits depth */
    public static final int D_FP32       = 0x33;
    /** Format: 32 bits depth, 8 bits stencil */
    public static final int DS_FP32UI8   = 0x34;
    /** Format: 8 bits stencil */
    public static final int S_UI8        = 0x35;

    // Note: do not rename, this field is used by native code
    @UnsupportedAppUsage
    private long mNativeObject;

    // Invoked on destruction
    private Runnable mCleaner;

    private final CloseGuard mCloseGuard = CloseGuard.get();

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @LongDef(flag = true, value = {USAGE_CPU_READ_RARELY, USAGE_CPU_READ_OFTEN,
            USAGE_CPU_WRITE_RARELY, USAGE_CPU_WRITE_OFTEN, USAGE_GPU_SAMPLED_IMAGE,
            USAGE_GPU_COLOR_OUTPUT, USAGE_PROTECTED_CONTENT, USAGE_VIDEO_ENCODE,
            USAGE_GPU_DATA_BUFFER, USAGE_SENSOR_DIRECT_DATA, USAGE_GPU_CUBE_MAP,
            USAGE_GPU_MIPMAP_COMPLETE})
    public @interface Usage {};

    @Usage
    /** Usage: The buffer will sometimes be read by the CPU */
    public static final long USAGE_CPU_READ_RARELY       = 2;
    /** Usage: The buffer will often be read by the CPU */
    public static final long USAGE_CPU_READ_OFTEN        = 3;

    /** Usage: The buffer will sometimes be written to by the CPU */
    public static final long USAGE_CPU_WRITE_RARELY      = 2 << 4;
    /** Usage: The buffer will often be written to by the CPU */
    public static final long USAGE_CPU_WRITE_OFTEN       = 3 << 4;

    /** Usage: The buffer will be read from by the GPU */
    public static final long USAGE_GPU_SAMPLED_IMAGE      = 1 << 8;
    /** Usage: The buffer will be written to by the GPU */
    public static final long USAGE_GPU_COLOR_OUTPUT       = 1 << 9;
    /** Usage: The buffer must not be used outside of a protected hardware path */
    public static final long USAGE_PROTECTED_CONTENT      = 1 << 14;
    /** Usage: The buffer will be read by a hardware video encoder */
    public static final long USAGE_VIDEO_ENCODE           = 1 << 16;
    /** Usage: The buffer will be used for sensor direct data */
    public static final long USAGE_SENSOR_DIRECT_DATA     = 1 << 23;
    /** Usage: The buffer will be used as a shader storage or uniform buffer object */
    public static final long USAGE_GPU_DATA_BUFFER        = 1 << 24;
    /** Usage: The buffer will be used as a cube map texture */
    public static final long USAGE_GPU_CUBE_MAP           = 1 << 25;
    /** Usage: The buffer contains a complete mipmap hierarchy */
    public static final long USAGE_GPU_MIPMAP_COMPLETE    = 1 << 26;

    // The approximate size of a native AHardwareBuffer object.
    private static final long NATIVE_HARDWARE_BUFFER_SIZE = 232;
    /**
     * Creates a new HardwareBuffer instance.
     *
     * 

Calling this method will throw an IllegalStateException if * format is not a supported Format type.

* * @param width The width in pixels of the buffer * @param height The height in pixels of the buffer * @param format The @Format of each pixel * @param layers The number of layers in the buffer * @param usage The @Usage flags describing how the buffer will be used * @return A HardwareBuffer instance if successful, or throws an * IllegalArgumentException if the dimensions passed are invalid (either zero, negative, or * too large to allocate), if the format is not supported, if the requested number of layers * is less than one or not supported, or if the passed usage flags are not a supported set. */ @NonNull public static HardwareBuffer create( @IntRange(from = 1) int width, @IntRange(from = 1) int height, @Format int format, @IntRange(from = 1) int layers, @Usage long usage) { if (!HardwareBuffer.isSupportedFormat(format)) { throw new IllegalArgumentException("Invalid pixel format " + format); } if (width <= 0) { throw new IllegalArgumentException("Invalid width " + width); } if (height <= 0) { throw new IllegalArgumentException("Invalid height " + height); } if (layers <= 0) { throw new IllegalArgumentException("Invalid layer count " + layers); } if (format == BLOB && height != 1) { throw new IllegalArgumentException("Height must be 1 when using the BLOB format"); } long nativeObject = nCreateHardwareBuffer(width, height, format, layers, usage); if (nativeObject == 0) { throw new IllegalArgumentException("Unable to create a HardwareBuffer, either the " + "dimensions passed were too large, too many image layers were requested, " + "or an invalid set of usage flags or invalid format was passed"); } return new HardwareBuffer(nativeObject); } /** * Queries whether the given buffer description is supported by the system. If this returns * true, then the allocation may succeed until resource exhaustion occurs. If this returns * false then this combination will never succeed. * * @param width The width in pixels of the buffer * @param height The height in pixels of the buffer * @param format The @Format of each pixel * @param layers The number of layers in the buffer * @param usage The @Usage flags describing how the buffer will be used * @return True if the combination is supported, false otherwise. */ public static boolean isSupported(@IntRange(from = 1) int width, @IntRange(from = 1) int height, @Format int format, @IntRange(from = 1) int layers, @Usage long usage) { if (!HardwareBuffer.isSupportedFormat(format)) { throw new IllegalArgumentException("Invalid pixel format " + format); } if (width <= 0) { throw new IllegalArgumentException("Invalid width " + width); } if (height <= 0) { throw new IllegalArgumentException("Invalid height " + height); } if (layers <= 0) { throw new IllegalArgumentException("Invalid layer count " + layers); } if (format == BLOB && height != 1) { throw new IllegalArgumentException("Height must be 1 when using the BLOB format"); } return nIsSupported(width, height, format, layers, usage); } /** * @hide * Returns a HardwareBuffer instance from GraphicBuffer * * @param graphicBuffer A GraphicBuffer to be wrapped as HardwareBuffer * @return A HardwareBuffer instance. */ @NonNull public static HardwareBuffer createFromGraphicBuffer(@NonNull GraphicBuffer graphicBuffer) { long nativeObject = nCreateFromGraphicBuffer(graphicBuffer); return new HardwareBuffer(nativeObject); } /** * Private use only. See {@link #create(int, int, int, int, long)}. May also be * called from JNI using an already allocated native HardwareBuffer. */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private HardwareBuffer(long nativeObject) { mNativeObject = nativeObject; ClassLoader loader = HardwareBuffer.class.getClassLoader(); NativeAllocationRegistry registry = new NativeAllocationRegistry( loader, nGetNativeFinalizer(), NATIVE_HARDWARE_BUFFER_SIZE); mCleaner = registry.registerNativeAllocation(this, mNativeObject); mCloseGuard.open("close"); } @Override protected void finalize() throws Throwable { try { mCloseGuard.warnIfOpen(); close(); } finally { super.finalize(); } } /** * Returns the width of this buffer in pixels. */ public int getWidth() { if (isClosed()) { throw new IllegalStateException("This HardwareBuffer has been closed and its width " + "cannot be obtained."); } return nGetWidth(mNativeObject); } /** * Returns the height of this buffer in pixels. */ public int getHeight() { if (isClosed()) { throw new IllegalStateException("This HardwareBuffer has been closed and its height " + "cannot be obtained."); } return nGetHeight(mNativeObject); } /** * Returns the @Format of this buffer. */ @Format public int getFormat() { if (isClosed()) { throw new IllegalStateException("This HardwareBuffer has been closed and its format " + "cannot be obtained."); } return nGetFormat(mNativeObject); } /** * Returns the number of layers in this buffer. */ public int getLayers() { if (isClosed()) { throw new IllegalStateException("This HardwareBuffer has been closed and its layer " + "count cannot be obtained."); } return nGetLayers(mNativeObject); } /** * Returns the usage flags of the usage hints set on this buffer. */ public long getUsage() { if (isClosed()) { throw new IllegalStateException("This HardwareBuffer has been closed and its usage " + "cannot be obtained."); } return nGetUsage(mNativeObject); } /** @removed replaced by {@link #close()} */ @Deprecated public void destroy() { close(); } /** @removed replaced by {@link #isClosed()} */ @Deprecated public boolean isDestroyed() { return isClosed(); } /** * Destroys this buffer immediately. Calling this method frees up any * underlying native resources. After calling this method, this buffer * must not be used in any way. * * @see #isClosed() */ @Override public void close() { if (!isClosed()) { mCloseGuard.close(); mNativeObject = 0; mCleaner.run(); mCleaner = null; } } /** * Indicates whether this buffer has been closed. A closed buffer cannot * be used in any way: the buffer cannot be written to a parcel, etc. * * @return True if this HardwareBuffer is in a closed state, * false otherwise. * * @see #close() */ public boolean isClosed() { return mNativeObject == 0; } @Override public int describeContents() { return Parcelable.CONTENTS_FILE_DESCRIPTOR; } /** * Flatten this object in to a Parcel. * *

Calling this method will throw an IllegalStateException if * {@link #close()} has been previously called.

* * @param dest The Parcel in which the object should be written. * @param flags Additional flags about how the object should be written. * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}. */ @Override public void writeToParcel(Parcel dest, int flags) { if (isClosed()) { throw new IllegalStateException("This HardwareBuffer has been closed and cannot be " + "written to a parcel."); } nWriteHardwareBufferToParcel(mNativeObject, dest); } public static final @android.annotation.NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { public HardwareBuffer createFromParcel(Parcel in) { long nativeObject = nReadHardwareBufferFromParcel(in); if (nativeObject != 0) { return new HardwareBuffer(nativeObject); } return null; } public HardwareBuffer[] newArray(int size) { return new HardwareBuffer[size]; } }; /** * Validates whether a particular format is supported by HardwareBuffer. * * @param format The format to validate. * * @return True if format is a supported format. false otherwise. * See {@link #create(int, int, int, int, long)}. */ private static boolean isSupportedFormat(@Format int format) { switch(format) { case RGBA_8888: case RGBA_FP16: case RGBA_1010102: case RGBX_8888: case RGB_565: case RGB_888: case BLOB: case D_16: case D_24: case DS_24UI8: case D_FP32: case DS_FP32UI8: case S_UI8: return true; } return false; } private static native long nCreateHardwareBuffer(int width, int height, int format, int layers, long usage); private static native long nCreateFromGraphicBuffer(GraphicBuffer graphicBuffer); private static native long nGetNativeFinalizer(); private static native void nWriteHardwareBufferToParcel(long nativeObject, Parcel dest); private static native long nReadHardwareBufferFromParcel(Parcel in); @FastNative private static native int nGetWidth(long nativeObject); @FastNative private static native int nGetHeight(long nativeObject); @FastNative private static native int nGetFormat(long nativeObject); @FastNative private static native int nGetLayers(long nativeObject); @FastNative private static native long nGetUsage(long nativeObject); private static native boolean nIsSupported(int width, int height, int format, int layers, long usage); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy