1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program EGL Module
3 * ---------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Android-specific operations.
22 *//*--------------------------------------------------------------------*/
24 #include "teglAndroidUtil.hpp"
26 #include "deStringUtil.hpp"
27 #include "tcuTextureUtil.hpp"
28 #include "gluTextureUtil.hpp"
29 #include "glwEnums.hpp"
30 #include "eglwLibrary.hpp"
31 #include "eglwEnums.hpp"
42 using tcu::PixelBufferAccess;
43 using tcu::TextureFormat;
45 using eglu::AttribMap;
49 #if (DE_OS != DE_OS_ANDROID)
51 MovePtr<ImageSource> createAndroidNativeImageSource (GLenum format)
53 return createUnsupportedImageSource("Not Android platform", format);
56 #else // DE_OS == DE_OS_ANDROID
58 #if defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
59 # define BUILT_WITH_ANDROID_HARDWARE_BUFFER 1
62 #if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
63 # define BUILT_WITH_ANDROID_P_HARDWARE_BUFFER 1
66 #if !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
68 MovePtr<ImageSource> createAndroidNativeImageSource (GLenum format)
70 return createUnsupportedImageSource("AHB API not supported", format);
73 #else // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
78 #include <sys/system_properties.h>
79 #include <android/hardware_buffer.h>
80 #include "deDynamicLibrary.hpp"
82 deInt32 androidGetSdkVersion (void)
84 static deInt32 sdkVersion = -1;
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);
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);
103 pfnAHardwareBuffer_allocate allocate;
104 pfnAHardwareBuffer_describe describe;
105 pfnAHardwareBuffer_acquire acquire;
106 pfnAHardwareBuffer_release release;
107 pfnAHardwareBuffer_isSupported isSupported;
110 AhbFunctions ahbFunctions;
112 bool ahbFunctionsLoaded (AhbFunctions* pAhbFunctions)
114 static bool ahbApiLoaded = false;
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)))
128 bool loadAhbDynamicApis (deInt32 sdkVersion)
130 if (sdkVersion >= __ANDROID_API_O__)
132 if (!ahbFunctionsLoaded(&ahbFunctions))
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"));
141 return ahbFunctionsLoaded(&ahbFunctions);
152 AHardwareBuffer_Format getPixelFormat (GLenum format)
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;
168 default: TCU_THROW(NotSupportedError, "Texture format unsupported by Android");
172 class AndroidNativeClientBuffer : public ClientBuffer
175 AndroidNativeClientBuffer (const Library& egl, GLenum format);
176 ~AndroidNativeClientBuffer (void);
177 EGLClientBuffer get (void) const;
178 void lock (void** data);
182 const Library& m_egl;
183 AHardwareBuffer* m_hardwareBuffer;
186 AndroidNativeClientBuffer::AndroidNativeClientBuffer (const Library& egl, GLenum format)
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__ */
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)
199 if (sdkVersion >= __ANDROID_API_O__)
201 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
202 if (!loadAhbDynamicApis(sdkVersion))
204 // Couldn't load Android AHB system APIs.
205 DE_TEST_ASSERT(false);
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)
213 AHardwareBuffer_Desc hbufferdesc = {
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
227 if (!ahbFunctions.isSupported(&hbufferdesc))
228 TCU_THROW(NotSupportedError, "Texture format unsupported");
230 ahbFunctions.allocate(&hbufferdesc, &m_hardwareBuffer);
233 AndroidNativeClientBuffer::~AndroidNativeClientBuffer (void)
235 ahbFunctions.release(m_hardwareBuffer);
238 EGLClientBuffer AndroidNativeClientBuffer::get (void) const
240 typedef EGLW_APICALL EGLClientBuffer (EGLW_APIENTRY* eglGetNativeClientBufferANDROIDFunc) (const struct AHardwareBuffer *buffer);
241 return ((eglGetNativeClientBufferANDROIDFunc)m_egl.getProcAddress("eglGetNativeClientBufferANDROID"))(m_hardwareBuffer);
244 void AndroidNativeClientBuffer::lock(void** data)
246 const int status = AHardwareBuffer_lock(m_hardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1, DE_NULL, data);
249 TCU_FAIL(("AHardwareBuffer_lock failed with error: " + de::toString(status)).c_str());
252 void AndroidNativeClientBuffer::unlock(void)
254 const int status = AHardwareBuffer_unlock(m_hardwareBuffer, DE_NULL);
257 TCU_FAIL(("AHardwareBuffer_unlock failed with error: " + de::toString(status)).c_str());
260 class AndroidNativeImageSource : public ImageSource
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; }
274 AndroidNativeImageSource::~AndroidNativeImageSource (void)
278 MovePtr<ClientBuffer> AndroidNativeImageSource::createBuffer (const Library& egl, const glw::Functions&, Texture2D* ref) const
280 MovePtr<AndroidNativeClientBuffer> buffer (new AndroidNativeClientBuffer(egl, m_format));
284 const TextureFormat texFormat = glu::mapGLInternalFormat(m_format);
285 void* bufferData = DE_NULL;
287 *ref = Texture2D(texFormat, 64, 64);
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);
294 PixelBufferAccess nativeBuffer(texFormat, 64, 64, 1, bufferData);
295 tcu::copy(nativeBuffer, ref->getLevel(0));
299 return MovePtr<ClientBuffer>(buffer);
302 EGLImageKHR AndroidNativeImageSource::createImage (const Library& egl, EGLDisplay dpy, EGLContext, EGLClientBuffer clientBuffer) const
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);
307 EGLU_CHECK_MSG(egl, "eglCreateImageKHR()");
313 MovePtr<ImageSource> createAndroidNativeImageSource (GLenum format)
317 return MovePtr<ImageSource>(new AndroidNativeImageSource(format));
319 catch (const std::runtime_error& exc)
321 return createUnsupportedImageSource(string("Android native buffers unsupported: ") + exc.what(), format);
325 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
327 #endif // DE_OS == DE_OS_ANDROID