| /*------------------------------------------------------------------------- |
| * 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" |
| #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; |
| using tcu::TextureFormat; |
| using tcu::Texture2D; |
| using eglu::AttribMap; |
| using namespace glw; |
| using namespace eglw; |
| |
| #if (DE_OS != DE_OS_ANDROID) |
| |
| MovePtr<ImageSource> createAndroidNativeImageSource (GLenum format) |
| { |
| return createUnsupportedImageSource("Not Android platform", format); |
| } |
| |
| #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), m_libui(DE_NULL) {} |
| ~AndroidNativeImageSource (void); |
| MovePtr<ClientBuffer> createBuffer (const glw::Functions&, Texture2D*) const; |
| string getRequiredExtension (void) const { return "EGL_ANDROID_image_native_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) |
| { |
| 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(getLibUI(), 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 Library& egl, EGLDisplay dpy, EGLContext, EGLClientBuffer clientBuffer) const |
| { |
| 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; |
| } |
| |
| MovePtr<ImageSource> createAndroidNativeImageSource (GLenum format) |
| { |
| try |
| { |
| return MovePtr<ImageSource>(new AndroidNativeImageSource(format)); |
| } |
| catch (const std::runtime_error& exc) |
| { |
| return createUnsupportedImageSource(string("Android native buffers unsupported: ") + exc.what(), format); |
| } |
| } |
| |
| #endif // DE_OS == DE_OS_ANDROID |
| |
| } // Image |
| } // egl |
| } // deqp |