Home | History | Annotate | Download | only in egl
      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