Native Hardware Buffer

AHardwareBuffer objects represent chunks of memory that can be accessed by various hardware components in the system.

Summary

It can be easily converted to the Java counterpart android.hardware.HardwareBuffer and passed between processes using Binder. All operations involving AHardwareBuffer and HardwareBuffer are zero-copy, i.e., passing AHardwareBuffer to another process creates a shared view of the same region of memory.

AHardwareBuffers can be bound to EGL/OpenGL and Vulkan primitives. For EGL, use the extension function eglGetNativeClientBufferANDROID to obtain an EGLClientBuffer and pass it directly to eglCreateImageKHR. Refer to the EGL extensions EGL_ANDROID_get_native_client_buffer and EGL_ANDROID_image_native_buffer for more information. In Vulkan, the contents of the AHardwareBuffer can be accessed as external memory. See the VK_ANDROID_external_memory_android_hardware_buffer extension for details.

Enumerations

AHardwareBuffer_Format{
  AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
  AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM = 2,
  AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM = 3,
  AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM = 4,
  AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT = 0x16,
  AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM = 0x2b,
  AHARDWAREBUFFER_FORMAT_BLOB = 0x21,
  AHARDWAREBUFFER_FORMAT_D16_UNORM = 0x30,
  AHARDWAREBUFFER_FORMAT_D24_UNORM = 0x31,
  AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT = 0x32,
  AHARDWAREBUFFER_FORMAT_D32_FLOAT = 0x33,
  AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT = 0x34,
  AHARDWAREBUFFER_FORMAT_S8_UINT = 0x35
}
enum
Buffer pixel formats.
AHardwareBuffer_UsageFlags{
  AHARDWAREBUFFER_USAGE_CPU_READ_NEVER = 0UL,
  AHARDWAREBUFFER_USAGE_CPU_READ_RARELY = 2UL,
  AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN = 3UL,
  AHARDWAREBUFFER_USAGE_CPU_READ_MASK = 0xFUL,
  AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER = 0UL << 4,
  AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY = 2UL << 4,
  AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN = 3UL << 4,
  AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK = 0xFUL << 4,
  AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE = 1UL << 8,
  AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER = 1UL << 9,
  AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER,
  AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY = 1ULL << 11,
  AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT = 1UL << 14,
  AHARDWAREBUFFER_USAGE_VIDEO_ENCODE = 1UL << 16,
  AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA = 1UL << 23,
  AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER = 1UL << 24,
  AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP = 1UL << 25,
  AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE = 1UL << 26,
  AHARDWAREBUFFER_USAGE_VENDOR_0 = 1ULL << 28,
  AHARDWAREBUFFER_USAGE_VENDOR_1 = 1ULL << 29,
  AHARDWAREBUFFER_USAGE_VENDOR_2 = 1ULL << 30,
  AHARDWAREBUFFER_USAGE_VENDOR_3 = 1ULL << 31,
  AHARDWAREBUFFER_USAGE_VENDOR_4 = 1ULL << 48,
  AHARDWAREBUFFER_USAGE_VENDOR_5 = 1ULL << 49,
  AHARDWAREBUFFER_USAGE_VENDOR_6 = 1ULL << 50,
  AHARDWAREBUFFER_USAGE_VENDOR_7 = 1ULL << 51,
  AHARDWAREBUFFER_USAGE_VENDOR_8 = 1ULL << 52,
  AHARDWAREBUFFER_USAGE_VENDOR_9 = 1ULL << 53,
  AHARDWAREBUFFER_USAGE_VENDOR_10 = 1ULL << 54,
  AHARDWAREBUFFER_USAGE_VENDOR_11 = 1ULL << 55,
  AHARDWAREBUFFER_USAGE_VENDOR_12 = 1ULL << 56,
  AHARDWAREBUFFER_USAGE_VENDOR_13 = 1ULL << 57,
  AHARDWAREBUFFER_USAGE_VENDOR_14 = 1ULL << 58,
  AHARDWAREBUFFER_USAGE_VENDOR_15 = 1ULL << 59,
  AHARDWAREBUFFER_USAGE_VENDOR_16 = 1ULL << 60,
  AHARDWAREBUFFER_USAGE_VENDOR_17 = 1ULL << 61,
  AHARDWAREBUFFER_USAGE_VENDOR_18 = 1ULL << 62,
  AHARDWAREBUFFER_USAGE_VENDOR_19 = 1ULL << 63
}
enum
Buffer usage flags, specifying how the buffer will be accessed.

Typedefs

AHardwareBuffer typedef
Opaque handle for a native hardware buffer.
AHardwareBuffer_Desc typedef
Buffer description.

Functions

AHardwareBuffer_acquire(AHardwareBuffer *buffer)
void
Acquire a reference on the given AHardwareBuffer object.
AHardwareBuffer_allocate(const AHardwareBuffer_Desc *desc, AHardwareBuffer **outBuffer)
int
Allocates a buffer that matches the passed AHardwareBuffer_Desc.
AHardwareBuffer_describe(const AHardwareBuffer *buffer, AHardwareBuffer_Desc *outDesc)
void
Return a description of the AHardwareBuffer in the passed AHardwareBuffer_Desc struct.
AHardwareBuffer_isSupported(const AHardwareBuffer_Desc *desc)
int
Test whether the given format and usage flag combination is allocatable.
AHardwareBuffer_lock(AHardwareBuffer *buffer, uint64_t usage, int32_t fence, const ARect *rect, void **outVirtualAddress)
int
Lock the AHardwareBuffer for direct CPU access.
AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer **outBuffer)
int
Receive an AHardwareBuffer from an AF_UNIX socket.
AHardwareBuffer_release(AHardwareBuffer *buffer)
void
Remove a reference that was previously acquired with AHardwareBuffer_acquire() or AHardwareBuffer_allocate().
AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer *buffer, int socketFd)
int
Send the AHardwareBuffer to an AF_UNIX socket.
AHardwareBuffer_unlock(AHardwareBuffer *buffer, int32_t *fence)
int
Unlock the AHardwareBuffer from direct CPU access.

Structs

AHardwareBuffer_Desc

Buffer description.

Enumerations

AHardwareBuffer_Format

 AHardwareBuffer_Format

Buffer pixel formats.

Properties
AHARDWAREBUFFER_FORMAT_BLOB

Opaque binary blob format.

Must have height 1 and one layer, with width equal to the buffer size in bytes. Corresponds to Vulkan buffers and OpenGL buffer objects. Can be bound to the latter using GL_EXT_external_buffer.

AHARDWAREBUFFER_FORMAT_D16_UNORM

Corresponding formats: Vulkan: VK_FORMAT_D16_UNORM OpenGL ES: GL_DEPTH_COMPONENT16.

AHARDWAREBUFFER_FORMAT_D24_UNORM

Corresponding formats: Vulkan: VK_FORMAT_X8_D24_UNORM_PACK32 OpenGL ES: GL_DEPTH_COMPONENT24.

AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT

Corresponding formats: Vulkan: VK_FORMAT_D24_UNORM_S8_UINT OpenGL ES: GL_DEPTH24_STENCIL8.

AHARDWAREBUFFER_FORMAT_D32_FLOAT

Corresponding formats: Vulkan: VK_FORMAT_D32_SFLOAT OpenGL ES: GL_DEPTH_COMPONENT32F.

AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT

Corresponding formats: Vulkan: VK_FORMAT_D32_SFLOAT_S8_UINT OpenGL ES: GL_DEPTH32F_STENCIL8.

AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM

Corresponding formats: Vulkan: VK_FORMAT_A2B10G10R10_UNORM_PACK32 OpenGL ES: GL_RGB10_A2.

AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT

Corresponding formats: Vulkan: VK_FORMAT_R16G16B16A16_SFLOAT OpenGL ES: GL_RGBA16F.

AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM

Corresponding formats: Vulkan: VK_FORMAT_R5G6B5_UNORM_PACK16 OpenGL ES: GL_RGB565.

AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM

Corresponding formats: Vulkan: VK_FORMAT_R8G8B8A8_UNORM OpenGL ES: GL_RGBA8.

AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM

32 bits per pixel, 8 bits per channel format where alpha values are ignored (always opaque).

Corresponding formats: Vulkan: VK_FORMAT_R8G8B8A8_UNORM OpenGL ES: GL_RGB8

AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM

Corresponding formats: Vulkan: VK_FORMAT_R8G8B8_UNORM OpenGL ES: GL_RGB8.

AHARDWAREBUFFER_FORMAT_S8_UINT

Corresponding formats: Vulkan: VK_FORMAT_S8_UINT OpenGL ES: GL_STENCIL_INDEX8.

AHardwareBuffer_UsageFlags

 AHardwareBuffer_UsageFlags

Buffer usage flags, specifying how the buffer will be accessed.

Properties
AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY

The buffer will be used as a composer HAL overlay layer.

This flag is currently only needed when using ASurfaceTransaction_setBuffer to set a buffer. In all other cases, the framework adds this flag internally to buffers that could be presented in a composer overlay. ASurfaceTransaction_setBuffer is special because it uses buffers allocated directly through AHardwareBuffer_allocate instead of buffers allocated by the framework.

AHARDWAREBUFFER_USAGE_CPU_READ_MASK

CPU read value mask.

AHARDWAREBUFFER_USAGE_CPU_READ_NEVER

The buffer will never be locked for direct CPU reads using the AHardwareBuffer_lock() function.

Note that reading the buffer using OpenGL or Vulkan functions or memory mappings is still allowed.

AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN

The buffer will often be locked for direct CPU reads using the AHardwareBuffer_lock() function.

Note that reading the buffer using OpenGL or Vulkan functions or memory mappings does not require the presence of this flag.

AHARDWAREBUFFER_USAGE_CPU_READ_RARELY

The buffer will sometimes be locked for direct CPU reads using the AHardwareBuffer_lock() function.

Note that reading the buffer using OpenGL or Vulkan functions or memory mappings does not require the presence of this flag.

AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK

CPU write value mask.

AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER

The buffer will never be locked for direct CPU writes using the AHardwareBuffer_lock() function.

Note that writing the buffer using OpenGL or Vulkan functions or memory mappings is still allowed.

AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN

The buffer will often be locked for direct CPU writes using the AHardwareBuffer_lock() function.

Note that writing the buffer using OpenGL or Vulkan functions or memory mappings does not require the presence of this flag.

AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY

The buffer will sometimes be locked for direct CPU writes using the AHardwareBuffer_lock() function.

Note that writing the buffer using OpenGL or Vulkan functions or memory mappings does not require the presence of this flag.

AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT

The buffer will be written to by the GPU as a framebuffer attachment.

Note that the name of this flag is somewhat misleading: it does not imply that the buffer contains a color format. A buffer with depth or stencil format that will be used as a framebuffer attachment should also have this flag. Use the equivalent flag AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER to avoid this confusion.

AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP

The buffer will be used as a cube map texture.

When this flag is present, the buffer must have a layer count that is a multiple of 6. Note that buffers with this flag must be bound to OpenGL textures using the extension GL_EXT_EGL_image_storage instead of GL_KHR_EGL_image.

AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER

The buffer will be used as a shader storage or uniform buffer object.

When this flag is present, the format must be AHARDWAREBUFFER_FORMAT_BLOB.

AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER

The buffer will be written to by the GPU as a framebuffer attachment.

AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE

The buffer contains a complete mipmap hierarchy.

Note that buffers with this flag must be bound to OpenGL textures using the extension GL_EXT_EGL_image_storage instead of GL_KHR_EGL_image.

AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE

The buffer will be read from by the GPU as a texture.

AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT

The buffer is protected from direct CPU access or being read by non-secure hardware, such as video encoders.

This flag is incompatible with CPU read and write flags. It is mainly used when handling DRM video. Refer to the EGL extension EGL_EXT_protected_content and GL extension GL_EXT_protected_textures for more information on how these buffers are expected to behave.

AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA

The buffer will be used for direct writes from sensors.

When this flag is present, the format must be AHARDWAREBUFFER_FORMAT_BLOB.

AHARDWAREBUFFER_USAGE_VENDOR_0
AHARDWAREBUFFER_USAGE_VENDOR_1
AHARDWAREBUFFER_USAGE_VENDOR_10
AHARDWAREBUFFER_USAGE_VENDOR_11
AHARDWAREBUFFER_USAGE_VENDOR_12
AHARDWAREBUFFER_USAGE_VENDOR_13
AHARDWAREBUFFER_USAGE_VENDOR_14
AHARDWAREBUFFER_USAGE_VENDOR_15
AHARDWAREBUFFER_USAGE_VENDOR_16
AHARDWAREBUFFER_USAGE_VENDOR_17
AHARDWAREBUFFER_USAGE_VENDOR_18
AHARDWAREBUFFER_USAGE_VENDOR_19
AHARDWAREBUFFER_USAGE_VENDOR_2
AHARDWAREBUFFER_USAGE_VENDOR_3
AHARDWAREBUFFER_USAGE_VENDOR_4
AHARDWAREBUFFER_USAGE_VENDOR_5
AHARDWAREBUFFER_USAGE_VENDOR_6
AHARDWAREBUFFER_USAGE_VENDOR_7
AHARDWAREBUFFER_USAGE_VENDOR_8
AHARDWAREBUFFER_USAGE_VENDOR_9
AHARDWAREBUFFER_USAGE_VIDEO_ENCODE

The buffer will be read by a hardware video encoder.

Typedefs

AHardwareBuffer

struct AHardwareBuffer AHardwareBuffer

Opaque handle for a native hardware buffer.

AHardwareBuffer_Desc

struct AHardwareBuffer_Desc AHardwareBuffer_Desc

Buffer description.

Used for allocating new buffers and querying parameters of existing ones.

Functions

AHardwareBuffer_acquire

void AHardwareBuffer_acquire(
  AHardwareBuffer *buffer
)

Acquire a reference on the given AHardwareBuffer object.

This prevents the object from being deleted until the last reference is removed.

AHardwareBuffer_allocate

int AHardwareBuffer_allocate(
  const AHardwareBuffer_Desc *desc,
  AHardwareBuffer **outBuffer
)

Allocates a buffer that matches the passed AHardwareBuffer_Desc.

If allocation succeeds, the buffer can be used according to the usage flags specified in its description. If a buffer is used in ways not compatible with its usage flags, the results are undefined and may include program termination.

Details
Returns
0 on success, or an error number of the allocation fails for any reason. The returned buffer has a reference count of 1.

AHardwareBuffer_describe

void AHardwareBuffer_describe(
  const AHardwareBuffer *buffer,
  AHardwareBuffer_Desc *outDesc
)

Return a description of the AHardwareBuffer in the passed AHardwareBuffer_Desc struct.

AHardwareBuffer_isSupported

int AHardwareBuffer_isSupported(
  const AHardwareBuffer_Desc *desc
)

Test whether the given format and usage flag combination is allocatable.

If this function returns true, it means that a buffer with the given description can be allocated on this implementation, unless resource exhaustion occurs. If this function returns false, it means that the allocation of the given description will never succeed.

The return value of this function may depend on all fields in the description, except stride, which is always ignored. For example, some implementations have implementation-defined limits on texture size and layer count.

Details
Returns
1 if the format and usage flag combination is allocatable, 0 otherwise.

AHardwareBuffer_lock

int AHardwareBuffer_lock(
  AHardwareBuffer *buffer,
  uint64_t usage,
  int32_t fence,
  const ARect *rect,
  void **outVirtualAddress
)

Lock the AHardwareBuffer for direct CPU access.

This function can lock the buffer for either reading or writing. It may block if the hardware needs to finish rendering, if CPU caches need to be synchronized, or possibly for other implementation- specific reasons.

The passed AHardwareBuffer must have one layer, otherwise the call will fail.

If fence is not negative, it specifies a fence file descriptor on which to wait before locking the buffer. If it's negative, the caller is responsible for ensuring that writes to the buffer have completed before calling this function. Using this parameter is more efficient than waiting on the fence and then calling this function.

The usage parameter may only specify AHARDWAREBUFFER_USAGE_CPU_*. If set, then outVirtualAddress is filled with the address of the buffer in virtual memory. The flags must also be compatible with usage flags specified at buffer creation: if a read flag is passed, the buffer must have been created with AHARDWAREBUFFER_USAGE_CPU_READ_RARELY or AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN. If a write flag is passed, it must have been created with AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY or AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN.

If rect is not NULL, the caller promises to modify only data in the area specified by rect. If rect is NULL, the caller may modify the contents of the entire buffer. The content of the buffer outside of the specified rect is NOT modified by this call.

It is legal for several different threads to lock a buffer for read access; none of the threads are blocked.

Locking a buffer simultaneously for write or read/write is undefined, but will neither terminate the process nor block the caller. AHardwareBuffer_lock may return an error or leave the buffer's content in an indeterminate state.

If the buffer has AHARDWAREBUFFER_FORMAT_BLOB, it is legal lock it for reading and writing in multiple threads and/or processes simultaneously, and the contents of the buffer behave like shared memory.

Details
Returns
0 on success. -EINVAL if buffer is NULL, the usage flags are not a combination of AHARDWAREBUFFER_USAGE_CPU_*, or the buffer has more than one layer. Error number if the lock fails for any other reason.

AHardwareBuffer_recvHandleFromUnixSocket

int AHardwareBuffer_recvHandleFromUnixSocket(
  int socketFd,
  AHardwareBuffer **outBuffer
)

Receive an AHardwareBuffer from an AF_UNIX socket.

Details
Returns
0 on success, -EINVAL if outBuffer is NULL, or an error number if the operation fails for any reason.

AHardwareBuffer_release

void AHardwareBuffer_release(
  AHardwareBuffer *buffer
)

Remove a reference that was previously acquired with AHardwareBuffer_acquire() or AHardwareBuffer_allocate().

AHardwareBuffer_sendHandleToUnixSocket

int AHardwareBuffer_sendHandleToUnixSocket(
  const AHardwareBuffer *buffer,
  int socketFd
)

Send the AHardwareBuffer to an AF_UNIX socket.

Details
Returns
0 on success, -EINVAL if buffer is NULL, or an error number if the operation fails for any reason.

AHardwareBuffer_unlock

int AHardwareBuffer_unlock(
  AHardwareBuffer *buffer,
  int32_t *fence
)

Unlock the AHardwareBuffer from direct CPU access.

Must be called after all changes to the buffer are completed by the caller. If fence is NULL, the function will block until all work is completed. Otherwise, fence will be set either to a valid file descriptor or to -1. The file descriptor will become signaled once the unlocking is complete and buffer contents are updated. The caller is responsible for closing the file descriptor once it's no longer needed. The value -1 indicates that unlocking has already completed before the function returned and no further operations are necessary.

Details
Returns
0 on success. -EINVAL if buffer is NULL. Error number if the unlock fails for any reason.