1/*------------------------------------------------------------------------- 2 * drawElements Quality Program EGL Module 3 * --------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Android-specific operations. 22 *//*--------------------------------------------------------------------*/ 23 24#include "teglAndroidUtil.hpp" 25 26#include "deStringUtil.hpp" 27#include "tcuTextureUtil.hpp" 28#include "gluTextureUtil.hpp" 29#include "glwEnums.hpp" 30#include "eglwLibrary.hpp" 31#include "eglwEnums.hpp" 32 33#if (DE_OS == DE_OS_ANDROID) 34# include "tcuAndroidInternals.hpp" 35#endif 36 37namespace deqp 38{ 39namespace egl 40{ 41namespace Image 42{ 43using std::string; 44using de::MovePtr; 45using tcu::PixelBufferAccess; 46using tcu::TextureFormat; 47using tcu::Texture2D; 48using eglu::AttribMap; 49using namespace glw; 50using namespace eglw; 51 52#if (DE_OS != DE_OS_ANDROID) 53 54MovePtr<ImageSource> createAndroidNativeImageSource (GLenum format) 55{ 56 return createUnsupportedImageSource("Not Android platform", format); 57} 58 59#else // DE_OS == DE_OS_ANDROID 60 61using tcu::Android::internal::LibUI; 62using tcu::Android::internal::GraphicBuffer; 63using tcu::Android::internal::PixelFormat; 64using tcu::Android::internal::status_t; 65 66PixelFormat getPixelFormat (GLenum format) 67{ 68 switch (format) 69 { 70 case GL_RGB565: return tcu::Android::internal::PIXEL_FORMAT_RGB_565; 71 case GL_RGB8: return tcu::Android::internal::PIXEL_FORMAT_RGB_888; 72 case GL_RGBA4: return tcu::Android::internal::PIXEL_FORMAT_RGBA_4444; 73 case GL_RGB5_A1: return tcu::Android::internal::PIXEL_FORMAT_RGBA_5551; 74 case GL_RGBA8: return tcu::Android::internal::PIXEL_FORMAT_RGBA_8888; 75 default: TCU_THROW(NotSupportedError, "Texture format unsupported by Android"); 76 } 77} 78 79class AndroidNativeClientBuffer : public ClientBuffer 80{ 81public: 82 AndroidNativeClientBuffer (const LibUI& lib, GLenum format); 83 EGLClientBuffer get (void) const { return reinterpret_cast<EGLClientBuffer>(m_windowBuffer); } 84 GraphicBuffer& getGraphicBuffer (void) { return m_graphicBuffer; } 85 86private: 87 GraphicBuffer m_graphicBuffer; 88 ANativeWindowBuffer* m_windowBuffer; 89}; 90 91AndroidNativeClientBuffer::AndroidNativeClientBuffer (const LibUI& lib, GLenum format) 92 : m_graphicBuffer (lib, 64, 64, getPixelFormat(format), 93 GraphicBuffer::USAGE_SW_READ_OFTEN | 94 GraphicBuffer::USAGE_SW_WRITE_RARELY | 95 GraphicBuffer::USAGE_HW_TEXTURE | 96 GraphicBuffer::USAGE_HW_RENDER) 97 , m_windowBuffer (m_graphicBuffer.getNativeBuffer()) 98{ 99} 100 101class AndroidNativeImageSource : public ImageSource 102{ 103public: 104 AndroidNativeImageSource (GLenum format) : m_format(format), m_libui(DE_NULL) {} 105 ~AndroidNativeImageSource (void); 106 MovePtr<ClientBuffer> createBuffer (const glw::Functions&, Texture2D*) const; 107 string getRequiredExtension (void) const { return "EGL_ANDROID_image_native_buffer"; } 108 EGLImageKHR createImage (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const; 109 GLenum getEffectiveFormat (void) const { return m_format; } 110 111protected: 112 GLenum m_format; 113 114 const LibUI& getLibUI (void) const; 115 116private: 117 mutable LibUI* m_libui; 118}; 119 120AndroidNativeImageSource::~AndroidNativeImageSource (void) 121{ 122 delete m_libui; 123} 124 125const LibUI& AndroidNativeImageSource::getLibUI (void) const 126{ 127 if (!m_libui) 128 m_libui = new LibUI(); 129 130 return *m_libui; 131} 132 133void checkStatus (status_t status) 134{ 135 if (status != tcu::Android::internal::OK) 136 TCU_FAIL(("Android error: status code " + de::toString(status)).c_str()); 137} 138 139MovePtr<ClientBuffer> AndroidNativeImageSource::createBuffer (const glw::Functions&, Texture2D* ref) const 140{ 141 MovePtr<AndroidNativeClientBuffer> buffer (new AndroidNativeClientBuffer(getLibUI(), m_format)); 142 GraphicBuffer& graphicBuffer = buffer->getGraphicBuffer(); 143 if (ref != DE_NULL) 144 { 145 const TextureFormat texFormat = glu::mapGLInternalFormat(m_format); 146 void* bufferData = DE_NULL; 147 148 *ref = Texture2D(texFormat, 64, 64); 149 ref->allocLevel(0); 150 tcu::fillWithComponentGradients(ref->getLevel(0), 151 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), 152 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 153 checkStatus(graphicBuffer.lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, &bufferData)); 154 { 155 PixelBufferAccess nativeBuffer(texFormat, 64, 64, 1, bufferData); 156 tcu::copy(nativeBuffer, ref->getLevel(0)); 157 } 158 checkStatus(graphicBuffer.unlock()); 159 } 160 return MovePtr<ClientBuffer>(buffer); 161} 162 163EGLImageKHR AndroidNativeImageSource::createImage (const Library& egl, EGLDisplay dpy, EGLContext, EGLClientBuffer clientBuffer) const 164{ 165 static const EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; 166 const EGLImageKHR image = egl.createImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attribs); 167 168 EGLU_CHECK_MSG(egl, "eglCreateImageKHR()"); 169 return image; 170} 171 172MovePtr<ImageSource> createAndroidNativeImageSource (GLenum format) 173{ 174 try 175 { 176 return MovePtr<ImageSource>(new AndroidNativeImageSource(format)); 177 } 178 catch (const std::runtime_error& exc) 179 { 180 return createUnsupportedImageSource(string("Android native buffers unsupported: ") + exc.what(), format); 181 } 182} 183 184#endif // DE_OS == DE_OS_ANDROID 185 186} // Image 187} // egl 188} // deqp 189