framework/opengl/wrapper/glwWrapper.cpp \
framework/platform/android/tcuAndroidAssets.cpp \
framework/platform/android/tcuAndroidExecService.cpp \
- framework/platform/android/tcuAndroidInternals.cpp \
framework/platform/android/tcuAndroidJNI.cpp \
framework/platform/android/tcuAndroidMain.cpp \
framework/platform/android/tcuAndroidNativeActivity.cpp \
${TCUTIL_PLATFORM_SRCS}
android/tcuAndroidAssets.cpp
android/tcuAndroidAssets.hpp
- android/tcuAndroidInternals.cpp
- android/tcuAndroidInternals.hpp
android/tcuAndroidNativeActivity.cpp
android/tcuAndroidNativeActivity.hpp
android/tcuAndroidPlatform.cpp
+++ /dev/null
-/*-------------------------------------------------------------------------
- * drawElements Quality Program Tester Core
- * ----------------------------------------
- *
- * Copyright 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *//*!
- * \file
- * \brief Access to Android internals that are not a part of the NDK.
- *//*--------------------------------------------------------------------*/
-
-#include "tcuAndroidInternals.hpp"
-#include "deMemory.h"
-#include "deStringUtil.hpp"
-
-namespace tcu
-{
-namespace Android
-{
-namespace internal
-{
-
-using std::string;
-using de::DynamicLibrary;
-
-template<typename Func>
-void setFuncPtr (Func*& funcPtr, DynamicLibrary& lib, const string& symname)
-{
- funcPtr = reinterpret_cast<Func*>(lib.getFunction(symname.c_str()));
- if (!funcPtr)
- TCU_THROW(NotSupportedError, ("Unable to look up symbol from shared object: " + symname).c_str());
-}
-
-LibUI::LibUI (void)
- : m_library ("libui.so")
-{
- GraphicBufferFunctions& gb = m_functions.graphicBuffer;
-
- setFuncPtr(gb.constructor, m_library, "_ZN7android13GraphicBufferC1Ejjij");
- setFuncPtr(gb.destructor, m_library, "_ZN7android13GraphicBufferD1Ev");
- setFuncPtr(gb.getNativeBuffer, m_library, "_ZNK7android13GraphicBuffer15getNativeBufferEv");
- setFuncPtr(gb.lock, m_library, "_ZN7android13GraphicBuffer4lockEjPPv");
- setFuncPtr(gb.unlock, m_library, "_ZN7android13GraphicBuffer6unlockEv");
- setFuncPtr(gb.initCheck, m_library, "_ZNK7android13GraphicBuffer9initCheckEv");
-}
-
-#define GRAPHICBUFFER_SIZE 1024 // Hopefully enough
-
-typedef void (*GenericFptr)();
-
-//! call constructor with 4 arguments
-template <typename RT, typename T1, typename T2, typename T3, typename T4>
-RT* callConstructor4 (GenericFptr fptr, void* memory, size_t memorySize, T1 param1, T2 param2, T3 param3, T4 param4)
-{
- DE_UNREF(memorySize);
-
-#if (DE_CPU == DE_CPU_ARM)
- // C1 constructors return pointer
- typedef RT* (*ABIFptr)(void*, T1, T2, T3, T4);
- (void)((ABIFptr)fptr)(memory, param1, param2, param3, param4);
- return reinterpret_cast<RT*>(memory);
-#elif (DE_CPU == DE_CPU_ARM_64)
- // C1 constructors return void
- typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
- ((ABIFptr)fptr)(memory, param1, param2, param3, param4);
- return reinterpret_cast<RT*>(memory);
-#elif (DE_CPU == DE_CPU_X86)
- // ctor returns void
- typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
- ((ABIFptr)fptr)(memory, param1, param2, param3, param4);
- return reinterpret_cast<RT*>(memory);
-#elif (DE_CPU == DE_CPU_X86_64)
- // ctor returns void
- typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
- ((ABIFptr)fptr)(memory, param1, param2, param3, param4);
- return reinterpret_cast<RT*>(memory);
-#else
- DE_UNREF(fptr);
- DE_UNREF(memory);
- DE_UNREF(param1);
- DE_UNREF(param2);
- DE_UNREF(param3);
- DE_UNREF(param4);
- TCU_THROW(NotSupportedError, "ABI not supported");
- return DE_NULL;
-#endif
-}
-
-template <typename T>
-void callDestructor (GenericFptr fptr, T* obj)
-{
-#if (DE_CPU == DE_CPU_ARM)
- // D1 destructor returns ptr
- typedef void* (*ABIFptr)(T* obj);
- (void)((ABIFptr)fptr)(obj);
-#elif (DE_CPU == DE_CPU_ARM_64)
- // D1 destructor returns void
- typedef void (*ABIFptr)(T* obj);
- ((ABIFptr)fptr)(obj);
-#elif (DE_CPU == DE_CPU_X86)
- // dtor returns void
- typedef void (*ABIFptr)(T* obj);
- ((ABIFptr)fptr)(obj);
-#elif (DE_CPU == DE_CPU_X86_64)
- // dtor returns void
- typedef void (*ABIFptr)(T* obj);
- ((ABIFptr)fptr)(obj);
-#else
- DE_UNREF(fptr);
- DE_UNREF(obj);
- TCU_THROW(NotSupportedError, "ABI not supported");
-#endif
-}
-
-template<typename T1, typename T2>
-T1* pointerToOffset (T2* ptr, size_t bytes)
-{
- return reinterpret_cast<T1*>((deUint8*)ptr + bytes);
-}
-
-static android::android_native_base_t* getAndroidNativeBase (android::GraphicBuffer* gb)
-{
- // \note: assuming Itanium ABI
- return pointerToOffset<android::android_native_base_t>(gb, 2 * DE_PTR_SIZE);
-}
-
-//! android_native_base_t::magic for ANativeWindowBuffer
-static deInt32 getExpectedNativeBufferVersion (void)
-{
-#if (DE_PTR_SIZE == 4)
- return 96;
-#elif (DE_PTR_SIZE == 8)
- return 168;
-#else
-# error Invalid DE_PTR_SIZE
-#endif
-}
-
-//! access android_native_base_t::magic
-static deUint32 getNativeBaseMagic (android::android_native_base_t* base)
-{
- return *pointerToOffset<deUint32>(base, 0);
-}
-
-//! access android_native_base_t::version
-static deUint32 getNativeBaseVersion (android::android_native_base_t* base)
-{
- return *pointerToOffset<deInt32>(base, 4);
-}
-
-//! access android_native_base_t::incRef
-static NativeBaseFunctions::incRefFunc getNativeBaseIncRefFunc (android::android_native_base_t* base)
-{
- return *pointerToOffset<NativeBaseFunctions::incRefFunc>(base, 8 + DE_PTR_SIZE*4);
-}
-
-//! access android_native_base_t::decRef
-static NativeBaseFunctions::decRefFunc getNativeBaseDecRefFunc (android::android_native_base_t* base)
-{
- return *pointerToOffset<NativeBaseFunctions::decRefFunc>(base, 8 + DE_PTR_SIZE*5);
-}
-
-static android::GraphicBuffer* createGraphicBuffer (const GraphicBufferFunctions& functions, NativeBaseFunctions& baseFunctions, deUint32 w, deUint32 h, PixelFormat format, deUint32 usage)
-{
- // \note: Hopefully uses the same allocator as libui
- void* const memory = deMalloc(GRAPHICBUFFER_SIZE);
- if (memory == DE_NULL)
- TCU_THROW(ResourceError, "Could not alloc for GraphicBuffer");
- else
- {
- try
- {
- android::GraphicBuffer* const gb = callConstructor4<android::GraphicBuffer, deUint32, deUint32, PixelFormat, deUint32>(functions.constructor,
- memory,
- GRAPHICBUFFER_SIZE,
- w,
- h,
- format,
- usage);
- android::android_native_base_t* const base = getAndroidNativeBase(gb);
- status_t ctorStatus = functions.initCheck(gb);
-
- if (ctorStatus)
- {
- // ctor failed
- callDestructor<android::GraphicBuffer>(functions.destructor, gb);
- TCU_THROW(NotSupportedError, ("GraphicBuffer ctor failed, initCheck returned " + de::toString(ctorStatus)).c_str());
- }
-
- // check object layout
- {
- const deUint32 magic = getNativeBaseMagic(base);
- const deUint32 bufferMagic = 0x5f626672u; // "_bfr"
-
- if (magic != bufferMagic)
- TCU_THROW(NotSupportedError, "GraphicBuffer layout unexpected");
- }
-
- // check object version
- {
- const deInt32 version = getNativeBaseVersion(base);
- const deInt32 expectedVersion = getExpectedNativeBufferVersion();
-
- if (version != expectedVersion)
- TCU_THROW(NotSupportedError, "GraphicBuffer version unexpected");
- }
-
- // locate refcounting functions
-
- if (!baseFunctions.incRef || !baseFunctions.decRef)
- {
- baseFunctions.incRef = getNativeBaseIncRefFunc(base);
- baseFunctions.decRef = getNativeBaseDecRefFunc(base);
- }
-
- // take the initial reference and return
- baseFunctions.incRef(base);
- return gb;
- }
- catch (...)
- {
- deFree(memory);
- throw;
- }
- }
-}
-
-GraphicBuffer::GraphicBuffer (const LibUI& lib, deUint32 width, deUint32 height, PixelFormat format, deUint32 usage)
- : m_functions (lib.getFunctions().graphicBuffer)
- , m_impl (DE_NULL)
-{
- m_baseFunctions.incRef = DE_NULL;
- m_baseFunctions.decRef = DE_NULL;
-
- // \note createGraphicBuffer updates m_baseFunctions
- m_impl = createGraphicBuffer(m_functions, m_baseFunctions, width, height, format, usage);
-}
-
-GraphicBuffer::~GraphicBuffer (void)
-{
- if (m_impl && m_baseFunctions.decRef)
- {
- m_baseFunctions.decRef(getAndroidNativeBase(m_impl));
- m_impl = DE_NULL;
- }
-}
-
-status_t GraphicBuffer::lock (deUint32 usage, void** vaddr)
-{
- return m_functions.lock(m_impl, usage, vaddr);
-}
-
-status_t GraphicBuffer::unlock (void)
-{
- return m_functions.unlock(m_impl);
-}
-
-ANativeWindowBuffer* GraphicBuffer::getNativeBuffer (void) const
-{
- return m_functions.getNativeBuffer(m_impl);
-}
-
-} // internal
-} // Android
-} // tcu
+++ /dev/null
-#ifndef _TCUANDROIDINTERNALS_HPP
-#define _TCUANDROIDINTERNALS_HPP
-/*-------------------------------------------------------------------------
- * drawElements Quality Program Tester Core
- * ----------------------------------------
- *
- * Copyright 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *//*!
- * \file
- * \brief Access to Android internals that are not a part of the NDK.
- *//*--------------------------------------------------------------------*/
-
-#include "tcuDefs.hpp"
-
-#include "deDynamicLibrary.hpp"
-
-#include <vector>
-#include <errno.h>
-
-struct ANativeWindowBuffer;
-
-namespace android
-{
-class GraphicBuffer;
-class android_native_base_t;
-}
-
-namespace tcu
-{
-
-namespace Android
-{
-
-// These classes and enums reflect internal android definitions
-namespace internal
-{
-
-// utils/Errors.h
-enum
-{
- OK = 0,
- UNKNOWN_ERROR = (-2147483647-1),
- NO_MEMORY = -ENOMEM,
- INVALID_OPERATION = -ENOSYS,
- BAD_VALUE = -EINVAL,
- BAD_TYPE = (UNKNOWN_ERROR + 1),
- NAME_NOT_FOUND = -ENOENT,
- PERMISSION_DENIED = -EPERM,
- NO_INIT = -ENODEV,
- ALREADY_EXISTS = -EEXIST,
- DEAD_OBJECT = -EPIPE,
- FAILED_TRANSACTION = (UNKNOWN_ERROR + 2),
- BAD_INDEX = -E2BIG,
- NOT_ENOUGH_DATA = (UNKNOWN_ERROR + 3),
- WOULD_BLOCK = (UNKNOWN_ERROR + 4),
- TIMED_OUT = (UNKNOWN_ERROR + 5),
- UNKNOWN_TRANSACTION = (UNKNOWN_ERROR + 6),
- FDS_NOT_ALLOWED = (UNKNOWN_ERROR + 7),
-};
-
-typedef deInt32 status_t;
-
-// ui/PixelFormat.h, system/graphics.h
-enum
-{
- PIXEL_FORMAT_UNKNOWN = 0,
- PIXEL_FORMAT_NONE = 0,
- PIXEL_FORMAT_CUSTOM = -4,
- PIXEL_FORMAT_TRANSLUCENT = -3,
- PIXEL_FORMAT_TRANSPARENT = -2,
- PIXEL_FORMAT_OPAQUE = -1,
- PIXEL_FORMAT_RGBA_8888 = 1,
- PIXEL_FORMAT_RGBX_8888 = 2,
- PIXEL_FORMAT_RGB_888 = 3,
- PIXEL_FORMAT_RGB_565 = 4,
- PIXEL_FORMAT_BGRA_8888 = 5,
- PIXEL_FORMAT_RGBA_5551 = 6,
- PIXEL_FORMAT_RGBA_4444 = 7,
-};
-
-typedef deInt32 PixelFormat;
-
-// ui/GraphicBuffer.h
-struct GraphicBufferFunctions
-{
- typedef void (*genericFunc) ();
- typedef status_t (*initCheckFunc) (android::GraphicBuffer* buffer);
- typedef status_t (*lockFunc) (android::GraphicBuffer* buffer, deUint32 usage, void** vaddr);
- typedef status_t (*unlockFunc) (android::GraphicBuffer* buffer);
- typedef ANativeWindowBuffer* (*getNativeBufferFunc) (const android::GraphicBuffer* buffer);
-
- genericFunc constructor;
- genericFunc destructor;
- lockFunc lock;
- unlockFunc unlock;
- getNativeBufferFunc getNativeBuffer;
- initCheckFunc initCheck;
-};
-
-// system/window.h
-struct NativeBaseFunctions
-{
- typedef void (*incRefFunc) (android::android_native_base_t* base);
- typedef void (*decRefFunc) (android::android_native_base_t* base);
-
- incRefFunc incRef;
- decRefFunc decRef;
-};
-
-struct LibUIFunctions
-{
- GraphicBufferFunctions graphicBuffer;
-};
-
-class LibUI
-{
-public:
- struct Functions
- {
- GraphicBufferFunctions graphicBuffer;
- };
-
- LibUI (void);
- const Functions& getFunctions (void) const { return m_functions; }
-
-private:
- Functions m_functions;
- de::DynamicLibrary m_library;
-};
-
-class GraphicBuffer
-{
-public:
- // ui/GraphicBuffer.h, hardware/gralloc.h
- enum {
- USAGE_SW_READ_NEVER = 0x00000000,
- USAGE_SW_READ_RARELY = 0x00000002,
- USAGE_SW_READ_OFTEN = 0x00000003,
- USAGE_SW_READ_MASK = 0x0000000f,
-
- USAGE_SW_WRITE_NEVER = 0x00000000,
- USAGE_SW_WRITE_RARELY = 0x00000020,
- USAGE_SW_WRITE_OFTEN = 0x00000030,
- USAGE_SW_WRITE_MASK = 0x000000f0,
-
- USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK | USAGE_SW_WRITE_MASK,
-
- USAGE_PROTECTED = 0x00004000,
-
- USAGE_HW_TEXTURE = 0x00000100,
- USAGE_HW_RENDER = 0x00000200,
- USAGE_HW_2D = 0x00000400,
- USAGE_HW_COMPOSER = 0x00000800,
- USAGE_HW_VIDEO_ENCODER = 0x00010000,
- USAGE_HW_MASK = 0x00071F00,
- };
-
- GraphicBuffer (const LibUI& lib, deUint32 width, deUint32 height, PixelFormat format, deUint32 usage);
- ~GraphicBuffer ();
-
- status_t lock (deUint32 usage, void** vaddr);
- status_t unlock (void);
- ANativeWindowBuffer* getNativeBuffer (void) const;
-
-private:
- const GraphicBufferFunctions& m_functions;
- NativeBaseFunctions m_baseFunctions;
- android::GraphicBuffer* m_impl;
-};
-
-} // internal
-} // Android
-} // tcu
-
-#endif // _TCUANDROIDINTERNALS_HPP
#include "eglwLibrary.hpp"
#include "eglwEnums.hpp"
-#if (DE_OS == DE_OS_ANDROID)
-# include "tcuAndroidInternals.hpp"
-#endif
-
namespace deqp
{
namespace egl
{
namespace Image
{
+
using std::string;
using de::MovePtr;
using tcu::PixelBufferAccess;
#else // DE_OS == DE_OS_ANDROID
-using tcu::Android::internal::LibUI;
-using tcu::Android::internal::GraphicBuffer;
-using tcu::Android::internal::PixelFormat;
-using tcu::Android::internal::status_t;
+namespace
+{
+
+#if defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
+# include <android/hardware_buffer.h>
+# include "deDynamicLibrary.hpp"
+# define BUILT_WITH_ANDROID_HARDWARE_BUFFER 1
+#endif
+
+#if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
+# define BUILT_WITH_ANDROID_P_HARDWARE_BUFFER 1
+#endif
+
+deInt32 androidGetSdkVersion (void)
+{
+ static deInt32 sdkVersion = -1;
+ if (sdkVersion < 0)
+ {
+ char value[128] = {0};
+ __system_property_get("ro.build.version.sdk", value);
+ sdkVersion = static_cast<deInt32>(strtol(value, DE_NULL, 10));
+ printf("SDK Version is %d\n", sdkVersion);
+ }
+ return sdkVersion;
+}
+
+typedef int (*pfnAHardwareBuffer_allocate)(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer);
+typedef void (*pfnAHardwareBuffer_describe)(const AHardwareBuffer* buffer, AHardwareBuffer_Desc* outDesc);
+typedef void (*pfnAHardwareBuffer_acquire)(AHardwareBuffer* buffer);
+typedef void (*pfnAHardwareBuffer_release)(AHardwareBuffer* buffer);
+typedef int (*pfnAHardwareBuffer_isSupported)(const AHardwareBuffer_Desc* desc);
+
+struct AhbFunctions
+{
+ pfnAHardwareBuffer_allocate allocate;
+ pfnAHardwareBuffer_describe describe;
+ pfnAHardwareBuffer_acquire acquire;
+ pfnAHardwareBuffer_release release;
+ pfnAHardwareBuffer_isSupported isSupported;
+};
+
+AhbFunctions ahbFunctions;
+
+bool ahbFunctionsLoaded (AhbFunctions* pAhbFunctions)
+{
+ static bool ahbApiLoaded = false;
+ if (ahbApiLoaded ||
+ ((pAhbFunctions->allocate != DE_NULL) &&
+ (pAhbFunctions->describe != DE_NULL) &&
+ (pAhbFunctions->acquire != DE_NULL) &&
+ (pAhbFunctions->release != DE_NULL) &&
+ (pAhbFunctions->isSupported != DE_NULL)))
+ {
+ ahbApiLoaded = true;
+ return true;
+ }
+ return false;
+}
+
+bool loadAhbDynamicApis (deInt32 sdkVersion)
+{
+ if (sdkVersion >= __ANDROID_API_O__)
+ {
+ if (!ahbFunctionsLoaded(&ahbFunctions))
+ {
+ static de::DynamicLibrary libnativewindow("libnativewindow.so");
+ ahbFunctions.allocate = reinterpret_cast<pfnAHardwareBuffer_allocate>(libnativewindow.getFunction("AHardwareBuffer_allocate"));
+ ahbFunctions.describe = reinterpret_cast<pfnAHardwareBuffer_describe>(libnativewindow.getFunction("AHardwareBuffer_describe"));
+ ahbFunctions.acquire = reinterpret_cast<pfnAHardwareBuffer_acquire>(libnativewindow.getFunction("AHardwareBuffer_acquire"));
+ ahbFunctions.release = reinterpret_cast<pfnAHardwareBuffer_release>(libnativewindow.getFunction("AHardwareBuffer_release"));
+ ahbFunctions.isSupported = reinterpret_cast<pfnAHardwareBuffer_isSupported>(libnativewindow.getFunction("AHardwareBuffer_isSupported"));
+
+ return ahbFunctionsLoaded(&ahbFunctions);
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
-PixelFormat getPixelFormat (GLenum format)
+AHardwareBuffer_Format getPixelFormat (GLenum format)
{
switch (format)
{
- case GL_RGB565: return tcu::Android::internal::PIXEL_FORMAT_RGB_565;
- case GL_RGB8: return tcu::Android::internal::PIXEL_FORMAT_RGB_888;
- case GL_RGBA4: return tcu::Android::internal::PIXEL_FORMAT_RGBA_4444;
- case GL_RGB5_A1: return tcu::Android::internal::PIXEL_FORMAT_RGBA_5551;
- case GL_RGBA8: return tcu::Android::internal::PIXEL_FORMAT_RGBA_8888;
- default: TCU_THROW(NotSupportedError, "Texture format unsupported by Android");
+ case GL_RGB565: return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
+ case GL_RGB8: return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
+ case GL_RGBA8: return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+ case GL_DEPTH_COMPONENT16: return AHARDWAREBUFFER_FORMAT_D16_UNORM;
+ case GL_DEPTH_COMPONENT24: return AHARDWAREBUFFER_FORMAT_D24_UNORM;
+ case GL_DEPTH24_STENCIL8: return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
+ case GL_DEPTH_COMPONENT32F: return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
+ case GL_DEPTH32F_STENCIL8: return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
+ case GL_RGB10_A2: return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
+ case GL_RGBA16F: return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
+ case GL_STENCIL_INDEX8: return AHARDWAREBUFFER_FORMAT_S8_UINT;
+
+ default: TCU_THROW(NotSupportedError, "Texture format unsupported by Android");
}
}
class AndroidNativeClientBuffer : public ClientBuffer
{
public:
- AndroidNativeClientBuffer (const LibUI& lib, GLenum format);
- EGLClientBuffer get (void) const { return reinterpret_cast<EGLClientBuffer>(m_windowBuffer); }
- GraphicBuffer& getGraphicBuffer (void) { return m_graphicBuffer; }
+ AndroidNativeClientBuffer (const Library& egl, GLenum format);
+ ~AndroidNativeClientBuffer (void);
+ EGLClientBuffer get (void) const;
+ void lock (void** data);
+ void unlock (void);
private:
- GraphicBuffer m_graphicBuffer;
- ANativeWindowBuffer* m_windowBuffer;
+ const Library& m_egl;
+ AHardwareBuffer* m_hardwareBuffer;
};
-AndroidNativeClientBuffer::AndroidNativeClientBuffer (const LibUI& lib, GLenum format)
- : m_graphicBuffer (lib, 64, 64, getPixelFormat(format),
- GraphicBuffer::USAGE_SW_READ_OFTEN |
- GraphicBuffer::USAGE_SW_WRITE_RARELY |
- GraphicBuffer::USAGE_HW_TEXTURE |
- GraphicBuffer::USAGE_HW_RENDER)
- , m_windowBuffer (m_graphicBuffer.getNativeBuffer())
+AndroidNativeClientBuffer::AndroidNativeClientBuffer (const Library& egl, GLenum format)
+ : m_egl(egl)
{
+ //deInt32 sdkVersion = checkAnbApiBuild();
+ deInt32 sdkVersion = androidGetSdkVersion();
+#if defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
+ // When testing AHB on Android-P and newer the CTS must be compiled against API28 or newer.
+ DE_TEST_ASSERT(sdkVersion >= 28); /*__ANDROID_API_P__ */
+#else
+ // When testing AHB on Android-O and newer the CTS must be compiled against API26 or newer.
+ DE_TEST_ASSERT(sdkVersion >= 26); /* __ANDROID_API_O__ */
+#endif // !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
+
+ if (sdkVersion >= __ANDROID_API_O__)
+ {
+#if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
+ if (!loadAhbDynamicApis(sdkVersion))
+ {
+ // Couldn't load Android AHB system APIs.
+ DE_TEST_ASSERT(false);
+ }
+#else
+ // Invalid Android AHB APIs configuration. Please check the instructions on how to build NDK for Android.
+ DE_TEST_ASSERT(false);
+#endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
+ }
+
+ AHardwareBuffer_Desc hbufferdesc = {
+ 64u,
+ 64u,
+ 1u, // number of images
+ getPixelFormat(format),
+ AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
+ AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY |
+ AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
+ AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER,
+ 0u, // Stride in pixels, ignored for AHardwareBuffer_allocate()
+ 0u, // Initialize to zero, reserved for future use
+ 0u // Initialize to zero, reserved for future use
+ };
+
+ if (!ahbFunctions.isSupported(&hbufferdesc))
+ TCU_THROW(NotSupportedError, "Texture format unsupported");
+
+ ahbFunctions.allocate(&hbufferdesc, &m_hardwareBuffer);
+}
+
+AndroidNativeClientBuffer::~AndroidNativeClientBuffer (void)
+{
+ ahbFunctions.release(m_hardwareBuffer);
+}
+
+EGLClientBuffer AndroidNativeClientBuffer::get (void) const
+{
+ typedef EGLW_APICALL EGLClientBuffer (EGLW_APIENTRY* eglGetNativeClientBufferANDROIDFunc) (const struct AHardwareBuffer *buffer);
+ return ((eglGetNativeClientBufferANDROIDFunc)m_egl.getProcAddress("eglGetNativeClientBufferANDROID"))(m_hardwareBuffer);
+}
+
+void AndroidNativeClientBuffer::lock(void** data)
+{
+ const int status = AHardwareBuffer_lock(m_hardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, -1, DE_NULL, data);
+
+ if (status != 0)
+ TCU_FAIL(("AHardwareBuffer_lock failed with error: " + de::toString(status)).c_str());
+}
+
+void AndroidNativeClientBuffer::unlock(void)
+{
+ const int status = AHardwareBuffer_unlock(m_hardwareBuffer, DE_NULL);
+
+ if (status != 0)
+ TCU_FAIL(("AHardwareBuffer_unlock failed with error: " + de::toString(status)).c_str());
}
class AndroidNativeImageSource : public ImageSource
{
public:
- AndroidNativeImageSource (GLenum format) : m_format(format), m_libui(DE_NULL) {}
+ AndroidNativeImageSource (GLenum format) : m_format(format) {}
~AndroidNativeImageSource (void);
- MovePtr<ClientBuffer> createBuffer (const glw::Functions&, Texture2D*) const;
- string getRequiredExtension (void) const { return "EGL_ANDROID_image_native_buffer"; }
+ MovePtr<ClientBuffer> createBuffer (const Library& egl, const glw::Functions&, Texture2D*) const;
+ string getRequiredExtension (void) const { return "EGL_ANDROID_get_native_client_buffer"; }
EGLImageKHR createImage (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
GLenum getEffectiveFormat (void) const { return m_format; }
protected:
GLenum m_format;
-
- const LibUI& getLibUI (void) const;
-
-private:
- mutable LibUI* m_libui;
};
AndroidNativeImageSource::~AndroidNativeImageSource (void)
{
- delete m_libui;
-}
-
-const LibUI& AndroidNativeImageSource::getLibUI (void) const
-{
- if (!m_libui)
- m_libui = new LibUI();
-
- return *m_libui;
}
-void checkStatus (status_t status)
+MovePtr<ClientBuffer> AndroidNativeImageSource::createBuffer (const Library& egl, const glw::Functions&, Texture2D* ref) const
{
- if (status != tcu::Android::internal::OK)
- TCU_FAIL(("Android error: status code " + de::toString(status)).c_str());
-}
+ MovePtr<AndroidNativeClientBuffer> buffer (new AndroidNativeClientBuffer(egl, m_format));
-MovePtr<ClientBuffer> AndroidNativeImageSource::createBuffer (const glw::Functions&, Texture2D* ref) const
-{
- MovePtr<AndroidNativeClientBuffer> buffer (new AndroidNativeClientBuffer(getLibUI(), m_format));
- GraphicBuffer& graphicBuffer = buffer->getGraphicBuffer();
if (ref != DE_NULL)
{
const TextureFormat texFormat = glu::mapGLInternalFormat(m_format);
tcu::fillWithComponentGradients(ref->getLevel(0),
tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
- checkStatus(graphicBuffer.lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, &bufferData));
+ buffer->lock(&bufferData);
{
PixelBufferAccess nativeBuffer(texFormat, 64, 64, 1, bufferData);
tcu::copy(nativeBuffer, ref->getLevel(0));
}
- checkStatus(graphicBuffer.unlock());
+ buffer->unlock();
}
return MovePtr<ClientBuffer>(buffer);
}
EGLImageKHR AndroidNativeImageSource::createImage (const Library& egl, EGLDisplay dpy, EGLContext, EGLClientBuffer clientBuffer) const
{
- static const EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+ static const EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
const EGLImageKHR image = egl.createImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attribs);
EGLU_CHECK_MSG(egl, "eglCreateImageKHR()");
return image;
}
+} // anonymous
+
MovePtr<ImageSource> createAndroidNativeImageSource (GLenum format)
{
try
bool GLES2ImageApi::Create::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const
{
- de::UniquePtr<ClientBuffer> buffer (m_imgSource->createBuffer(api.m_gl, &ref));
+ de::UniquePtr<ClientBuffer> buffer (m_imgSource->createBuffer(api.m_egl, api.m_gl, &ref));
GLU_CHECK_GLW_CALL(api.m_gl, finish());
tcu::Surface screen (reference.getWidth(), reference.getHeight());
tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
- // Branch only taken in TryAll case
- if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
- throw IllegalRendererException(); // Skip, GLES2 does not support ReadPixels for depth attachments
- if (reference.getFormat().order == tcu::TextureFormat::S)
- throw IllegalRendererException(); // Skip, GLES2 does not support ReadPixels for stencil attachments
+ switch (glu::getInternalFormat(reference.getFormat()))
+ {
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB565:
+ break;
+ default:
+ // Skip, not in the list of allowed render buffer formats for GLES2.
+ throw tcu::NotSupportedError("Image format not allowed for glReadPixels.");
+ break;
+ }
log << tcu::TestLog::Message << "Reading with ReadPixels from renderbuffer" << tcu::TestLog::EndMessage;
GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer));
imageTargetRenderbuffer(api.m_egl, gl, **img);
+
+ GLU_EXPECT_NO_ERROR(gl.getError(), "imageTargetRenderbuffer");
framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferRenderbuffer");
GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
- gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
+ GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
void add (const string& label, MovePtr<Action> action);
int size (void) const { return m_numActions; }
private:
- LabeledAction m_actions[32];
+ LabeledAction m_actions[64];
int m_numActions;
};
void ImageTests::addCreateAndroidNativeActions (void)
{
- addCreateAndroidNative("android_native_rgb565", GL_RGB565);
- addCreateAndroidNative("android_native_rgb8", GL_RGB8);
addCreateAndroidNative("android_native_rgba4", GL_RGBA4);
addCreateAndroidNative("android_native_rgb5_a1", GL_RGB5_A1);
+ addCreateAndroidNative("android_native_rgb565", GL_RGB565);
+ addCreateAndroidNative("android_native_rgb8", GL_RGB8);
addCreateAndroidNative("android_native_rgba8", GL_RGBA8);
+ addCreateAndroidNative("android_native_d16", GL_DEPTH_COMPONENT16);
+ addCreateAndroidNative("android_native_d24", GL_DEPTH_COMPONENT24);
+ addCreateAndroidNative("android_native_d24s8", GL_DEPTH24_STENCIL8);
+ addCreateAndroidNative("android_native_d32f", GL_DEPTH_COMPONENT32F);
+ addCreateAndroidNative("android_native_d32fs8", GL_DEPTH32F_STENCIL8);
+ addCreateAndroidNative("android_native_rgb10a2", GL_RGB10_A2);
+ addCreateAndroidNative("android_native_rgba16f", GL_RGBA16F);
+ addCreateAndroidNative("android_native_s8", GL_STENCIL_INDEX8);
}
class RenderTests : public ImageTests
case GL_RGBA4:
case GL_RGBA8:
case GL_RGB5_A1:
+ case GL_RGB10_A2:
+ case GL_RGBA16F:
return false;
case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+ case GL_DEPTH_COMPONENT32F:
+ case GL_DEPTH24_STENCIL8:
+ case GL_DEPTH32F_STENCIL8:
return true;
case GL_STENCIL_INDEX8:
case GL_RGBA4:
case GL_RGBA8:
case GL_RGB5_A1:
+ case GL_RGB10_A2:
+ case GL_RGBA16F:
return false;
case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+ case GL_DEPTH_COMPONENT32F:
return false;
case GL_STENCIL_INDEX8:
+ case GL_DEPTH24_STENCIL8:
+ case GL_DEPTH32F_STENCIL8:
return true;
default:
void MultiContextRenderTests::addClearActions (void)
{
- m_clearActions.add("renderbuffer_clear_color", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearColor(tcu::Vec4(0.8f, 0.2f, 0.9f, 1.0f))));
- m_clearActions.add("renderbuffer_clear_depth", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearDepth(0.75f)));
- m_clearActions.add("renderbuffer_clear_stencil", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearStencil(97)));
+ m_clearActions.add("clear_color", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearColor(tcu::Vec4(0.8f, 0.2f, 0.9f, 1.0f))));
+ m_clearActions.add("clear_depth", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearDepth(0.75f)));
+ m_clearActions.add("clear_stencil", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearStencil(97)));
}
void MultiContextRenderTests::init (void)
continue;
spec.name = std::string("gles2_") + createAction.label + "_" + renderAction.label;
+
+ const GLenum createFormat = dynamic_cast<const GLES2ImageApi::Create*>(createAction.action.get())->getEffectiveFormat();
+ if (isDepthFormat(createFormat) && isStencilFormat(createFormat))
+ {
+ // Combined depth and stencil format. Add the clear action label to avoid test
+ // name clashes.
+ spec.name += std::string("_") + clearAction.label;
+ }
+
spec.desc = spec.name;
spec.contexts.push_back(TestSpec::API_GLES2);
case GL_LUMINANCE_ALPHA: return "luminance_alpha";
case GL_RGB: return "rgb";
case GL_RGBA: return "rgba";
+ case GL_RGBA16F: return "rgba16f";
case GL_DEPTH_COMPONENT16: return "depth_component_16";
+ case GL_DEPTH_COMPONENT24: return "depth_component_24";
+ case GL_DEPTH_COMPONENT32F: return "depth_component_32f";
+ case GL_DEPTH24_STENCIL8: return "depth24_stencil8";
+ case GL_DEPTH32F_STENCIL8: return "depth32f_stencil8";
+ case GL_RGB10_A2: return "rgb10_a2";
case GL_RGBA4: return "rgba4";
case GL_RGB5_A1: return "rgb5_a1";
case GL_RGB565: return "rgb565";
log << TestLog::Message << "Using EGL config " << eglu::getConfigID(egl, dpy, context.getConfig()) << TestLog::EndMessage;
- UniquePtr<ClientBuffer> clientBuffer (m_source->createBuffer(context.gl()));
+ UniquePtr<ClientBuffer> clientBuffer (m_source->createBuffer(egl, context.gl()));
const EGLImageKHR image = m_source->createImage(egl, dpy, eglContext, clientBuffer->get());
if (image == EGL_NO_IMAGE_KHR)
{
GL_RGB565,
GL_RGB8,
+ GL_RGBA8,
GL_RGBA4,
GL_RGB5_A1,
- GL_RGBA8,
+ GL_DEPTH_COMPONENT16,
+ GL_DEPTH_COMPONENT24,
+ GL_DEPTH24_STENCIL8,
+ GL_DEPTH_COMPONENT32F,
+ GL_DEPTH32F_STENCIL8,
+ GL_RGB10_A2,
+ GL_RGBA16F,
+ GL_STENCIL_INDEX8
};
for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(androidFormats); ++formatNdx)
{
public:
TextureImageSource (GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0) : m_internalFormat(internalFormat), m_format(format), m_type(type), m_useTexLevel0(useTexLevel0) {}
- MovePtr<ClientBuffer> createBuffer (const glw::Functions& gl, Texture2D* reference) const;
+ MovePtr<ClientBuffer> createBuffer (const eglw::Library& egl, const glw::Functions& gl, Texture2D* reference) const;
GLenum getEffectiveFormat (void) const;
GLenum getInternalFormat (void) const { return m_internalFormat; }
return ret;
}
-MovePtr<ClientBuffer> TextureImageSource::createBuffer (const glw::Functions& gl, Texture2D* ref) const
+MovePtr<ClientBuffer> TextureImageSource::createBuffer (const eglw::Library& egl, const glw::Functions& gl, Texture2D* ref) const
{
+ DE_UNREF(egl);
+
MovePtr<TextureClientBuffer> clientBuffer (new TextureClientBuffer(gl));
const GLuint texture = clientBuffer->getName();
const GLenum target = getGLTarget();
RenderbufferImageSource (GLenum format) : m_format(format) {}
string getRequiredExtension (void) const { return "EGL_KHR_gl_renderbuffer_image"; }
- MovePtr<ClientBuffer> createBuffer (const glw::Functions& gl, Texture2D* reference) const;
+ MovePtr<ClientBuffer> createBuffer (const eglw::Library& egl, const glw::Functions& gl, Texture2D* reference) const;
GLenum getEffectiveFormat (void) const { return m_format; }
protected:
GL_RENDERBUFFER, 0));
}
-MovePtr<ClientBuffer> RenderbufferImageSource::createBuffer (const glw::Functions& gl, Texture2D* ref) const
+MovePtr<ClientBuffer> RenderbufferImageSource::createBuffer (const eglw::Library& egl, const glw::Functions& gl, Texture2D* ref) const
{
+ DE_UNREF(egl);
+
MovePtr<RenderbufferClientBuffer> buffer (new RenderbufferClientBuffer(gl));
const GLuint rbo = buffer->getName();
public:
UnsupportedImageSource (const string& message, GLenum format) : m_message(message), m_format(format) {}
string getRequiredExtension (void) const { fail(); return ""; }
- MovePtr<ClientBuffer> createBuffer (const glw::Functions&, tcu::Texture2D*) const { fail(); return de::MovePtr<ClientBuffer>(); }
+ MovePtr<ClientBuffer> createBuffer (const eglw::Library& egl, const glw::Functions&, tcu::Texture2D*) const { DE_UNREF(egl); fail(); return de::MovePtr<ClientBuffer>(); }
EGLImageKHR createImage (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
GLenum getEffectiveFormat (void) const { return m_format; }
public:
virtual ~ImageSource (void) {}
virtual std::string getRequiredExtension(void) const = 0;
- virtual de::MovePtr<ClientBuffer> createBuffer (const glw::Functions& gl, tcu::Texture2D* reference = DE_NULL) const = 0;
+ virtual de::MovePtr<ClientBuffer> createBuffer (const eglw::Library& egl, const glw::Functions& gl, tcu::Texture2D* reference = DE_NULL) const = 0;
virtual eglw::EGLImageKHR createImage (const eglw::Library& egl, eglw::EGLDisplay dpy, eglw::EGLContext ctx, eglw::EGLClientBuffer clientBuffer) const = 0;
virtual glw::GLenum getEffectiveFormat (void) const = 0;
};