Path: blob/main_old/src/common/android_util.cpp
1693 views
//1// Copyright 2018 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// android_util.cpp: Utilities for the using the Android platform78#include "common/android_util.h"9#include "common/debug.h"1011#include <cstdint>1213#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 2614# define ANGLE_AHARDWARE_BUFFER_SUPPORT15// NDK header file for access to Android Hardware Buffers16# include <android/hardware_buffer.h>17#endif1819// Taken from cutils/native_handle.h:20// https://android.googlesource.com/platform/system/core/+/master/libcutils/include/cutils/native_handle.h21typedef struct native_handle22{23int version; /* sizeof(native_handle_t) */24int numFds; /* number of file-descriptors at &data[0] */25int numInts; /* number of ints at &data[numFds] */26#if defined(__clang__)27# pragma clang diagnostic push28# pragma clang diagnostic ignored "-Wzero-length-array"29#elif defined(_MSC_VER)30# pragma warning(push)31# pragma warning(disable : 4200)32#endif33int data[0]; /* numFds + numInts ints */34#if defined(__clang__)35# pragma clang diagnostic pop36#elif defined(_MSC_VER)37# pragma warning(pop)38#endif39} native_handle_t;4041// Taken from nativebase/nativebase.h42// https://android.googlesource.com/platform/frameworks/native/+/master/libs/nativebase/include/nativebase/nativebase.h43typedef const native_handle_t *buffer_handle_t;4445typedef struct android_native_base_t46{47/* a magic value defined by the actual EGL native type */48int magic;49/* the sizeof() of the actual EGL native type */50int version;51void *reserved[4];52/* reference-counting interface */53void (*incRef)(struct android_native_base_t *base);54void (*decRef)(struct android_native_base_t *base);55} android_native_base_t;5657typedef struct ANativeWindowBuffer58{59struct android_native_base_t common;60int width;61int height;62int stride;63int format;64int usage_deprecated;65uintptr_t layerCount;66void *reserved[1];67const native_handle_t *handle;68uint64_t usage;69// we needed extra space for storing the 64-bits usage flags70// the number of slots to use from reserved_proc depends on the71// architecture.72void *reserved_proc[8 - (sizeof(uint64_t) / sizeof(void *))];73} ANativeWindowBuffer_t;7475// Taken from android/hardware_buffer.h76// https://android.googlesource.com/platform/frameworks/native/+/master/libs/nativewindow/include/android/hardware_buffer.h7778// AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM,79// AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM formats were deprecated and re-added explicitly.8081// clang-format off82/**83* Buffer pixel formats.84*/85enum {8687#ifndef ANGLE_AHARDWARE_BUFFER_SUPPORT88/**89* Corresponding formats:90* Vulkan: VK_FORMAT_R8G8B8A8_UNORM91* OpenGL ES: GL_RGBA892*/93AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,9495/**96* 32 bits per pixel, 8 bits per channel format where alpha values are97* ignored (always opaque).98* Corresponding formats:99* Vulkan: VK_FORMAT_R8G8B8A8_UNORM100* OpenGL ES: GL_RGB8101*/102AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM = 2,103104/**105* Corresponding formats:106* Vulkan: VK_FORMAT_R8G8B8_UNORM107* OpenGL ES: GL_RGB8108*/109AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM = 3,110111/**112* Corresponding formats:113* Vulkan: VK_FORMAT_R5G6B5_UNORM_PACK16114* OpenGL ES: GL_RGB565115*/116AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM = 4,117#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT118119AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM = 5,120AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM = 6,121AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM = 7,122123#ifndef ANGLE_AHARDWARE_BUFFER_SUPPORT124/**125* Corresponding formats:126* Vulkan: VK_FORMAT_R16G16B16A16_SFLOAT127* OpenGL ES: GL_RGBA16F128*/129AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT = 0x16,130131/**132* Corresponding formats:133* Vulkan: VK_FORMAT_A2B10G10R10_UNORM_PACK32134* OpenGL ES: GL_RGB10_A2135*/136AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM = 0x2b,137138/**139* An opaque binary blob format that must have height 1, with width equal to140* the buffer size in bytes.141*/142AHARDWAREBUFFER_FORMAT_BLOB = 0x21,143144/**145* Corresponding formats:146* Vulkan: VK_FORMAT_D16_UNORM147* OpenGL ES: GL_DEPTH_COMPONENT16148*/149AHARDWAREBUFFER_FORMAT_D16_UNORM = 0x30,150151/**152* Corresponding formats:153* Vulkan: VK_FORMAT_X8_D24_UNORM_PACK32154* OpenGL ES: GL_DEPTH_COMPONENT24155*/156AHARDWAREBUFFER_FORMAT_D24_UNORM = 0x31,157158/**159* Corresponding formats:160* Vulkan: VK_FORMAT_D24_UNORM_S8_UINT161* OpenGL ES: GL_DEPTH24_STENCIL8162*/163AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT = 0x32,164165/**166* Corresponding formats:167* Vulkan: VK_FORMAT_D32_SFLOAT168* OpenGL ES: GL_DEPTH_COMPONENT32F169*/170AHARDWAREBUFFER_FORMAT_D32_FLOAT = 0x33,171172/**173* Corresponding formats:174* Vulkan: VK_FORMAT_D32_SFLOAT_S8_UINT175* OpenGL ES: GL_DEPTH32F_STENCIL8176*/177AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT = 0x34,178179/**180* Corresponding formats:181* Vulkan: VK_FORMAT_S8_UINT182* OpenGL ES: GL_STENCIL_INDEX8183*/184AHARDWAREBUFFER_FORMAT_S8_UINT = 0x35,185186/**187* YUV 420 888 format.188* Must have an even width and height. Can be accessed in OpenGL189* shaders through an external sampler. Does not support mip-maps190* cube-maps or multi-layered textures.191*/192AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 = 0x23,193194#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT195};196// clang-format on197198namespace199{200201// In the Android system:202// - AHardwareBuffer is essentially a typedef of GraphicBuffer. Conversion functions simply203// reinterpret_cast.204// - GraphicBuffer inherits from two base classes, ANativeWindowBuffer and RefBase.205//206// GraphicBuffer implements a getter for ANativeWindowBuffer (getNativeBuffer) by static_casting207// itself to its base class ANativeWindowBuffer. The offset of the ANativeWindowBuffer pointer208// from the GraphicBuffer pointer is 16 bytes. This is likely due to two pointers: The vtable of209// GraphicBuffer and the one pointer member of the RefBase class.210//211// This is not future proof at all. We need to look into getting utilities added to Android to212// perform this cast for us.213constexpr int kAHardwareBufferToANativeWindowBufferOffset = static_cast<int>(sizeof(void *)) * 2;214215template <typename T1, typename T2>216T1 *offsetPointer(T2 *ptr, int bytes)217{218return reinterpret_cast<T1 *>(reinterpret_cast<intptr_t>(ptr) + bytes);219}220221GLenum getPixelFormatInfo(int pixelFormat, bool *isYUV)222{223*isYUV = false;224switch (pixelFormat)225{226case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:227return GL_RGBA8;228case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:229return GL_RGB8;230case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:231return GL_RGB8;232case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:233return GL_RGB565;234case AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM:235return GL_BGRA8_EXT;236case AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM:237return GL_RGB5_A1;238case AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM:239return GL_RGBA4;240case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:241return GL_RGBA16F;242case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:243return GL_RGB10_A2;244case AHARDWAREBUFFER_FORMAT_BLOB:245return GL_NONE;246case AHARDWAREBUFFER_FORMAT_D16_UNORM:247return GL_DEPTH_COMPONENT16;248case AHARDWAREBUFFER_FORMAT_D24_UNORM:249return GL_DEPTH_COMPONENT24;250case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:251return GL_DEPTH24_STENCIL8;252case AHARDWAREBUFFER_FORMAT_D32_FLOAT:253return GL_DEPTH_COMPONENT32F;254case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:255return GL_DEPTH32F_STENCIL8;256case AHARDWAREBUFFER_FORMAT_S8_UINT:257return GL_STENCIL_INDEX8;258case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:259*isYUV = true;260return GL_RGB8;261default:262// Treat unknown formats as RGB. They are vendor-specific YUV formats that would sample263// as RGB.264WARN() << "Unknown pixelFormat: " << pixelFormat << ". Treating as RGB8";265*isYUV = true;266return GL_RGB8;267}268}269270} // anonymous namespace271272namespace angle273{274275namespace android276{277278ANativeWindowBuffer *ClientBufferToANativeWindowBuffer(EGLClientBuffer clientBuffer)279{280return reinterpret_cast<ANativeWindowBuffer *>(clientBuffer);281}282283uint64_t GetAHBUsage(int eglNativeBufferUsage)284{285uint64_t ahbUsage = 0;286#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)287if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID)288{289ahbUsage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;290}291if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID)292{293ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;294}295if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)296{297ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;298}299#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT300return ahbUsage;301}302303EGLClientBuffer CreateEGLClientBufferFromAHardwareBuffer(int width,304int height,305int depth,306int androidFormat,307int usage)308{309#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)310311// The height and width are number of pixels of size format312AHardwareBuffer_Desc aHardwareBufferDescription = {};313aHardwareBufferDescription.width = static_cast<uint32_t>(width);314aHardwareBufferDescription.height = static_cast<uint32_t>(height);315aHardwareBufferDescription.layers = static_cast<uint32_t>(depth);316aHardwareBufferDescription.format = androidFormat;317aHardwareBufferDescription.usage = GetAHBUsage(usage);318319// Allocate memory from Android Hardware Buffer320AHardwareBuffer *aHardwareBuffer = nullptr;321int res = AHardwareBuffer_allocate(&aHardwareBufferDescription, &aHardwareBuffer);322if (res != 0)323{324return nullptr;325}326327return AHardwareBufferToClientBuffer(aHardwareBuffer);328#else329return nullptr;330#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT331}332333void GetANativeWindowBufferProperties(const ANativeWindowBuffer *buffer,334int *width,335int *height,336int *depth,337int *pixelFormat,338uint64_t *usage)339{340*width = buffer->width;341*height = buffer->height;342*depth = static_cast<int>(buffer->layerCount);343*height = buffer->height;344*pixelFormat = buffer->format;345*usage = buffer->usage;346}347348GLenum NativePixelFormatToGLInternalFormat(int pixelFormat)349{350bool isYuv = false;351return getPixelFormatInfo(pixelFormat, &isYuv);352}353354int GLInternalFormatToNativePixelFormat(GLenum internalFormat)355{356switch (internalFormat)357{358case GL_RGBA8:359return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;360case GL_RGB8:361return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;362case GL_RGB565:363return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;364case GL_BGRA8_EXT:365return AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM;366case GL_RGB5_A1:367return AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM;368case GL_RGBA4:369return AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM;370case GL_RGBA16F:371return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;372case GL_RGB10_A2:373return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;374case GL_NONE:375return AHARDWAREBUFFER_FORMAT_BLOB;376case GL_DEPTH_COMPONENT16:377return AHARDWAREBUFFER_FORMAT_D16_UNORM;378case GL_DEPTH_COMPONENT24:379return AHARDWAREBUFFER_FORMAT_D24_UNORM;380case GL_DEPTH24_STENCIL8:381return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;382case GL_DEPTH_COMPONENT32F:383return AHARDWAREBUFFER_FORMAT_D32_FLOAT;384case GL_DEPTH32F_STENCIL8:385return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;386case GL_STENCIL_INDEX8:387return AHARDWAREBUFFER_FORMAT_S8_UINT;388default:389WARN() << "Unknown internalFormat: " << internalFormat << ". Treating as 0";390return 0;391}392}393394bool NativePixelFormatIsYUV(int pixelFormat)395{396bool isYuv = false;397getPixelFormatInfo(pixelFormat, &isYuv);398return isYuv;399}400401AHardwareBuffer *ANativeWindowBufferToAHardwareBuffer(ANativeWindowBuffer *windowBuffer)402{403return offsetPointer<AHardwareBuffer>(windowBuffer,404-kAHardwareBufferToANativeWindowBufferOffset);405}406407EGLClientBuffer AHardwareBufferToClientBuffer(const AHardwareBuffer *hardwareBuffer)408{409return offsetPointer<EGLClientBuffer>(hardwareBuffer,410kAHardwareBufferToANativeWindowBufferOffset);411}412413AHardwareBuffer *ClientBufferToAHardwareBuffer(EGLClientBuffer clientBuffer)414{415return offsetPointer<AHardwareBuffer>(clientBuffer,416-kAHardwareBufferToANativeWindowBufferOffset);417}418} // namespace android419} // namespace angle420421422