Test behaviour of color write enable with colorWriteMask
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglAndroidUtil.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program EGL Module
3  * ---------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Android-specific operations.
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglAndroidUtil.hpp"
25
26 #include "deStringUtil.hpp"
27 #include "tcuTextureUtil.hpp"
28 #include "gluTextureUtil.hpp"
29 #include "glwEnums.hpp"
30 #include "eglwLibrary.hpp"
31 #include "eglwEnums.hpp"
32
33 namespace deqp
34 {
35 namespace egl
36 {
37 namespace Image
38 {
39
40 using std::string;
41 using de::MovePtr;
42 using tcu::PixelBufferAccess;
43 using tcu::TextureFormat;
44 using tcu::Texture2D;
45 using eglu::AttribMap;
46 using namespace glw;
47 using namespace eglw;
48
49 #if (DE_OS != DE_OS_ANDROID)
50
51 MovePtr<ImageSource> createAndroidNativeImageSource     (GLenum format)
52 {
53         return createUnsupportedImageSource("Not Android platform", format);
54 }
55
56 #else // DE_OS == DE_OS_ANDROID
57
58 #if defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
59 #       define BUILT_WITH_ANDROID_HARDWARE_BUFFER 1
60 #endif
61
62 #if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
63 #       define BUILT_WITH_ANDROID_P_HARDWARE_BUFFER 1
64 #endif
65
66 #if !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
67
68 MovePtr<ImageSource> createAndroidNativeImageSource     (GLenum format)
69 {
70         return createUnsupportedImageSource("AHB API not supported", format);
71 }
72
73 #else // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
74
75 namespace
76 {
77
78 #include <sys/system_properties.h>
79 #include <android/hardware_buffer.h>
80 #include "deDynamicLibrary.hpp"
81
82 deInt32 androidGetSdkVersion (void)
83 {
84         static deInt32 sdkVersion = -1;
85         if (sdkVersion < 0)
86         {
87                 char value[128] = {0};
88                 __system_property_get("ro.build.version.sdk", value);
89                 sdkVersion = static_cast<deInt32>(strtol(value, DE_NULL, 10));
90                 printf("SDK Version is %d\n", sdkVersion);
91         }
92         return sdkVersion;
93 }
94
95 typedef int             (*pfnAHardwareBuffer_allocate)(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer);
96 typedef void    (*pfnAHardwareBuffer_describe)(const AHardwareBuffer* buffer, AHardwareBuffer_Desc* outDesc);
97 typedef void    (*pfnAHardwareBuffer_acquire)(AHardwareBuffer* buffer);
98 typedef void    (*pfnAHardwareBuffer_release)(AHardwareBuffer* buffer);
99 typedef int             (*pfnAHardwareBuffer_isSupported)(const AHardwareBuffer_Desc* desc);
100
101 struct AhbFunctions
102 {
103         pfnAHardwareBuffer_allocate             allocate;
104         pfnAHardwareBuffer_describe             describe;
105         pfnAHardwareBuffer_acquire              acquire;
106         pfnAHardwareBuffer_release              release;
107         pfnAHardwareBuffer_isSupported  isSupported;
108 };
109
110 AhbFunctions ahbFunctions;
111
112 bool ahbFunctionsLoaded (AhbFunctions* pAhbFunctions)
113 {
114         static bool ahbApiLoaded = false;
115         if (ahbApiLoaded ||
116                         ((pAhbFunctions->allocate != DE_NULL) &&
117                          (pAhbFunctions->describe != DE_NULL) &&
118                          (pAhbFunctions->acquire  != DE_NULL) &&
119                          (pAhbFunctions->release  != DE_NULL) &&
120                          (pAhbFunctions->isSupported  != DE_NULL)))
121         {
122                 ahbApiLoaded = true;
123                 return true;
124         }
125         return false;
126 }
127
128 bool loadAhbDynamicApis (deInt32 sdkVersion)
129 {
130         if (sdkVersion >= __ANDROID_API_O__)
131         {
132                 if (!ahbFunctionsLoaded(&ahbFunctions))
133                 {
134                         static de::DynamicLibrary libnativewindow("libnativewindow.so");
135                         ahbFunctions.allocate = reinterpret_cast<pfnAHardwareBuffer_allocate>(libnativewindow.getFunction("AHardwareBuffer_allocate"));
136                         ahbFunctions.describe = reinterpret_cast<pfnAHardwareBuffer_describe>(libnativewindow.getFunction("AHardwareBuffer_describe"));
137                         ahbFunctions.acquire  = reinterpret_cast<pfnAHardwareBuffer_acquire>(libnativewindow.getFunction("AHardwareBuffer_acquire"));
138                         ahbFunctions.release  = reinterpret_cast<pfnAHardwareBuffer_release>(libnativewindow.getFunction("AHardwareBuffer_release"));
139                         ahbFunctions.isSupported  = reinterpret_cast<pfnAHardwareBuffer_isSupported>(libnativewindow.getFunction("AHardwareBuffer_isSupported"));
140
141                         return ahbFunctionsLoaded(&ahbFunctions);
142                 }
143                 else
144                 {
145                         return true;
146                 }
147         }
148
149         return false;
150 }
151
152 AHardwareBuffer_Format getPixelFormat (GLenum format)
153 {
154         switch (format)
155         {
156                 case GL_RGB565:                         return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
157                 case GL_RGB8:                           return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
158                 case GL_RGBA8:                          return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
159                 case GL_DEPTH_COMPONENT16:      return AHARDWAREBUFFER_FORMAT_D16_UNORM;
160                 case GL_DEPTH_COMPONENT24:      return AHARDWAREBUFFER_FORMAT_D24_UNORM;
161                 case GL_DEPTH24_STENCIL8:       return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
162                 case GL_DEPTH_COMPONENT32F:     return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
163                 case GL_DEPTH32F_STENCIL8:      return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
164                 case GL_RGB10_A2:                       return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
165                 case GL_RGBA16F:                        return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
166                 case GL_STENCIL_INDEX8:         return AHARDWAREBUFFER_FORMAT_S8_UINT;
167
168                 default:                                        TCU_THROW(NotSupportedError, "Texture format unsupported by Android");
169         }
170 }
171
172 class AndroidNativeClientBuffer : public ClientBuffer
173 {
174 public:
175                                                 AndroidNativeClientBuffer       (const Library& egl, GLenum format);
176                                                 ~AndroidNativeClientBuffer      (void);
177         EGLClientBuffer         get                                                     (void) const;
178         void                            lock                                            (void** data);
179         void                            unlock                                          (void);
180
181 private:
182         const Library&          m_egl;
183         AHardwareBuffer*        m_hardwareBuffer;
184 };
185
186 AndroidNativeClientBuffer::AndroidNativeClientBuffer (const Library& egl, GLenum format)
187         : m_egl(egl)
188 {
189         //deInt32 sdkVersion = checkAnbApiBuild();
190         deInt32 sdkVersion = androidGetSdkVersion();
191 #if defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
192         // When testing AHB on Android-P and newer the CTS must be compiled against API28 or newer.
193         DE_TEST_ASSERT(sdkVersion >= 28); /*__ANDROID_API_P__ */
194 #else
195         // When testing AHB on Android-O and newer the CTS must be compiled against API26 or newer.
196         DE_TEST_ASSERT(sdkVersion >= 26); /* __ANDROID_API_O__ */
197 #endif // !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
198
199         if (sdkVersion >= __ANDROID_API_O__)
200         {
201 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
202                 if (!loadAhbDynamicApis(sdkVersion))
203                 {
204                         // Couldn't load Android AHB system APIs.
205                         DE_TEST_ASSERT(false);
206                 }
207 #else
208                 // Invalid Android AHB APIs configuration. Please check the instructions on how to build NDK for Android.
209                 DE_TEST_ASSERT(false);
210 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
211         }
212
213         AHardwareBuffer_Desc hbufferdesc = {
214                 64u,
215                 64u,
216                 1u,             // number of images
217                 getPixelFormat(format),
218                 AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN    |
219                 AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY  |
220                 AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
221                 AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER,
222                 0u,             // Stride in pixels, ignored for AHardwareBuffer_allocate()
223                 0u,             // Initialize to zero, reserved for future use
224                 0u              // Initialize to zero, reserved for future use
225         };
226
227         if (!ahbFunctions.isSupported(&hbufferdesc))
228                 TCU_THROW(NotSupportedError, "Texture format unsupported");
229
230         ahbFunctions.allocate(&hbufferdesc, &m_hardwareBuffer);
231 }
232
233 AndroidNativeClientBuffer::~AndroidNativeClientBuffer (void)
234 {
235         ahbFunctions.release(m_hardwareBuffer);
236 }
237
238 EGLClientBuffer AndroidNativeClientBuffer::get (void) const
239 {
240         typedef EGLW_APICALL EGLClientBuffer (EGLW_APIENTRY* eglGetNativeClientBufferANDROIDFunc) (const struct AHardwareBuffer *buffer);
241         return ((eglGetNativeClientBufferANDROIDFunc)m_egl.getProcAddress("eglGetNativeClientBufferANDROID"))(m_hardwareBuffer);
242 }
243
244 void AndroidNativeClientBuffer::lock(void** data)
245 {
246         const int status = AHardwareBuffer_lock(m_hardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1, DE_NULL, data);
247
248         if (status != 0)
249                 TCU_FAIL(("AHardwareBuffer_lock failed with error: " + de::toString(status)).c_str());
250 }
251
252 void AndroidNativeClientBuffer::unlock(void)
253 {
254         const int status = AHardwareBuffer_unlock(m_hardwareBuffer, DE_NULL);
255
256         if (status != 0)
257                 TCU_FAIL(("AHardwareBuffer_unlock failed with error: " + de::toString(status)).c_str());
258 }
259
260 class AndroidNativeImageSource : public ImageSource
261 {
262 public:
263                                                         AndroidNativeImageSource        (GLenum format) : m_format(format) {}
264                                                         ~AndroidNativeImageSource       (void);
265         MovePtr<ClientBuffer>   createBuffer                            (const Library& egl, const glw::Functions&, Texture2D*) const;
266         string                                  getRequiredExtension            (void) const { return "EGL_ANDROID_get_native_client_buffer"; }
267         EGLImageKHR                             createImage                                     (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
268         GLenum                                  getEffectiveFormat                      (void) const { return m_format; }
269
270 protected:
271         GLenum                                  m_format;
272 };
273
274 AndroidNativeImageSource::~AndroidNativeImageSource (void)
275 {
276 }
277
278 MovePtr<ClientBuffer> AndroidNativeImageSource::createBuffer (const Library& egl, const glw::Functions&, Texture2D* ref) const
279 {
280         MovePtr<AndroidNativeClientBuffer> buffer (new AndroidNativeClientBuffer(egl, m_format));
281
282         if (ref != DE_NULL)
283         {
284                 const TextureFormat     texFormat       = glu::mapGLInternalFormat(m_format);
285                 void*                           bufferData      = DE_NULL;
286
287                 *ref = Texture2D(texFormat, 64, 64);
288                 ref->allocLevel(0);
289                 tcu::fillWithComponentGradients(ref->getLevel(0),
290                                                                                 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
291                                                                                 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
292         buffer->lock(&bufferData);
293                 {
294                         PixelBufferAccess nativeBuffer(texFormat, 64, 64, 1, bufferData);
295                         tcu::copy(nativeBuffer, ref->getLevel(0));
296                 }
297         buffer->unlock();
298         }
299         return MovePtr<ClientBuffer>(buffer);
300 }
301
302 EGLImageKHR AndroidNativeImageSource::createImage (const Library& egl, EGLDisplay dpy, EGLContext, EGLClientBuffer clientBuffer) const
303 {
304         static const EGLint     attribs[]       = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
305         const EGLImageKHR       image           = egl.createImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attribs);
306
307         EGLU_CHECK_MSG(egl, "eglCreateImageKHR()");
308         return image;
309 }
310
311 } // anonymous
312
313 MovePtr<ImageSource> createAndroidNativeImageSource     (GLenum format)
314 {
315         try
316         {
317                 return MovePtr<ImageSource>(new AndroidNativeImageSource(format));
318         }
319         catch (const std::runtime_error& exc)
320         {
321                 return createUnsupportedImageSource(string("Android native buffers unsupported: ") + exc.what(), format);
322         }
323 }
324
325 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
326
327 #endif // DE_OS == DE_OS_ANDROID
328
329 } // Image
330 } // egl
331 } // deqp