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 
createAndroidNativeImageSource(GLenum format)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 
getPixelFormat(GLenum format)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);
get(void) const83 	EGLClientBuffer			get							(void) const { return reinterpret_cast<EGLClientBuffer>(m_windowBuffer); }
getGraphicBuffer(void)84 	GraphicBuffer&			getGraphicBuffer			(void) { return m_graphicBuffer; }
85 
86 private:
87 	GraphicBuffer			m_graphicBuffer;
88 	ANativeWindowBuffer*	m_windowBuffer;
89 };
90 
AndroidNativeClientBuffer(const LibUI & lib,GLenum format)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:
AndroidNativeImageSource(GLenum format)104 							AndroidNativeImageSource	(GLenum format) : m_format(format) {}
105 	MovePtr<ClientBuffer>	createBuffer 				(const glw::Functions&, Texture2D*) const;
getRequiredExtension(void) const106 	string					getRequiredExtension		(void) const { return "EGL_ANDROID_image_native_buffer"; }
107 	EGLImageKHR				createImage					(const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
getFormat(void) const108 	GLenum					getFormat					(void) const { return m_format; }
109 
110 protected:
111 	GLenum					m_format;
112 	LibUI					m_libui;
113 };
114 
checkStatus(status_t status)115 void checkStatus (status_t status)
116 {
117 	if (status != tcu::Android::internal::OK)
118 		TCU_FAIL(("Android error: status code " + de::toString(status)).c_str());
119 }
120 
createBuffer(const glw::Functions &,Texture2D * ref) const121 MovePtr<ClientBuffer> AndroidNativeImageSource::createBuffer (const glw::Functions&, Texture2D* ref) const
122 {
123 	MovePtr<AndroidNativeClientBuffer>	buffer			(new AndroidNativeClientBuffer(m_libui, m_format));
124 	GraphicBuffer&						graphicBuffer	= buffer->getGraphicBuffer();
125 	if (ref != DE_NULL)
126 	{
127 		const TextureFormat	texFormat	= glu::mapGLInternalFormat(m_format);
128 		void*				bufferData	= DE_NULL;
129 
130 		*ref = Texture2D(texFormat, 64, 64);
131 		ref->allocLevel(0);
132 		tcu::fillWithComponentGradients(ref->getLevel(0),
133 										tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
134 										tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
135 		checkStatus(graphicBuffer.lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, &bufferData));
136 		{
137 			PixelBufferAccess nativeBuffer(texFormat, 64, 64, 1, bufferData);
138 			tcu::copy(nativeBuffer, ref->getLevel(0));
139 		}
140 		checkStatus(graphicBuffer.unlock());
141 	}
142 	return MovePtr<ClientBuffer>(buffer);
143 }
144 
createImage(const Library & egl,EGLDisplay dpy,EGLContext,EGLClientBuffer clientBuffer) const145 EGLImageKHR AndroidNativeImageSource::createImage (const Library& egl, EGLDisplay dpy, EGLContext, EGLClientBuffer clientBuffer) const
146 {
147 	static const EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
148 	const EGLImageKHR	image 		= egl.createImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attribs);
149 
150 	EGLU_CHECK_MSG(egl, "eglCreateImageKHR()");
151 	return image;
152 }
153 
createAndroidNativeImageSource(GLenum format)154 MovePtr<ImageSource> createAndroidNativeImageSource	(GLenum format)
155 {
156 	try
157 	{
158 		return MovePtr<ImageSource>(new AndroidNativeImageSource(format));
159 	}
160 	catch (std::runtime_error& exc)
161 	{
162 		return createUnsupportedImageSource(string("Android native buffers unsupported: ") + exc.what(), format);
163 	}
164 }
165 
166 #endif // DE_OS == DE_OS_ANDROID
167 
168 } // Image
169 } // egl
170 } // deqp
171