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