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