• 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 
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