• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26
13 #    define ANGLE_AHARDWARE_BUFFER_SUPPORT
14 // NDK header file for access to Android Hardware Buffers
15 #    include <android/hardware_buffer.h>
16 #endif
17 
18 // Taken from cutils/native_handle.h:
19 // https://android.googlesource.com/platform/system/core/+/master/libcutils/include/cutils/native_handle.h
20 typedef struct native_handle
21 {
22     int version; /* sizeof(native_handle_t) */
23     int numFds;  /* number of file-descriptors at &data[0] */
24     int numInts; /* number of ints at &data[numFds] */
25 #if defined(__clang__)
26 #    pragma clang diagnostic push
27 #    pragma clang diagnostic ignored "-Wzero-length-array"
28 #elif defined(_MSC_VER)
29 #    pragma warning(push)
30 #    pragma warning(disable : 4200)
31 #endif
32     int data[0]; /* numFds + numInts ints */
33 #if defined(__clang__)
34 #    pragma clang diagnostic pop
35 #elif defined(_MSC_VER)
36 #    pragma warning(pop)
37 #endif
38 } native_handle_t;
39 
40 // Taken from nativebase/nativebase.h
41 // https://android.googlesource.com/platform/frameworks/native/+/master/libs/nativebase/include/nativebase/nativebase.h
42 typedef const native_handle_t *buffer_handle_t;
43 
44 typedef struct android_native_base_t
45 {
46     /* a magic value defined by the actual EGL native type */
47     int magic;
48     /* the sizeof() of the actual EGL native type */
49     int version;
50     void *reserved[4];
51     /* reference-counting interface */
52     void (*incRef)(struct android_native_base_t *base);
53     void (*decRef)(struct android_native_base_t *base);
54 } android_native_base_t;
55 
56 typedef struct ANativeWindowBuffer
57 {
58     struct android_native_base_t common;
59     int width;
60     int height;
61     int stride;
62     int format;
63     int usage_deprecated;
64     uintptr_t layerCount;
65     void *reserved[1];
66     const native_handle_t *handle;
67     uint64_t usage;
68     // we needed extra space for storing the 64-bits usage flags
69     // the number of slots to use from reserved_proc depends on the
70     // architecture.
71     void *reserved_proc[8 - (sizeof(uint64_t) / sizeof(void *))];
72 } ANativeWindowBuffer_t;
73 
74 namespace angle
75 {
76 
77 namespace android
78 {
79 
80 namespace
81 {
82 
83 // In the Android system:
84 // - AHardwareBuffer is essentially a typedef of GraphicBuffer. Conversion functions simply
85 // reinterpret_cast.
86 // - GraphicBuffer inherits from two base classes, ANativeWindowBuffer and RefBase.
87 //
88 // GraphicBuffer implements a getter for ANativeWindowBuffer (getNativeBuffer) by static_casting
89 // itself to its base class ANativeWindowBuffer. The offset of the ANativeWindowBuffer pointer
90 // from the GraphicBuffer pointer is 16 bytes. This is likely due to two pointers: The vtable of
91 // GraphicBuffer and the one pointer member of the RefBase class.
92 //
93 // This is not future proof at all. We need to look into getting utilities added to Android to
94 // perform this cast for us.
95 constexpr int kAHardwareBufferToANativeWindowBufferOffset = static_cast<int>(sizeof(void *)) * 2;
96 
97 template <typename T1, typename T2>
OffsetPointer(T2 * ptr,int bytes)98 T1 *OffsetPointer(T2 *ptr, int bytes)
99 {
100     return reinterpret_cast<T1 *>(reinterpret_cast<intptr_t>(ptr) + bytes);
101 }
102 
GetPixelFormatInfo(int pixelFormat,bool * isYUV)103 GLenum GetPixelFormatInfo(int pixelFormat, bool *isYUV)
104 {
105     *isYUV = false;
106     switch (pixelFormat)
107     {
108         case ANGLE_AHB_FORMAT_R8G8B8A8_UNORM:
109             return GL_RGBA8;
110         case ANGLE_AHB_FORMAT_R8G8B8X8_UNORM:
111             return GL_RGB8;
112         case ANGLE_AHB_FORMAT_R8G8B8_UNORM:
113             return GL_RGB8;
114         case ANGLE_AHB_FORMAT_R5G6B5_UNORM:
115             return GL_RGB565;
116         case ANGLE_AHB_FORMAT_B8G8R8A8_UNORM:
117             return GL_BGRA8_EXT;
118         case ANGLE_AHB_FORMAT_B5G5R5A1_UNORM:
119             return GL_RGB5_A1;
120         case ANGLE_AHB_FORMAT_B4G4R4A4_UNORM:
121             return GL_RGBA4;
122         case ANGLE_AHB_FORMAT_R16G16B16A16_FLOAT:
123             return GL_RGBA16F;
124         case ANGLE_AHB_FORMAT_R10G10B10A2_UNORM:
125             return GL_RGB10_A2;
126         case ANGLE_AHB_FORMAT_BLOB:
127             return GL_NONE;
128         case ANGLE_AHB_FORMAT_D16_UNORM:
129             return GL_DEPTH_COMPONENT16;
130         case ANGLE_AHB_FORMAT_D24_UNORM:
131             return GL_DEPTH_COMPONENT24;
132         case ANGLE_AHB_FORMAT_D24_UNORM_S8_UINT:
133             return GL_DEPTH24_STENCIL8;
134         case ANGLE_AHB_FORMAT_D32_FLOAT:
135             return GL_DEPTH_COMPONENT32F;
136         case ANGLE_AHB_FORMAT_D32_FLOAT_S8_UINT:
137             return GL_DEPTH32F_STENCIL8;
138         case ANGLE_AHB_FORMAT_S8_UINT:
139             return GL_STENCIL_INDEX8;
140         case ANGLE_AHB_FORMAT_R8_UNORM:
141             return GL_R8;
142         case ANGLE_AHB_FORMAT_Y8Cb8Cr8_420:
143         case ANGLE_AHB_FORMAT_YV12:
144         case ANGLE_AHB_FORMAT_IMPLEMENTATION_DEFINED:
145             *isYUV = true;
146             return GL_RGB8;
147         default:
148             // Treat unknown formats as RGB. They are vendor-specific YUV formats that would sample
149             // as RGB.
150             *isYUV = true;
151             return GL_RGB8;
152     }
153 }
154 
155 }  // anonymous namespace
156 
ClientBufferToANativeWindowBuffer(EGLClientBuffer clientBuffer)157 ANativeWindowBuffer *ClientBufferToANativeWindowBuffer(EGLClientBuffer clientBuffer)
158 {
159     return reinterpret_cast<ANativeWindowBuffer *>(clientBuffer);
160 }
161 
GetAHBUsage(int eglNativeBufferUsage)162 uint64_t GetAHBUsage(int eglNativeBufferUsage)
163 {
164     uint64_t ahbUsage = 0;
165 #if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
166     if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID)
167     {
168         ahbUsage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
169     }
170     if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID)
171     {
172         ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
173     }
174     if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)
175     {
176         ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
177     }
178 #endif  // ANGLE_AHARDWARE_BUFFER_SUPPORT
179     return ahbUsage;
180 }
181 
CreateEGLClientBufferFromAHardwareBuffer(int width,int height,int depth,int androidFormat,int usage)182 EGLClientBuffer CreateEGLClientBufferFromAHardwareBuffer(int width,
183                                                          int height,
184                                                          int depth,
185                                                          int androidFormat,
186                                                          int usage)
187 {
188 #if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
189 
190     // The height and width are number of pixels of size format
191     AHardwareBuffer_Desc aHardwareBufferDescription = {};
192     aHardwareBufferDescription.width                = static_cast<uint32_t>(width);
193     aHardwareBufferDescription.height               = static_cast<uint32_t>(height);
194     aHardwareBufferDescription.layers               = static_cast<uint32_t>(depth);
195     aHardwareBufferDescription.format               = androidFormat;
196     aHardwareBufferDescription.usage                = GetAHBUsage(usage);
197 
198     // Allocate memory from Android Hardware Buffer
199     AHardwareBuffer *aHardwareBuffer = nullptr;
200     int res = AHardwareBuffer_allocate(&aHardwareBufferDescription, &aHardwareBuffer);
201     if (res != 0)
202     {
203         return nullptr;
204     }
205 
206     return AHardwareBufferToClientBuffer(aHardwareBuffer);
207 #else
208     return nullptr;
209 #endif  // ANGLE_AHARDWARE_BUFFER_SUPPORT
210 }
211 
GetANativeWindowBufferProperties(const ANativeWindowBuffer * buffer,int * width,int * height,int * depth,int * pixelFormat,uint64_t * usage)212 void GetANativeWindowBufferProperties(const ANativeWindowBuffer *buffer,
213                                       int *width,
214                                       int *height,
215                                       int *depth,
216                                       int *pixelFormat,
217                                       uint64_t *usage)
218 {
219     *width       = buffer->width;
220     *height      = buffer->height;
221     *depth       = static_cast<int>(buffer->layerCount);
222     *height      = buffer->height;
223     *pixelFormat = buffer->format;
224     *usage       = buffer->usage;
225 }
226 
NativePixelFormatToGLInternalFormat(int pixelFormat)227 GLenum NativePixelFormatToGLInternalFormat(int pixelFormat)
228 {
229     bool isYuv = false;
230     return GetPixelFormatInfo(pixelFormat, &isYuv);
231 }
232 
GLInternalFormatToNativePixelFormat(GLenum internalFormat)233 int GLInternalFormatToNativePixelFormat(GLenum internalFormat)
234 {
235     switch (internalFormat)
236     {
237         case GL_R8:
238             return ANGLE_AHB_FORMAT_R8_UNORM;
239         case GL_RGBA8:
240             return ANGLE_AHB_FORMAT_R8G8B8A8_UNORM;
241         case GL_RGB8:
242             return ANGLE_AHB_FORMAT_R8G8B8X8_UNORM;
243         case GL_RGB565:
244             return ANGLE_AHB_FORMAT_R5G6B5_UNORM;
245         case GL_BGRA8_EXT:
246             return ANGLE_AHB_FORMAT_B8G8R8A8_UNORM;
247         case GL_RGB5_A1:
248             return ANGLE_AHB_FORMAT_B5G5R5A1_UNORM;
249         case GL_RGBA4:
250             return ANGLE_AHB_FORMAT_B4G4R4A4_UNORM;
251         case GL_RGBA16F:
252             return ANGLE_AHB_FORMAT_R16G16B16A16_FLOAT;
253         case GL_RGB10_A2:
254             return ANGLE_AHB_FORMAT_R10G10B10A2_UNORM;
255         case GL_NONE:
256             return ANGLE_AHB_FORMAT_BLOB;
257         case GL_DEPTH_COMPONENT16:
258             return ANGLE_AHB_FORMAT_D16_UNORM;
259         case GL_DEPTH_COMPONENT24:
260             return ANGLE_AHB_FORMAT_D24_UNORM;
261         case GL_DEPTH24_STENCIL8:
262             return ANGLE_AHB_FORMAT_D24_UNORM_S8_UINT;
263         case GL_DEPTH_COMPONENT32F:
264             return ANGLE_AHB_FORMAT_D32_FLOAT;
265         case GL_DEPTH32F_STENCIL8:
266             return ANGLE_AHB_FORMAT_D32_FLOAT_S8_UINT;
267         case GL_STENCIL_INDEX8:
268             return ANGLE_AHB_FORMAT_S8_UINT;
269         default:
270             WARN() << "Unknown internalFormat: " << internalFormat << ". Treating as 0";
271             return 0;
272     }
273 }
274 
NativePixelFormatIsYUV(int pixelFormat)275 bool NativePixelFormatIsYUV(int pixelFormat)
276 {
277     bool isYuv = false;
278     GetPixelFormatInfo(pixelFormat, &isYuv);
279     return isYuv;
280 }
281 
ANativeWindowBufferToAHardwareBuffer(ANativeWindowBuffer * windowBuffer)282 AHardwareBuffer *ANativeWindowBufferToAHardwareBuffer(ANativeWindowBuffer *windowBuffer)
283 {
284     return OffsetPointer<AHardwareBuffer>(windowBuffer,
285                                           -kAHardwareBufferToANativeWindowBufferOffset);
286 }
287 
AHardwareBufferToClientBuffer(const AHardwareBuffer * hardwareBuffer)288 EGLClientBuffer AHardwareBufferToClientBuffer(const AHardwareBuffer *hardwareBuffer)
289 {
290     return OffsetPointer<EGLClientBuffer>(hardwareBuffer,
291                                           kAHardwareBufferToANativeWindowBufferOffset);
292 }
293 
ClientBufferToAHardwareBuffer(EGLClientBuffer clientBuffer)294 AHardwareBuffer *ClientBufferToAHardwareBuffer(EGLClientBuffer clientBuffer)
295 {
296     return OffsetPointer<AHardwareBuffer>(clientBuffer,
297                                           -kAHardwareBufferToANativeWindowBufferOffset);
298 }
299 }  // namespace android
300 }  // namespace angle
301