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