Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/common/android_util.cpp
1693 views
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
// clang-format on
198
199
namespace
200
{
201
202
// In the Android system:
203
// - AHardwareBuffer is essentially a typedef of GraphicBuffer. Conversion functions simply
204
// reinterpret_cast.
205
// - GraphicBuffer inherits from two base classes, ANativeWindowBuffer and RefBase.
206
//
207
// GraphicBuffer implements a getter for ANativeWindowBuffer (getNativeBuffer) by static_casting
208
// itself to its base class ANativeWindowBuffer. The offset of the ANativeWindowBuffer pointer
209
// from the GraphicBuffer pointer is 16 bytes. This is likely due to two pointers: The vtable of
210
// GraphicBuffer and the one pointer member of the RefBase class.
211
//
212
// This is not future proof at all. We need to look into getting utilities added to Android to
213
// perform this cast for us.
214
constexpr int kAHardwareBufferToANativeWindowBufferOffset = static_cast<int>(sizeof(void *)) * 2;
215
216
template <typename T1, typename T2>
217
T1 *offsetPointer(T2 *ptr, int bytes)
218
{
219
return reinterpret_cast<T1 *>(reinterpret_cast<intptr_t>(ptr) + bytes);
220
}
221
222
GLenum getPixelFormatInfo(int pixelFormat, bool *isYUV)
223
{
224
*isYUV = false;
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
*isYUV = true;
261
return GL_RGB8;
262
default:
263
// Treat unknown formats as RGB. They are vendor-specific YUV formats that would sample
264
// as RGB.
265
WARN() << "Unknown pixelFormat: " << pixelFormat << ". Treating as RGB8";
266
*isYUV = true;
267
return GL_RGB8;
268
}
269
}
270
271
} // anonymous namespace
272
273
namespace angle
274
{
275
276
namespace android
277
{
278
279
ANativeWindowBuffer *ClientBufferToANativeWindowBuffer(EGLClientBuffer clientBuffer)
280
{
281
return reinterpret_cast<ANativeWindowBuffer *>(clientBuffer);
282
}
283
284
uint64_t GetAHBUsage(int eglNativeBufferUsage)
285
{
286
uint64_t ahbUsage = 0;
287
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
288
if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID)
289
{
290
ahbUsage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
291
}
292
if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID)
293
{
294
ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
295
}
296
if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)
297
{
298
ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
299
}
300
#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT
301
return ahbUsage;
302
}
303
304
EGLClientBuffer CreateEGLClientBufferFromAHardwareBuffer(int width,
305
int height,
306
int depth,
307
int androidFormat,
308
int usage)
309
{
310
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
311
312
// The height and width are number of pixels of size format
313
AHardwareBuffer_Desc aHardwareBufferDescription = {};
314
aHardwareBufferDescription.width = static_cast<uint32_t>(width);
315
aHardwareBufferDescription.height = static_cast<uint32_t>(height);
316
aHardwareBufferDescription.layers = static_cast<uint32_t>(depth);
317
aHardwareBufferDescription.format = androidFormat;
318
aHardwareBufferDescription.usage = GetAHBUsage(usage);
319
320
// Allocate memory from Android Hardware Buffer
321
AHardwareBuffer *aHardwareBuffer = nullptr;
322
int res = AHardwareBuffer_allocate(&aHardwareBufferDescription, &aHardwareBuffer);
323
if (res != 0)
324
{
325
return nullptr;
326
}
327
328
return AHardwareBufferToClientBuffer(aHardwareBuffer);
329
#else
330
return nullptr;
331
#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT
332
}
333
334
void GetANativeWindowBufferProperties(const ANativeWindowBuffer *buffer,
335
int *width,
336
int *height,
337
int *depth,
338
int *pixelFormat,
339
uint64_t *usage)
340
{
341
*width = buffer->width;
342
*height = buffer->height;
343
*depth = static_cast<int>(buffer->layerCount);
344
*height = buffer->height;
345
*pixelFormat = buffer->format;
346
*usage = buffer->usage;
347
}
348
349
GLenum NativePixelFormatToGLInternalFormat(int pixelFormat)
350
{
351
bool isYuv = false;
352
return getPixelFormatInfo(pixelFormat, &isYuv);
353
}
354
355
int GLInternalFormatToNativePixelFormat(GLenum internalFormat)
356
{
357
switch (internalFormat)
358
{
359
case GL_RGBA8:
360
return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
361
case GL_RGB8:
362
return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
363
case GL_RGB565:
364
return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
365
case GL_BGRA8_EXT:
366
return AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM;
367
case GL_RGB5_A1:
368
return AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM;
369
case GL_RGBA4:
370
return AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM;
371
case GL_RGBA16F:
372
return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
373
case GL_RGB10_A2:
374
return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
375
case GL_NONE:
376
return AHARDWAREBUFFER_FORMAT_BLOB;
377
case GL_DEPTH_COMPONENT16:
378
return AHARDWAREBUFFER_FORMAT_D16_UNORM;
379
case GL_DEPTH_COMPONENT24:
380
return AHARDWAREBUFFER_FORMAT_D24_UNORM;
381
case GL_DEPTH24_STENCIL8:
382
return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
383
case GL_DEPTH_COMPONENT32F:
384
return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
385
case GL_DEPTH32F_STENCIL8:
386
return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
387
case GL_STENCIL_INDEX8:
388
return AHARDWAREBUFFER_FORMAT_S8_UINT;
389
default:
390
WARN() << "Unknown internalFormat: " << internalFormat << ". Treating as 0";
391
return 0;
392
}
393
}
394
395
bool NativePixelFormatIsYUV(int pixelFormat)
396
{
397
bool isYuv = false;
398
getPixelFormatInfo(pixelFormat, &isYuv);
399
return isYuv;
400
}
401
402
AHardwareBuffer *ANativeWindowBufferToAHardwareBuffer(ANativeWindowBuffer *windowBuffer)
403
{
404
return offsetPointer<AHardwareBuffer>(windowBuffer,
405
-kAHardwareBufferToANativeWindowBufferOffset);
406
}
407
408
EGLClientBuffer AHardwareBufferToClientBuffer(const AHardwareBuffer *hardwareBuffer)
409
{
410
return offsetPointer<EGLClientBuffer>(hardwareBuffer,
411
kAHardwareBufferToANativeWindowBufferOffset);
412
}
413
414
AHardwareBuffer *ClientBufferToAHardwareBuffer(EGLClientBuffer clientBuffer)
415
{
416
return offsetPointer<AHardwareBuffer>(clientBuffer,
417
-kAHardwareBufferToANativeWindowBufferOffset);
418
}
419
} // namespace android
420
} // namespace angle
421
422