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