1/*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
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 EGL platform.
22 *//*--------------------------------------------------------------------*/
23
24#include "tcuAndroidPlatform.hpp"
25#include "gluRenderContext.hpp"
26#include "egluNativeDisplay.hpp"
27#include "egluNativeWindow.hpp"
28#include "egluGLContextFactory.hpp"
29#include "egluUtil.hpp"
30
31namespace tcu
32{
33namespace Android
34{
35
36static const eglu::NativeDisplay::Capability	DISPLAY_CAPABILITIES	= eglu::NativeDisplay::CAPABILITY_GET_DISPLAY_LEGACY;
37static const eglu::NativeWindow::Capability		WINDOW_CAPABILITIES		= (eglu::NativeWindow::Capability)(eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY |
38																										   eglu::NativeWindow::CAPABILITY_SET_SURFACE_SIZE |
39																										   eglu::NativeWindow::CAPABILITY_GET_SCREEN_SIZE);
40
41class NativeDisplay : public eglu::NativeDisplay
42{
43public:
44									NativeDisplay			(void) : eglu::NativeDisplay(DISPLAY_CAPABILITIES) {}
45	virtual							~NativeDisplay			(void) {}
46
47	virtual EGLNativeDisplayType	getLegacyNative			(void) { return EGL_DEFAULT_DISPLAY; }
48};
49
50class NativeDisplayFactory : public eglu::NativeDisplayFactory
51{
52public:
53									NativeDisplayFactory	(WindowRegistry& windowRegistry);
54									~NativeDisplayFactory	(void) {}
55
56	virtual eglu::NativeDisplay*	createDisplay			(const EGLAttrib* attribList) const;
57};
58
59class NativeWindow : public eglu::NativeWindow
60{
61public:
62									NativeWindow			(Window* window, int width, int height, int32_t format);
63	virtual							~NativeWindow			(void);
64
65	virtual EGLNativeWindowType		getLegacyNative			(void)			{ return m_window->getNativeWindow();	}
66	IVec2							getScreenSize			(void) const	{ return m_window->getSize();			}
67
68	void							setSurfaceSize			(IVec2 size);
69
70	virtual void					processEvents			(void);
71
72private:
73	Window*							m_window;
74	int32_t							m_format;
75};
76
77class NativeWindowFactory : public eglu::NativeWindowFactory
78{
79public:
80									NativeWindowFactory		(WindowRegistry& windowRegistry);
81									~NativeWindowFactory	(void);
82
83	virtual eglu::NativeWindow*		createWindow			(eglu::NativeDisplay* nativeDisplay, const eglu::WindowParams& params) const;
84	virtual eglu::NativeWindow*		createWindow			(eglu::NativeDisplay* nativeDisplay, EGLDisplay display, EGLConfig config, const EGLAttrib* attribList, const eglu::WindowParams& params) const;
85
86private:
87	virtual eglu::NativeWindow*		createWindow			(const eglu::WindowParams& params, int32_t format) const;
88
89	WindowRegistry&					m_windowRegistry;
90};
91
92// NativeWindow
93
94NativeWindow::NativeWindow (Window* window, int width, int height, int32_t format)
95	: eglu::NativeWindow	(WINDOW_CAPABILITIES)
96	, m_window				(window)
97	, m_format				(format)
98{
99	// Set up buffers.
100	setSurfaceSize(IVec2(width, height));
101}
102
103NativeWindow::~NativeWindow (void)
104{
105	m_window->release();
106}
107
108void NativeWindow::processEvents (void)
109{
110	if (m_window->isPendingDestroy())
111		throw eglu::WindowDestroyedError("Window has been destroyed");
112}
113
114void NativeWindow::setSurfaceSize (tcu::IVec2 size)
115{
116	m_window->setBuffersGeometry(size.x() != eglu::WindowParams::SIZE_DONT_CARE ? size.x() : 0,
117								 size.y() != eglu::WindowParams::SIZE_DONT_CARE ? size.y() : 0,
118								 m_format);
119}
120
121// NativeWindowFactory
122
123NativeWindowFactory::NativeWindowFactory (WindowRegistry& windowRegistry)
124	: eglu::NativeWindowFactory	("default", "Default display", WINDOW_CAPABILITIES)
125	, m_windowRegistry			(windowRegistry)
126{
127}
128
129NativeWindowFactory::~NativeWindowFactory (void)
130{
131}
132
133eglu::NativeWindow* NativeWindowFactory::createWindow (eglu::NativeDisplay* nativeDisplay, const eglu::WindowParams& params) const
134{
135	DE_UNREF(nativeDisplay);
136	return createWindow(params, WINDOW_FORMAT_RGBA_8888);
137}
138
139eglu::NativeWindow* NativeWindowFactory::createWindow (eglu::NativeDisplay* nativeDisplay, EGLDisplay display, EGLConfig config, const EGLAttrib* attribList, const eglu::WindowParams& params) const
140{
141	const int32_t format = (int32_t)eglu::getConfigAttribInt(display, config, EGL_NATIVE_VISUAL_ID);
142	DE_UNREF(nativeDisplay && attribList);
143	return createWindow(params, format);
144}
145
146
147eglu::NativeWindow* NativeWindowFactory::createWindow (const eglu::WindowParams& params, int32_t format) const
148{
149	Window* window = m_windowRegistry.tryAcquireWindow();
150
151	if (!window)
152		throw ResourceError("Native window is not available", DE_NULL, __FILE__, __LINE__);
153
154	return new NativeWindow(window, params.width, params.height, format);
155}
156
157// NativeDisplayFactory
158
159NativeDisplayFactory::NativeDisplayFactory (WindowRegistry& windowRegistry)
160	: eglu::NativeDisplayFactory("default", "Default display", DISPLAY_CAPABILITIES)
161{
162	m_nativeWindowRegistry.registerFactory(new NativeWindowFactory(windowRegistry));
163}
164
165eglu::NativeDisplay* NativeDisplayFactory::createDisplay (const EGLAttrib* attribList) const
166{
167	DE_UNREF(attribList);
168	return new NativeDisplay();
169}
170
171// Platform
172
173Platform::Platform (void)
174{
175	m_nativeDisplayFactoryRegistry.registerFactory(new NativeDisplayFactory(m_windowRegistry));
176	m_contextFactoryRegistry.registerFactory(new eglu::GLContextFactory(m_nativeDisplayFactoryRegistry));
177}
178
179Platform::~Platform (void)
180{
181}
182
183bool Platform::processEvents (void)
184{
185	m_windowRegistry.garbageCollect();
186	return true;
187}
188
189} // Android
190} // tcu
191