tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

android_util.cpp (14146B)


      1 //
      2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // android_util.cpp: Utilities for the using the Android platform
      8 
      9 #include "common/android_util.h"
     10 #include "common/debug.h"
     11 
     12 #include <cstdint>
     13 
     14 #if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26
     15 #    define ANGLE_AHARDWARE_BUFFER_SUPPORT
     16 // NDK header file for access to Android Hardware Buffers
     17 #    include <android/hardware_buffer.h>
     18 #endif
     19 
     20 // Taken from cutils/native_handle.h:
     21 // https://android.googlesource.com/platform/system/core/+/master/libcutils/include/cutils/native_handle.h
     22 typedef struct native_handle
     23 {
     24    int version; /* sizeof(native_handle_t) */
     25    int numFds;  /* number of file-descriptors at &data[0] */
     26    int numInts; /* number of ints at &data[numFds] */
     27 #if defined(__clang__)
     28 #    pragma clang diagnostic push
     29 #    pragma clang diagnostic ignored "-Wzero-length-array"
     30 #elif defined(_MSC_VER)
     31 #    pragma warning(push)
     32 #    pragma warning(disable : 4200)
     33 #endif
     34    int data[0]; /* numFds + numInts ints */
     35 #if defined(__clang__)
     36 #    pragma clang diagnostic pop
     37 #elif defined(_MSC_VER)
     38 #    pragma warning(pop)
     39 #endif
     40 } native_handle_t;
     41 
     42 // Taken from nativebase/nativebase.h
     43 // https://android.googlesource.com/platform/frameworks/native/+/master/libs/nativebase/include/nativebase/nativebase.h
     44 typedef const native_handle_t *buffer_handle_t;
     45 
     46 typedef struct android_native_base_t
     47 {
     48    /* a magic value defined by the actual EGL native type */
     49    int magic;
     50    /* the sizeof() of the actual EGL native type */
     51    int version;
     52    void *reserved[4];
     53    /* reference-counting interface */
     54    void (*incRef)(struct android_native_base_t *base);
     55    void (*decRef)(struct android_native_base_t *base);
     56 } android_native_base_t;
     57 
     58 typedef struct ANativeWindowBuffer
     59 {
     60    struct android_native_base_t common;
     61    int width;
     62    int height;
     63    int stride;
     64    int format;
     65    int usage_deprecated;
     66    uintptr_t layerCount;
     67    void *reserved[1];
     68    const native_handle_t *handle;
     69    uint64_t usage;
     70    // we needed extra space for storing the 64-bits usage flags
     71    // the number of slots to use from reserved_proc depends on the
     72    // architecture.
     73    void *reserved_proc[8 - (sizeof(uint64_t) / sizeof(void *))];
     74 } ANativeWindowBuffer_t;
     75 
     76 // Taken from android/hardware_buffer.h
     77 // https://android.googlesource.com/platform/frameworks/native/+/master/libs/nativewindow/include/android/hardware_buffer.h
     78 
     79 // AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM,
     80 // AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM formats were deprecated and re-added explicitly.
     81 
     82 // clang-format off
     83 /**
     84 * Buffer pixel formats.
     85 */
     86 enum {
     87 
     88 #ifndef ANGLE_AHARDWARE_BUFFER_SUPPORT
     89    /**
     90     * Corresponding formats:
     91     *   Vulkan: VK_FORMAT_R8G8B8A8_UNORM
     92     *   OpenGL ES: GL_RGBA8
     93     */
     94    AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM           = 1,
     95 
     96    /**
     97     * 32 bits per pixel, 8 bits per channel format where alpha values are
     98     * ignored (always opaque).
     99     * Corresponding formats:
    100     *   Vulkan: VK_FORMAT_R8G8B8A8_UNORM
    101     *   OpenGL ES: GL_RGB8
    102     */
    103    AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM           = 2,
    104 
    105    /**
    106     * Corresponding formats:
    107     *   Vulkan: VK_FORMAT_R8G8B8_UNORM
    108     *   OpenGL ES: GL_RGB8
    109     */
    110    AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM             = 3,
    111 
    112    /**
    113     * Corresponding formats:
    114     *   Vulkan: VK_FORMAT_R5G6B5_UNORM_PACK16
    115     *   OpenGL ES: GL_RGB565
    116     */
    117    AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM             = 4,
    118 #endif  // ANGLE_AHARDWARE_BUFFER_SUPPORT
    119 
    120    AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM           = 5,
    121    AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM           = 6,
    122    AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM           = 7,
    123 
    124 #ifndef ANGLE_AHARDWARE_BUFFER_SUPPORT
    125    /**
    126     * Corresponding formats:
    127     *   Vulkan: VK_FORMAT_R16G16B16A16_SFLOAT
    128     *   OpenGL ES: GL_RGBA16F
    129     */
    130    AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT       = 0x16,
    131 
    132    /**
    133     * Corresponding formats:
    134     *   Vulkan: VK_FORMAT_A2B10G10R10_UNORM_PACK32
    135     *   OpenGL ES: GL_RGB10_A2
    136     */
    137    AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM        = 0x2b,
    138 
    139    /**
    140     * An opaque binary blob format that must have height 1, with width equal to
    141     * the buffer size in bytes.
    142     */
    143    AHARDWAREBUFFER_FORMAT_BLOB                     = 0x21,
    144 
    145    /**
    146     * Corresponding formats:
    147     *   Vulkan: VK_FORMAT_D16_UNORM
    148     *   OpenGL ES: GL_DEPTH_COMPONENT16
    149     */
    150    AHARDWAREBUFFER_FORMAT_D16_UNORM                = 0x30,
    151 
    152    /**
    153     * Corresponding formats:
    154     *   Vulkan: VK_FORMAT_X8_D24_UNORM_PACK32
    155     *   OpenGL ES: GL_DEPTH_COMPONENT24
    156     */
    157    AHARDWAREBUFFER_FORMAT_D24_UNORM                = 0x31,
    158 
    159    /**
    160     * Corresponding formats:
    161     *   Vulkan: VK_FORMAT_D24_UNORM_S8_UINT
    162     *   OpenGL ES: GL_DEPTH24_STENCIL8
    163     */
    164    AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT        = 0x32,
    165 
    166    /**
    167     * Corresponding formats:
    168     *   Vulkan: VK_FORMAT_D32_SFLOAT
    169     *   OpenGL ES: GL_DEPTH_COMPONENT32F
    170     */
    171    AHARDWAREBUFFER_FORMAT_D32_FLOAT                = 0x33,
    172 
    173    /**
    174     * Corresponding formats:
    175     *   Vulkan: VK_FORMAT_D32_SFLOAT_S8_UINT
    176     *   OpenGL ES: GL_DEPTH32F_STENCIL8
    177     */
    178    AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT        = 0x34,
    179 
    180    /**
    181     * Corresponding formats:
    182     *   Vulkan: VK_FORMAT_S8_UINT
    183     *   OpenGL ES: GL_STENCIL_INDEX8
    184     */
    185    AHARDWAREBUFFER_FORMAT_S8_UINT                  = 0x35,
    186 
    187    /**
    188     * YUV 420 888 format.
    189     * Must have an even width and height. Can be accessed in OpenGL
    190     * shaders through an external sampler. Does not support mip-maps
    191     * cube-maps or multi-layered textures.
    192     */
    193    AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420             = 0x23,
    194 
    195 #endif  // ANGLE_AHARDWARE_BUFFER_SUPPORT
    196 
    197    AHARDWAREBUFFER_FORMAT_YV12                     = 0x32315659,
    198    AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED   = 0x22,
    199 };
    200 // clang-format on
    201 
    202 namespace
    203 {
    204 
    205 // In the Android system:
    206 // - AHardwareBuffer is essentially a typedef of GraphicBuffer. Conversion functions simply
    207 // reinterpret_cast.
    208 // - GraphicBuffer inherits from two base classes, ANativeWindowBuffer and RefBase.
    209 //
    210 // GraphicBuffer implements a getter for ANativeWindowBuffer (getNativeBuffer) by static_casting
    211 // itself to its base class ANativeWindowBuffer. The offset of the ANativeWindowBuffer pointer
    212 // from the GraphicBuffer pointer is 16 bytes. This is likely due to two pointers: The vtable of
    213 // GraphicBuffer and the one pointer member of the RefBase class.
    214 //
    215 // This is not future proof at all. We need to look into getting utilities added to Android to
    216 // perform this cast for us.
    217 constexpr int kAHardwareBufferToANativeWindowBufferOffset = static_cast<int>(sizeof(void *)) * 2;
    218 
    219 template <typename T1, typename T2>
    220 T1 *OffsetPointer(T2 *ptr, int bytes)
    221 {
    222    return reinterpret_cast<T1 *>(reinterpret_cast<intptr_t>(ptr) + bytes);
    223 }
    224 
    225 GLenum GetPixelFormatInfo(int pixelFormat, bool *isYUV)
    226 {
    227    *isYUV = false;
    228    switch (pixelFormat)
    229    {
    230        case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
    231            return GL_RGBA8;
    232        case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
    233            return GL_RGB8;
    234        case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
    235            return GL_RGB8;
    236        case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
    237            return GL_RGB565;
    238        case AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM:
    239            return GL_BGRA8_EXT;
    240        case AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM:
    241            return GL_RGB5_A1;
    242        case AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM:
    243            return GL_RGBA4;
    244        case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
    245            return GL_RGBA16F;
    246        case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
    247            return GL_RGB10_A2;
    248        case AHARDWAREBUFFER_FORMAT_BLOB:
    249            return GL_NONE;
    250        case AHARDWAREBUFFER_FORMAT_D16_UNORM:
    251            return GL_DEPTH_COMPONENT16;
    252        case AHARDWAREBUFFER_FORMAT_D24_UNORM:
    253            return GL_DEPTH_COMPONENT24;
    254        case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
    255            return GL_DEPTH24_STENCIL8;
    256        case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
    257            return GL_DEPTH_COMPONENT32F;
    258        case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
    259            return GL_DEPTH32F_STENCIL8;
    260        case AHARDWAREBUFFER_FORMAT_S8_UINT:
    261            return GL_STENCIL_INDEX8;
    262        case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
    263        case AHARDWAREBUFFER_FORMAT_YV12:
    264        case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
    265            *isYUV = true;
    266            return GL_RGB8;
    267        default:
    268            // Treat unknown formats as RGB. They are vendor-specific YUV formats that would sample
    269            // as RGB.
    270            *isYUV = true;
    271            return GL_RGB8;
    272    }
    273 }
    274 
    275 }  // anonymous namespace
    276 
    277 namespace angle
    278 {
    279 
    280 namespace android
    281 {
    282 
    283 ANativeWindowBuffer *ClientBufferToANativeWindowBuffer(EGLClientBuffer clientBuffer)
    284 {
    285    return reinterpret_cast<ANativeWindowBuffer *>(clientBuffer);
    286 }
    287 
    288 uint64_t GetAHBUsage(int eglNativeBufferUsage)
    289 {
    290    uint64_t ahbUsage = 0;
    291 #if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
    292    if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID)
    293    {
    294        ahbUsage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
    295    }
    296    if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID)
    297    {
    298        ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
    299    }
    300    if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)
    301    {
    302        ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
    303    }
    304 #endif  // ANGLE_AHARDWARE_BUFFER_SUPPORT
    305    return ahbUsage;
    306 }
    307 
    308 EGLClientBuffer CreateEGLClientBufferFromAHardwareBuffer(int width,
    309                                                         int height,
    310                                                         int depth,
    311                                                         int androidFormat,
    312                                                         int usage)
    313 {
    314 #if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
    315 
    316    // The height and width are number of pixels of size format
    317    AHardwareBuffer_Desc aHardwareBufferDescription = {};
    318    aHardwareBufferDescription.width                = static_cast<uint32_t>(width);
    319    aHardwareBufferDescription.height               = static_cast<uint32_t>(height);
    320    aHardwareBufferDescription.layers               = static_cast<uint32_t>(depth);
    321    aHardwareBufferDescription.format               = androidFormat;
    322    aHardwareBufferDescription.usage                = GetAHBUsage(usage);
    323 
    324    // Allocate memory from Android Hardware Buffer
    325    AHardwareBuffer *aHardwareBuffer = nullptr;
    326    int res = AHardwareBuffer_allocate(&aHardwareBufferDescription, &aHardwareBuffer);
    327    if (res != 0)
    328    {
    329        return nullptr;
    330    }
    331 
    332    return AHardwareBufferToClientBuffer(aHardwareBuffer);
    333 #else
    334    return nullptr;
    335 #endif  // ANGLE_AHARDWARE_BUFFER_SUPPORT
    336 }
    337 
    338 void GetANativeWindowBufferProperties(const ANativeWindowBuffer *buffer,
    339                                      int *width,
    340                                      int *height,
    341                                      int *depth,
    342                                      int *pixelFormat,
    343                                      uint64_t *usage)
    344 {
    345    *width       = buffer->width;
    346    *height      = buffer->height;
    347    *depth       = static_cast<int>(buffer->layerCount);
    348    *height      = buffer->height;
    349    *pixelFormat = buffer->format;
    350    *usage       = buffer->usage;
    351 }
    352 
    353 GLenum NativePixelFormatToGLInternalFormat(int pixelFormat)
    354 {
    355    bool isYuv = false;
    356    return GetPixelFormatInfo(pixelFormat, &isYuv);
    357 }
    358 
    359 int GLInternalFormatToNativePixelFormat(GLenum internalFormat)
    360 {
    361    switch (internalFormat)
    362    {
    363        case GL_RGBA8:
    364            return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
    365        case GL_RGB8:
    366            return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
    367        case GL_RGB565:
    368            return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
    369        case GL_BGRA8_EXT:
    370            return AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM;
    371        case GL_RGB5_A1:
    372            return AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM;
    373        case GL_RGBA4:
    374            return AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM;
    375        case GL_RGBA16F:
    376            return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
    377        case GL_RGB10_A2:
    378            return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
    379        case GL_NONE:
    380            return AHARDWAREBUFFER_FORMAT_BLOB;
    381        case GL_DEPTH_COMPONENT16:
    382            return AHARDWAREBUFFER_FORMAT_D16_UNORM;
    383        case GL_DEPTH_COMPONENT24:
    384            return AHARDWAREBUFFER_FORMAT_D24_UNORM;
    385        case GL_DEPTH24_STENCIL8:
    386            return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
    387        case GL_DEPTH_COMPONENT32F:
    388            return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
    389        case GL_DEPTH32F_STENCIL8:
    390            return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
    391        case GL_STENCIL_INDEX8:
    392            return AHARDWAREBUFFER_FORMAT_S8_UINT;
    393        default:
    394            WARN() << "Unknown internalFormat: " << internalFormat << ". Treating as 0";
    395            return 0;
    396    }
    397 }
    398 
    399 bool NativePixelFormatIsYUV(int pixelFormat)
    400 {
    401    bool isYuv = false;
    402    GetPixelFormatInfo(pixelFormat, &isYuv);
    403    return isYuv;
    404 }
    405 
    406 AHardwareBuffer *ANativeWindowBufferToAHardwareBuffer(ANativeWindowBuffer *windowBuffer)
    407 {
    408    return OffsetPointer<AHardwareBuffer>(windowBuffer,
    409                                          -kAHardwareBufferToANativeWindowBufferOffset);
    410 }
    411 
    412 EGLClientBuffer AHardwareBufferToClientBuffer(const AHardwareBuffer *hardwareBuffer)
    413 {
    414    return OffsetPointer<EGLClientBuffer>(hardwareBuffer,
    415                                          kAHardwareBufferToANativeWindowBufferOffset);
    416 }
    417 
    418 AHardwareBuffer *ClientBufferToAHardwareBuffer(EGLClientBuffer clientBuffer)
    419 {
    420    return OffsetPointer<AHardwareBuffer>(clientBuffer,
    421                                          -kAHardwareBufferToANativeWindowBufferOffset);
    422 }
    423 }  // namespace android
    424 }  // namespace angle