• 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 #include <cstdint>
13 
14 // Taken from cutils/native_handle.h:
15 // https://android.googlesource.com/platform/system/core/+/master/libcutils/include/cutils/native_handle.h
16 typedef struct native_handle
17 {
18     int version; /* sizeof(native_handle_t) */
19     int numFds;  /* number of file-descriptors at &data[0] */
20     int numInts; /* number of ints at &data[numFds] */
21     int data[0]; /* numFds + numInts ints */
22 } native_handle_t;
23 
24 // Taken from nativebase/nativebase.h
25 // https://android.googlesource.com/platform/frameworks/native/+/master/libs/nativebase/include/nativebase/nativebase.h
26 typedef const native_handle_t *buffer_handle_t;
27 
28 typedef struct android_native_base_t
29 {
30     /* a magic value defined by the actual EGL native type */
31     int magic;
32     /* the sizeof() of the actual EGL native type */
33     int version;
34     void *reserved[4];
35     /* reference-counting interface */
36     void (*incRef)(struct android_native_base_t *base);
37     void (*decRef)(struct android_native_base_t *base);
38 } android_native_base_t;
39 
40 typedef struct ANativeWindowBuffer
41 {
42     struct android_native_base_t common;
43     int width;
44     int height;
45     int stride;
46     int format;
47     int usage_deprecated;
48     uintptr_t layerCount;
49     void *reserved[1];
50     const native_handle_t *handle;
51     uint64_t usage;
52     // we needed extra space for storing the 64-bits usage flags
53     // the number of slots to use from reserved_proc depends on the
54     // architecture.
55     void *reserved_proc[8 - (sizeof(uint64_t) / sizeof(void *))];
56 } ANativeWindowBuffer_t;
57 
58 // Taken from android/hardware_buffer.h
59 // https://android.googlesource.com/platform/frameworks/native/+/master/libs/nativewindow/include/android/hardware_buffer.h
60 
61 // AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM,
62 // AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM formats were deprecated and re-added explicitly.
63 
64 // clang-format off
65 /**
66  * Buffer pixel formats.
67  */
68 enum {
69     /**
70      * Corresponding formats:
71      *   Vulkan: VK_FORMAT_R8G8B8A8_UNORM
72      *   OpenGL ES: GL_RGBA8
73      */
74     AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM           = 1,
75 
76     /**
77      * 32 bits per pixel, 8 bits per channel format where alpha values are
78      * ignored (always opaque).
79      * Corresponding formats:
80      *   Vulkan: VK_FORMAT_R8G8B8A8_UNORM
81      *   OpenGL ES: GL_RGB8
82      */
83     AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM           = 2,
84 
85     /**
86      * Corresponding formats:
87      *   Vulkan: VK_FORMAT_R8G8B8_UNORM
88      *   OpenGL ES: GL_RGB8
89      */
90     AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM             = 3,
91 
92     /**
93      * Corresponding formats:
94      *   Vulkan: VK_FORMAT_R5G6B5_UNORM_PACK16
95      *   OpenGL ES: GL_RGB565
96      */
97     AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM             = 4,
98 
99     AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM           = 5,
100     AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM           = 6,
101     AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM           = 7,
102     /**
103      * Corresponding formats:
104      *   Vulkan: VK_FORMAT_R16G16B16A16_SFLOAT
105      *   OpenGL ES: GL_RGBA16F
106      */
107     AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT       = 0x16,
108 
109     /**
110      * Corresponding formats:
111      *   Vulkan: VK_FORMAT_A2B10G10R10_UNORM_PACK32
112      *   OpenGL ES: GL_RGB10_A2
113      */
114     AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM        = 0x2b,
115 
116     /**
117      * An opaque binary blob format that must have height 1, with width equal to
118      * the buffer size in bytes.
119      */
120     AHARDWAREBUFFER_FORMAT_BLOB                     = 0x21,
121 
122     /**
123      * Corresponding formats:
124      *   Vulkan: VK_FORMAT_D16_UNORM
125      *   OpenGL ES: GL_DEPTH_COMPONENT16
126      */
127     AHARDWAREBUFFER_FORMAT_D16_UNORM                = 0x30,
128 
129     /**
130      * Corresponding formats:
131      *   Vulkan: VK_FORMAT_X8_D24_UNORM_PACK32
132      *   OpenGL ES: GL_DEPTH_COMPONENT24
133      */
134     AHARDWAREBUFFER_FORMAT_D24_UNORM                = 0x31,
135 
136     /**
137      * Corresponding formats:
138      *   Vulkan: VK_FORMAT_D24_UNORM_S8_UINT
139      *   OpenGL ES: GL_DEPTH24_STENCIL8
140      */
141     AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT        = 0x32,
142 
143     /**
144      * Corresponding formats:
145      *   Vulkan: VK_FORMAT_D32_SFLOAT
146      *   OpenGL ES: GL_DEPTH_COMPONENT32F
147      */
148     AHARDWAREBUFFER_FORMAT_D32_FLOAT                = 0x33,
149 
150     /**
151      * Corresponding formats:
152      *   Vulkan: VK_FORMAT_D32_SFLOAT_S8_UINT
153      *   OpenGL ES: GL_DEPTH32F_STENCIL8
154      */
155     AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT        = 0x34,
156 
157     /**
158      * Corresponding formats:
159      *   Vulkan: VK_FORMAT_S8_UINT
160      *   OpenGL ES: GL_STENCIL_INDEX8
161      */
162     AHARDWAREBUFFER_FORMAT_S8_UINT                  = 0x35,
163 
164     /**
165      * YUV 420 888 format.
166      * Must have an even width and height. Can be accessed in OpenGL
167      * shaders through an external sampler. Does not support mip-maps
168      * cube-maps or multi-layered textures.
169      */
170     AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420             = 0x23,
171 };
172 // clang-format on
173 
174 namespace
175 {
176 
177 // In the Android system:
178 // - AHardwareBuffer is essentially a typedef of GraphicBuffer. Conversion functions simply
179 // reinterpret_cast.
180 // - GraphicBuffer inherits from two base classes, ANativeWindowBuffer and RefBase.
181 //
182 // GraphicBuffer implements a getter for ANativeWindowBuffer (getNativeBuffer) by static_casting
183 // itself to its base class ANativeWindowBuffer. The offset of the ANativeWindowBuffer pointer
184 // from the GraphicBuffer pointer is 16 bytes. This is likely due to two pointers: The vtable of
185 // GraphicBuffer and the one pointer member of the RefBase class.
186 //
187 // This is not future proof at all. We need to look into getting utilities added to Android to
188 // perform this cast for us.
189 constexpr int kAHardwareBufferToANativeWindowBufferOffset = static_cast<int>(sizeof(void *)) * 2;
190 
191 template <typename T1, typename T2>
offsetPointer(T2 * ptr,int bytes)192 T1 *offsetPointer(T2 *ptr, int bytes)
193 {
194     return reinterpret_cast<T1 *>(reinterpret_cast<intptr_t>(ptr) + bytes);
195 }
196 
197 }  // anonymous namespace
198 
199 namespace angle
200 {
201 
202 namespace android
203 {
204 
ClientBufferToANativeWindowBuffer(EGLClientBuffer clientBuffer)205 ANativeWindowBuffer *ClientBufferToANativeWindowBuffer(EGLClientBuffer clientBuffer)
206 {
207     return reinterpret_cast<ANativeWindowBuffer *>(clientBuffer);
208 }
209 
GetANativeWindowBufferProperties(const ANativeWindowBuffer * buffer,int * width,int * height,int * depth,int * pixelFormat)210 void GetANativeWindowBufferProperties(const ANativeWindowBuffer *buffer,
211                                       int *width,
212                                       int *height,
213                                       int *depth,
214                                       int *pixelFormat)
215 {
216     *width       = buffer->width;
217     *height      = buffer->height;
218     *depth       = static_cast<int>(buffer->layerCount);
219     *height      = buffer->height;
220     *pixelFormat = buffer->format;
221 }
222 
NativePixelFormatToGLInternalFormat(int pixelFormat)223 GLenum NativePixelFormatToGLInternalFormat(int pixelFormat)
224 {
225     switch (pixelFormat)
226     {
227         case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
228             return GL_RGBA8;
229         case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
230             return GL_RGB8;
231         case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
232             return GL_RGB8;
233         case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
234             return GL_RGB565;
235         case AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM:
236             return GL_BGRA8_EXT;
237         case AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM:
238             return GL_RGB5_A1;
239         case AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM:
240             return GL_RGBA4;
241         case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
242             return GL_RGBA16F;
243         case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
244             return GL_RGB10_A2;
245         case AHARDWAREBUFFER_FORMAT_BLOB:
246             return GL_NONE;
247         case AHARDWAREBUFFER_FORMAT_D16_UNORM:
248             return GL_DEPTH_COMPONENT16;
249         case AHARDWAREBUFFER_FORMAT_D24_UNORM:
250             return GL_DEPTH_COMPONENT24;
251         case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
252             return GL_DEPTH24_STENCIL8;
253         case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
254             return GL_DEPTH_COMPONENT32F;
255         case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
256             return GL_DEPTH32F_STENCIL8;
257         case AHARDWAREBUFFER_FORMAT_S8_UINT:
258             return GL_STENCIL_INDEX8;
259         case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
260             return GL_RGB8;
261         default:
262             // Treat unknown formats as RGB. They are vendor-specific YUV formats that would sample
263             // as RGB.
264             WARN() << "Unknown pixelFormat: " << pixelFormat << ". Treating as RGB8";
265             return GL_RGB8;
266     }
267 }
268 
GLInternalFormatToNativePixelFormat(GLenum internalFormat)269 int GLInternalFormatToNativePixelFormat(GLenum internalFormat)
270 {
271     switch (internalFormat)
272     {
273         case GL_RGBA8:
274             return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
275         case GL_RGB8:
276             return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
277         case GL_RGB565:
278             return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
279         case GL_BGRA8_EXT:
280             return AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM;
281         case GL_RGB5_A1:
282             return AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM;
283         case GL_RGBA4:
284             return AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM;
285         case GL_RGBA16F:
286             return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
287         case GL_RGB10_A2:
288             return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
289         case GL_NONE:
290             return AHARDWAREBUFFER_FORMAT_BLOB;
291         case GL_DEPTH_COMPONENT16:
292             return AHARDWAREBUFFER_FORMAT_D16_UNORM;
293         case GL_DEPTH_COMPONENT24:
294             return AHARDWAREBUFFER_FORMAT_D24_UNORM;
295         case GL_DEPTH24_STENCIL8:
296             return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
297         case GL_DEPTH_COMPONENT32F:
298             return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
299         case GL_DEPTH32F_STENCIL8:
300             return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
301         case GL_STENCIL_INDEX8:
302             return AHARDWAREBUFFER_FORMAT_S8_UINT;
303         default:
304             WARN() << "Unknown internalFormat: " << internalFormat << ". Treating as 0";
305             return 0;
306     }
307 }
308 
ANativeWindowBufferToAHardwareBuffer(ANativeWindowBuffer * windowBuffer)309 AHardwareBuffer *ANativeWindowBufferToAHardwareBuffer(ANativeWindowBuffer *windowBuffer)
310 {
311     return offsetPointer<AHardwareBuffer>(windowBuffer,
312                                           -kAHardwareBufferToANativeWindowBufferOffset);
313 }
314 
AHardwareBufferToClientBuffer(const AHardwareBuffer * hardwareBuffer)315 EGLClientBuffer AHardwareBufferToClientBuffer(const AHardwareBuffer *hardwareBuffer)
316 {
317     return offsetPointer<EGLClientBuffer>(hardwareBuffer,
318                                           kAHardwareBufferToANativeWindowBufferOffset);
319 }
320 
321 }  // namespace android
322 }  // namespace angle
323