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 37 namespace deqp 38 { 39 namespace egl 40 { 41 namespace Image 42 { 43 using std::string; 44 using de::MovePtr; 45 using tcu::PixelBufferAccess; 46 using tcu::TextureFormat; 47 using tcu::Texture2D; 48 using eglu::AttribMap; 49 using namespace glw; 50 using namespace eglw; 51 52 #if (DE_OS != DE_OS_ANDROID) 53 54 MovePtr<ImageSource> createAndroidNativeImageSource (GLenum format) 55 { 56 return createUnsupportedImageSource("Not Android platform", format); 57 } 58 59 #else // DE_OS == DE_OS_ANDROID 60 61 using tcu::Android::internal::LibUI; 62 using tcu::Android::internal::GraphicBuffer; 63 using tcu::Android::internal::PixelFormat; 64 using tcu::Android::internal::status_t; 65 66 PixelFormat 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 79 class AndroidNativeClientBuffer : public ClientBuffer 80 { 81 public: 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 86 private: 87 GraphicBuffer m_graphicBuffer; 88 ANativeWindowBuffer* m_windowBuffer; 89 }; 90 91 AndroidNativeClientBuffer::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 101 class AndroidNativeImageSource : public ImageSource 102 { 103 public: 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 111 protected: 112 GLenum m_format; 113 114 const LibUI& getLibUI (void) const; 115 116 private: 117 mutable LibUI* m_libui; 118 }; 119 120 AndroidNativeImageSource::~AndroidNativeImageSource (void) 121 { 122 delete m_libui; 123 } 124 125 const LibUI& AndroidNativeImageSource::getLibUI (void) const 126 { 127 if (!m_libui) 128 m_libui = new LibUI(); 129 130 return *m_libui; 131 } 132 133 void 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 139 MovePtr<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 163 EGLImageKHR 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 172 MovePtr<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