Add tests for EGL_ANDROID_image_native_buffer.
authorMika Isojärvi <misojarvi@google.com>
Wed, 29 Oct 2014 13:59:31 +0000 (15:59 +0200)
committerMika Isojärvi <misojarvi@google.com>
Tue, 18 Nov 2014 14:01:38 +0000 (16:01 +0200)
Add tests and required utilities for EGL_ANDROID_image_native_buffer.

Change-Id: I0763f49d09806118ddc21d905c3223a6978dcc5b

12 files changed:
CMakeLists.txt
framework/egl/egluHeaderWrapper.hpp
framework/platform/CMakeLists.txt
framework/platform/android/tcuAndroidInternals.cpp [new file with mode: 0644]
framework/platform/android/tcuAndroidInternals.hpp [new file with mode: 0644]
modules/egl/CMakeLists.txt
modules/egl/teglAndroidUtil.cpp [new file with mode: 0644]
modules/egl/teglAndroidUtil.hpp [new file with mode: 0644]
modules/egl/teglImageFormatTests.cpp
modules/egl/teglImageTests.cpp
modules/egl/teglImageUtil.cpp
modules/egl/teglImageUtil.hpp

index 02cb573..5265aed 100644 (file)
@@ -316,8 +316,6 @@ add_subdirectory(modules)
 
 # Single-binary targets
 if (DE_OS_IS_ANDROID)
-       # CTS activities require headers from Android port directory
-       include_directories(framework/platform/android)
        include_directories(executor)
 
        add_library(deqp SHARED framework/platform/android/tcuAndroidMain.cpp framework/platform/android/tcuAndroidJNI.cpp framework/platform/android/tcuTestLogParserJNI.cpp ${DEQP_MODULE_ENTRY_POINTS})
index cdb8b89..c5cea9d 100644 (file)
        #define EGL_OPENGL_ES3_BIT_KHR                                                          0x00000040
 #endif // EGL_KHR_create_context
 
+#if !defined(EGL_ANDROID_image_native_buffer)
+#define EGL_ANDROID_image_native_buffer 1
+struct ANativeWindowBuffer;
+#define EGL_NATIVE_BUFFER_ANDROID                                                              0x3140
+#endif
+
 #endif // _EGLUHEADERWRAPPER_HPP
index 109758d..36275db 100644 (file)
@@ -58,6 +58,8 @@ if (NOT DEFINED TCUTIL_PLATFORM_SRCS)
                                ${TCUTIL_PLATFORM_SRCS}
                                android/tcuAndroidAssets.cpp
                                android/tcuAndroidAssets.hpp
+                               android/tcuAndroidInternals.cpp
+                               android/tcuAndroidInternals.hpp
                                android/tcuAndroidNativeActivity.cpp
                                android/tcuAndroidNativeActivity.hpp
                                android/tcuAndroidPlatform.cpp
diff --git a/framework/platform/android/tcuAndroidInternals.cpp b/framework/platform/android/tcuAndroidInternals.cpp
new file mode 100644 (file)
index 0000000..d825b85
--- /dev/null
@@ -0,0 +1,87 @@
+/*-------------------------------------------------------------------------
+ * 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"
+
+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");
+}
+
+#define GRAPHICBUFFER_SIZE 1024 // Hopefully enough
+
+GraphicBuffer::GraphicBuffer (const LibUI& lib, deUint32 width, deUint32 height, PixelFormat format, deUint32 usage)
+       : m_functions   (lib.getFunctions().graphicBuffer)
+       , m_memory              (GRAPHICBUFFER_SIZE) // vector<char> (new char[]) is max-aligned
+       , m_impl                (m_functions.constructor(&m_memory.front(), width, height, format, usage))
+{
+}
+
+GraphicBuffer::~GraphicBuffer (void)
+{
+       m_functions.destructor(m_impl);
+}
+
+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
diff --git a/framework/platform/android/tcuAndroidInternals.hpp b/framework/platform/android/tcuAndroidInternals.hpp
new file mode 100644 (file)
index 0000000..e6754c6
--- /dev/null
@@ -0,0 +1,177 @@
+#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;
+}
+
+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),
+       JPARKS_BROKE_IT         = -EPIPE,
+       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 android::GraphicBuffer* (*constructorFunc)              (void* memory, deUint32 w, deUint32 h, PixelFormat format, deUint32 usage);
+       typedef void*                                   (*destructorFunc)               (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);
+
+       constructorFunc                                 constructor;
+       destructorFunc                                  destructor;
+       lockFunc                                                lock;
+       unlockFunc                                              unlock;
+       getNativeBufferFunc                             getNativeBuffer;
+};
+
+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;
+       std::vector<deUint8>                    m_memory;
+       android::GraphicBuffer*                 m_impl;
+};
+
+} // internal
+} // Android
+} // tcu
+
+#endif // _TCUANDROIDINTERNALS_HPP
index 92e3dd7..37a06fd 100644 (file)
@@ -1,6 +1,8 @@
 # dEQP-EGL
 
 set(DEQP_EGL_SRCS
+       teglAndroidUtil.cpp
+       teglAndroidUtil.hpp
        teglApiCase.cpp
        teglApiCase.hpp
        teglChooseConfigReference.cpp
@@ -90,6 +92,11 @@ set(DEQP_EGL_LIBS
        ${DEQP_EGL_LIBRARIES}
        )
 
+if (DE_OS_IS_ANDROID)
+       # EGL tests require headers from Android port directory
+       include_directories(${CMAKE_SOURCE_DIR}/framework/platform/android)
+       set(DEQP_EGL_LIBS ${DEQP_EGL_LIBS} tcutil-platform)
+endif ()
 
 if (DEQP_SUPPORT_GLES2)
        set(DEQP_EGL_LIBS ${DEQP_EGL_LIBS} glutil glutil-sglr ${DEQP_GLES2_LIBRARIES})
diff --git a/modules/egl/teglAndroidUtil.cpp b/modules/egl/teglAndroidUtil.cpp
new file mode 100644 (file)
index 0000000..0518bfc
--- /dev/null
@@ -0,0 +1,166 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program EGL Module
+ * ---------------------------------------
+ *
+ * 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 Android-specific operations.
+ *//*--------------------------------------------------------------------*/
+
+#include "teglAndroidUtil.hpp"
+
+#include "deStringUtil.hpp"
+#include "tcuTextureUtil.hpp"
+#include "gluTextureUtil.hpp"
+#include "glwEnums.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;
+using tcu::TextureFormat;
+using tcu::Texture2D;
+using eglu::AttribMap;
+using namespace glw;
+
+#if (DE_OS != DE_OS_ANDROID)
+
+MovePtr<ImageSource> createAndroidNativeImageSource    (GLenum)
+{
+       return createUnsupportedImageSource("Not an android platform");
+}
+
+#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;
+
+PixelFormat 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");
+       }
+}
+
+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; }
+
+private:
+       GraphicBuffer                   m_graphicBuffer;
+       ANativeWindowBuffer*    m_windowBuffer;
+};
+
+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())
+{
+}
+
+class AndroidNativeImageSource : public ImageSource
+{
+public:
+                                                       AndroidNativeImageSource        (GLenum format) : m_format(format) {}
+       MovePtr<ClientBuffer>   createBuffer                            (const glw::Functions&, Texture2D*) const;
+       string                                  getRequiredExtension            (void) const { return "EGL_ANDROID_image_native_buffer"; }
+       EGLImageKHR                             createImage                                     (const eglu::ImageFunctions& imgExt, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
+
+protected:
+       GLenum                                  m_format;
+       LibUI                                   m_libui;
+};
+
+void checkStatus (status_t status)
+{
+       if (status != tcu::Android::internal::OK)
+               TCU_FAIL(("Android error: status code " + de::toString(status)).c_str());
+}
+
+MovePtr<ClientBuffer> AndroidNativeImageSource::createBuffer (const glw::Functions&, Texture2D* ref) const
+{
+       MovePtr<AndroidNativeClientBuffer>      buffer                  (new AndroidNativeClientBuffer(m_libui, m_format));
+       GraphicBuffer&                                          graphicBuffer   = buffer->getGraphicBuffer();
+       if (ref != DE_NULL)
+       {
+               const TextureFormat     texFormat       = glu::mapGLInternalFormat(m_format);
+               void*                           bufferData      = DE_NULL;
+
+               *ref = Texture2D(texFormat, 64, 64);
+               ref->allocLevel(0);
+               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));
+               {
+                       PixelBufferAccess nativeBuffer(texFormat, 64, 64, 1, bufferData);
+                       tcu::copy(nativeBuffer, ref->getLevel(0));
+               }
+               checkStatus(graphicBuffer.unlock());
+       }
+       return MovePtr<ClientBuffer>(buffer);
+}
+
+EGLImageKHR AndroidNativeImageSource::createImage (const eglu::ImageFunctions& imgExt, EGLDisplay dpy, EGLContext, EGLClientBuffer clientBuffer) const
+{
+       static const EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+       const EGLImageKHR       image           = imgExt.createImage(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attribs);
+
+       EGLU_CHECK_MSG("eglCreateImageKHR()");
+       return image;
+}
+
+MovePtr<ImageSource> createAndroidNativeImageSource    (GLenum format)
+{
+       try
+       {
+               return MovePtr<ImageSource>(new AndroidNativeImageSource(format));
+       }
+       catch (std::runtime_error& exc)
+       {
+               return createUnsupportedImageSource(string("Android native buffers unsupported: ") + exc.what());
+       }
+}
+
+#endif // DE_OS == DE_OS_ANDROID
+
+} // Image
+} // egl
+} // deqp
diff --git a/modules/egl/teglAndroidUtil.hpp b/modules/egl/teglAndroidUtil.hpp
new file mode 100644 (file)
index 0000000..5eb48ac
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _TEGLANDROIDUTIL_HPP
+#define _TEGLANDROIDUTIL_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program EGL Module
+ * ---------------------------------------
+ *
+ * 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 Android-specific operations.
+ *//*--------------------------------------------------------------------*/
+
+#include "teglImageUtil.hpp"
+
+namespace deqp
+{
+namespace egl
+{
+namespace Image
+{
+
+de::MovePtr<ImageSource> createAndroidNativeImageSource                (glw::GLenum format);
+
+} // Image
+} // egl
+} // deqp
+
+#endif // _TEGLANDROIDUTIL_HPP
index fb093fc..0f027d5 100644 (file)
@@ -50,6 +50,7 @@
 #include "glwFunctions.hpp"
 
 #include "teglImageUtil.hpp"
+#include "teglAndroidUtil.hpp"
 
 #include <vector>
 #include <string>
@@ -883,9 +884,11 @@ protected:
 
        void                    addCreateTexture                                (const string& name, EGLenum source, GLenum format, GLenum type);
        void                    addCreateRenderbuffer                   (const string& name, GLenum format);
+       void                    addCreateAndroidNative                  (const string& name, GLenum format);
        void                    addCreateTexture2DActions               (const string& prefix);
        void                    addCreateTextureCubemapActions  (const string& suffix, GLenum format, GLenum type);
        void                    addCreateRenderbufferActions    (void);
+       void                    addCreateAndroidNativeActions   (void);
 
        LabeledActions  m_createActions;
 };
@@ -900,6 +903,11 @@ void ImageTests::addCreateRenderbuffer (const string& name, GLenum format)
        m_createActions.add(name, MovePtr<Action>(new GLES2ImageApi::Create(createRenderbufferImageSource(format))));
 }
 
+void ImageTests::addCreateAndroidNative (const string& name, GLenum format)
+{
+       m_createActions.add(name, MovePtr<Action>(new GLES2ImageApi::Create(createAndroidNativeImageSource(format))));
+}
+
 void ImageTests::addCreateTexture2DActions (const string& prefix)
 {
        addCreateTexture(prefix + "rgb8",               EGL_GL_TEXTURE_2D_KHR,  GL_RGB,         GL_UNSIGNED_BYTE);
@@ -928,6 +936,15 @@ void ImageTests::addCreateRenderbufferActions (void)
        addCreateRenderbuffer("renderbuffer_stencil",   GL_STENCIL_INDEX8);
 }
 
+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_rgba8",          GL_RGBA8);
+}
+
 class RenderTests : public ImageTests
 {
 protected:
@@ -958,6 +975,7 @@ void SimpleCreationTests::init (void)
        addCreateTextureCubemapActions("_rgba", GL_RGBA, GL_UNSIGNED_BYTE);
        addCreateTextureCubemapActions("_rgb", GL_RGB, GL_UNSIGNED_BYTE);
        addCreateRenderbufferActions();
+       addCreateAndroidNativeActions();
        addRenderActions();
 
        for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
@@ -1003,6 +1021,7 @@ void MultiContextRenderTests::init (void)
        addCreateTextureCubemapActions("_rgba8", GL_RGBA, GL_UNSIGNED_BYTE);
        addCreateTextureCubemapActions("_rgb8", GL_RGB, GL_UNSIGNED_BYTE);
        addCreateRenderbufferActions();
+       addCreateAndroidNativeActions();
        addRenderActions();
 
        for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
@@ -1067,6 +1086,7 @@ void ModifyTests::init (void)
 {
        addCreateTexture2DActions("tex_");
        addCreateRenderbufferActions();
+       addCreateAndroidNativeActions();
        addModifyActions();
 
        for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
index 255cc9a..4c38d1f 100644 (file)
@@ -24,6 +24,7 @@
 #include "teglImageTests.hpp"
 
 #include "teglImageUtil.hpp"
+#include "teglAndroidUtil.hpp"
 #include "teglImageFormatTests.hpp"
 
 #include "egluExtensions.hpp"
@@ -272,6 +273,7 @@ public:
                        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:    return "cubemap_pos_z";
                        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:    return "cubemap_neg_z";
                        case EGL_GL_RENDERBUFFER_KHR:                                   return "renderbuffer";
+                       case EGL_NATIVE_BUFFER_ANDROID:                                 return "android_native";
                        default:                DE_ASSERT(DE_FALSE);                    return "";
                }
        }
@@ -286,6 +288,8 @@ public:
                        case GL_RGBA4:                          return "rgba4";
                        case GL_RGB5_A1:                        return "rgb5_a1";
                        case GL_RGB565:                         return "rgb565";
+                       case GL_RGB8:                           return "rgb8";
+                       case GL_RGBA8:                          return "rgba8";
                        case GL_STENCIL_INDEX8:         return "stencil_index8";
                        default:
                                DE_ASSERT(DE_FALSE);
@@ -307,6 +311,8 @@ public:
                                return createTextureImageSource(target, format, GL_UNSIGNED_BYTE);
                        case EGL_GL_RENDERBUFFER_KHR:
                                return createRenderbufferImageSource(format);
+                       case EGL_NATIVE_BUFFER_ANDROID:
+                               return createAndroidNativeImageSource(format);
                        default:
                                DE_ASSERT(!"Impossible");
                                return MovePtr<ImageSource>();
@@ -356,7 +362,6 @@ public:
 
 private:
        UniquePtr<ImageSource>  m_source;
-       bool                                    m_useTexLevel0;
 };
 
 class ImageTargetGLES2 : public ImageTestCase
@@ -494,6 +499,18 @@ public:
                for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(rboStorages); storageNdx++)
                        addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_RENDERBUFFER_KHR, rboStorages[storageNdx]));
 
+               static const GLenum androidFormats[] =
+               {
+                       GL_RGB565,
+                       GL_RGB8,
+                       GL_RGBA4,
+                       GL_RGB5_A1,
+                       GL_RGBA8,
+               };
+
+               for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(androidFormats); ++formatNdx)
+                       addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_NATIVE_BUFFER_ANDROID, androidFormats[formatNdx]));
+
                addChild(new Image::ImageTargetGLES2(m_eglTestCtx, GL_TEXTURE_2D));
                addChild(new Image::ImageTargetGLES2(m_eglTestCtx, GL_RENDERBUFFER));
        }
index 4a61ded..a44b294 100644 (file)
@@ -117,7 +117,15 @@ MovePtr<ManagedSurface> createSurface (EglTestContext& eglTestCtx, EGLConfig con
                TCU_FAIL("No valid surface types supported in config");
 }
 
-class TextureClientBuffer : public ClientBuffer
+class GLClientBuffer : public ClientBuffer
+{
+       EGLClientBuffer get             (void) const { return reinterpret_cast<EGLClientBuffer>(static_cast<deUintptr>(getName())); }
+
+protected:
+       virtual GLuint  getName (void) const = 0;
+};
+
+class TextureClientBuffer : public GLClientBuffer
 {
 public:
                                                TextureClientBuffer     (const glw::Functions& gl) : m_texture (gl) {}
@@ -127,24 +135,39 @@ private:
        glu::Texture            m_texture;
 };
 
-EGLImageKHR ImageSource::createImage    (const eglu::ImageFunctions& imgExt, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const
+class GLImageSource : public ImageSource
 {
-       const vector<EGLint>    attribs = eglu::attribMapToVector(getCreateAttribs());
-       const EGLImageKHR               image   = imgExt.createImage(dpy, ctx, getSource(), clientBuffer,
-                                                                                                                &attribs.front());
-       EGLU_CHECK_MSG("eglCreateImageKHR()");
+public:
+       EGLImageKHR                     createImage                     (const eglu::ImageFunctions& imgExt, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
 
-       return image;
+protected:
+       virtual AttribMap       getCreateAttribs        (void) const = 0;
+       virtual EGLenum         getSource                       (void) const = 0;
+};
+
+EGLImageKHR GLImageSource::createImage  (const eglu::ImageFunctions& imgExt, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const
+{
+       AttribMap                               attribMap       = getCreateAttribs();
+
+       attribMap[EGL_IMAGE_PRESERVED_KHR] = EGL_TRUE;
+
+       {
+               const vector<EGLint>    attribs = eglu::attribMapToVector(attribMap);
+               const EGLImageKHR               image   = imgExt.createImage(dpy, ctx, getSource(),
+                                                                                                                        clientBuffer, &attribs.front());
+               EGLU_CHECK_MSG("eglCreateImageKHR()");
+               return image;
+       }
 }
 
-class TextureImageSource : public ImageSource
+class TextureImageSource : public GLImageSource
 {
 public:
                                                        TextureImageSource      (GLenum format, GLenum type, bool useTexLevel0) : m_format(format), m_type(type), m_useTexLevel0(useTexLevel0) {}
-       AttribMap                               getCreateAttribs        (void) const;
        MovePtr<ClientBuffer>   createBuffer            (const glw::Functions& gl, Texture2D* reference) const;
 
 protected:
+       AttribMap                               getCreateAttribs        (void) const;
        virtual void                    initTexture                     (const glw::Functions& gl) const = 0;
        virtual GLenum                  getGLTarget                     (void) const = 0;
 
@@ -162,7 +185,6 @@ AttribMap TextureImageSource::getCreateAttribs (void) const
        return ret;
 }
 
-
 MovePtr<ClientBuffer> TextureImageSource::createBuffer (const glw::Functions& gl, Texture2D* ref) const
 {
        MovePtr<TextureClientBuffer>    clientBuffer    (new TextureClientBuffer(gl));
@@ -251,7 +273,7 @@ void TextureCubeMapImageSource::initTexture (const glw::Functions& gl) const
                GLU_CHECK_GLW_CALL(gl, texImage2D(faces[faceNdx], 0, m_format, IMAGE_WIDTH, IMAGE_HEIGHT, 0, m_format, m_type, DE_NULL));
 }
 
-class RenderbufferClientBuffer : public ClientBuffer
+class RenderbufferClientBuffer : public GLClientBuffer
 {
 public:
                                                RenderbufferClientBuffer        (const glw::Functions& gl) : m_rbo (gl) {}
@@ -261,17 +283,18 @@ private:
        glu::Renderbuffer       m_rbo;
 };
 
-class RenderbufferImageSource : public ImageSource
+class RenderbufferImageSource : public GLImageSource
 {
 public:
                                                        RenderbufferImageSource (GLenum format) : m_format(format) {}
 
-       EGLenum                                 getSource                               (void) const    { return EGL_GL_RENDERBUFFER_KHR; }
        string                                  getRequiredExtension    (void) const    { return "EGL_KHR_gl_renderbuffer_image"; }
-       AttribMap                               getCreateAttribs                (void) const    { return AttribMap(); }
        MovePtr<ClientBuffer>   createBuffer                    (const glw::Functions& gl, Texture2D* reference) const;
 
-private:
+protected:
+       EGLenum                                 getSource                               (void) const    { return EGL_GL_RENDERBUFFER_KHR; }
+       AttribMap                               getCreateAttribs                (void) const    { return AttribMap(); }
+
        GLenum                                  m_format;
 };
 
@@ -357,6 +380,26 @@ MovePtr<ClientBuffer> RenderbufferImageSource::createBuffer (const glw::Function
        return MovePtr<ClientBuffer>(buffer);
 }
 
+class UnsupportedImageSource : public ImageSource
+{
+public:
+                                                       UnsupportedImageSource  (const string& message) : m_message(message) {}
+       string                                  getRequiredExtension    (void) const { fail(); return ""; }
+       MovePtr<ClientBuffer>   createBuffer                    (const glw::Functions&, tcu::Texture2D*) const { fail(); return de::MovePtr<ClientBuffer>(); }
+       EGLImageKHR                             createImage                             (const eglu::ImageFunctions& imgExt, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
+
+private:
+       const string                    m_message;
+
+       void                                    fail                                    (void) const { TCU_THROW(NotSupportedError, m_message.c_str()); }
+};
+
+EGLImageKHR    UnsupportedImageSource::createImage (const eglu::ImageFunctions&, EGLDisplay, EGLContext, EGLClientBuffer) const
+{
+       fail();
+       return EGL_NO_IMAGE_KHR;
+}
+
 MovePtr<ImageSource> createTextureImageSource (EGLenum source, GLenum format, GLenum type, bool useTexLevel0)
 {
        if (source == EGL_GL_TEXTURE_2D_KHR)
@@ -370,6 +413,11 @@ MovePtr<ImageSource> createRenderbufferImageSource (GLenum format)
        return MovePtr<ImageSource>(new RenderbufferImageSource(format));
 }
 
+MovePtr<ImageSource> createUnsupportedImageSource (const string& message)
+{
+       return MovePtr<ImageSource>(new UnsupportedImageSource(message));
+}
+
 } // Image
 } // egl
 } // deqp
index 7788cfa..9d13c3e 100644 (file)
@@ -60,25 +60,21 @@ class ClientBuffer
 {
 public:
        virtual                                 ~ClientBuffer   (void) {}
-       EGLClientBuffer                 get                             (void) const { return reinterpret_cast<EGLClientBuffer>(static_cast<deUintptr>(getName())); }
-
-protected:
-       virtual glw::GLuint             getName                 (void) const = 0;
+       virtual EGLClientBuffer get                             (void) const = 0;
 };
 
 class ImageSource
 {
 public:
        virtual                                                         ~ImageSource            (void) {}
-       virtual EGLenum                                         getSource                       (void) const = 0;
-       virtual eglu::AttribMap                         getCreateAttribs        (void) const = 0;
        virtual std::string                                     getRequiredExtension(void) const = 0;
        virtual de::MovePtr<ClientBuffer>       createBuffer            (const glw::Functions& gl, tcu::Texture2D* reference = DE_NULL) const = 0;
-       EGLImageKHR                                                     createImage                     (const eglu::ImageFunctions& imgExt, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
+       virtual EGLImageKHR                                     createImage                     (const eglu::ImageFunctions& imgExt, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const = 0;
 };
 
 de::MovePtr<ImageSource> createTextureImageSource                      (EGLenum source, glw::GLenum format, glw::GLenum type, bool useTexLevel0 = false);
-de::MovePtr<ImageSource> createRenderbufferImageSource         (glw::GLenum storage);
+de::MovePtr<ImageSource> createRenderbufferImageSource         (glw::GLenum format);
+de::MovePtr<ImageSource> createUnsupportedImageSource          (const std::string& message);
 
 } // Image
 } // egl