1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program Tester Core
3e5c31af7Sopenharmony_ci * ----------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Android window.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "tcuAndroidWindow.hpp"
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_cinamespace tcu
27e5c31af7Sopenharmony_ci{
28e5c31af7Sopenharmony_cinamespace Android
29e5c31af7Sopenharmony_ci{
30e5c31af7Sopenharmony_ci
31e5c31af7Sopenharmony_ciusing std::vector;
32e5c31af7Sopenharmony_ci
33e5c31af7Sopenharmony_ci// Window
34e5c31af7Sopenharmony_ci
35e5c31af7Sopenharmony_ciWindow::Window (ANativeWindow* window)
36e5c31af7Sopenharmony_ci	: m_window	(window)
37e5c31af7Sopenharmony_ci	, m_state	(STATE_AVAILABLE)
38e5c31af7Sopenharmony_ci{
39e5c31af7Sopenharmony_ci}
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_ciWindow::~Window (void)
42e5c31af7Sopenharmony_ci{
43e5c31af7Sopenharmony_ci}
44e5c31af7Sopenharmony_ci
45e5c31af7Sopenharmony_civoid Window::setBuffersGeometry (int width, int height, int32_t format)
46e5c31af7Sopenharmony_ci{
47e5c31af7Sopenharmony_ci	ANativeWindow_setBuffersGeometry(m_window, width, height, format);
48e5c31af7Sopenharmony_ci}
49e5c31af7Sopenharmony_ci
50e5c31af7Sopenharmony_ciIVec2 Window::getSize (void) const
51e5c31af7Sopenharmony_ci{
52e5c31af7Sopenharmony_ci	const int32_t	width	= ANativeWindow_getWidth(m_window);
53e5c31af7Sopenharmony_ci	const int32_t	height	= ANativeWindow_getHeight(m_window);
54e5c31af7Sopenharmony_ci	return IVec2(width, height);
55e5c31af7Sopenharmony_ci}
56e5c31af7Sopenharmony_ci
57e5c31af7Sopenharmony_cibool Window::tryAcquire (void)
58e5c31af7Sopenharmony_ci{
59e5c31af7Sopenharmony_ci	de::ScopedLock lock(m_stateLock);
60e5c31af7Sopenharmony_ci
61e5c31af7Sopenharmony_ci	if (m_state == STATE_AVAILABLE)
62e5c31af7Sopenharmony_ci	{
63e5c31af7Sopenharmony_ci		m_state = STATE_IN_USE;
64e5c31af7Sopenharmony_ci		return true;
65e5c31af7Sopenharmony_ci	}
66e5c31af7Sopenharmony_ci	else
67e5c31af7Sopenharmony_ci		return false;
68e5c31af7Sopenharmony_ci}
69e5c31af7Sopenharmony_ci
70e5c31af7Sopenharmony_civoid Window::release (void)
71e5c31af7Sopenharmony_ci{
72e5c31af7Sopenharmony_ci	de::ScopedLock lock(m_stateLock);
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ci	if (m_state == STATE_IN_USE)
75e5c31af7Sopenharmony_ci	{
76e5c31af7Sopenharmony_ci		// Reset buffer size and format back to initial state
77e5c31af7Sopenharmony_ci		ANativeWindow_setBuffersGeometry(m_window, 0, 0, 0);
78e5c31af7Sopenharmony_ci
79e5c31af7Sopenharmony_ci		m_state = STATE_AVAILABLE;
80e5c31af7Sopenharmony_ci	}
81e5c31af7Sopenharmony_ci	else if (m_state == STATE_PENDING_DESTROY)
82e5c31af7Sopenharmony_ci		m_state = STATE_READY_FOR_DESTROY;
83e5c31af7Sopenharmony_ci	else
84e5c31af7Sopenharmony_ci		DE_FATAL("Invalid window state");
85e5c31af7Sopenharmony_ci}
86e5c31af7Sopenharmony_ci
87e5c31af7Sopenharmony_civoid Window::markForDestroy (void)
88e5c31af7Sopenharmony_ci{
89e5c31af7Sopenharmony_ci	de::ScopedLock lock(m_stateLock);
90e5c31af7Sopenharmony_ci
91e5c31af7Sopenharmony_ci	if (m_state == STATE_AVAILABLE)
92e5c31af7Sopenharmony_ci		m_state = STATE_READY_FOR_DESTROY;
93e5c31af7Sopenharmony_ci	else if (m_state == STATE_IN_USE)
94e5c31af7Sopenharmony_ci		m_state = STATE_PENDING_DESTROY;
95e5c31af7Sopenharmony_ci	else
96e5c31af7Sopenharmony_ci		DE_FATAL("Invalid window state");
97e5c31af7Sopenharmony_ci}
98e5c31af7Sopenharmony_ci
99e5c31af7Sopenharmony_cibool Window::isPendingDestroy (void) const
100e5c31af7Sopenharmony_ci{
101e5c31af7Sopenharmony_ci	de::ScopedLock lock(m_stateLock);
102e5c31af7Sopenharmony_ci	return m_state == STATE_PENDING_DESTROY;
103e5c31af7Sopenharmony_ci}
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_cibool Window::tryAcquireForDestroy (bool onlyMarked)
106e5c31af7Sopenharmony_ci{
107e5c31af7Sopenharmony_ci	de::ScopedLock lock(m_stateLock);
108e5c31af7Sopenharmony_ci
109e5c31af7Sopenharmony_ci	if (m_state == STATE_READY_FOR_DESTROY ||
110e5c31af7Sopenharmony_ci		(!onlyMarked && m_state == STATE_AVAILABLE))
111e5c31af7Sopenharmony_ci	{
112e5c31af7Sopenharmony_ci		m_state = STATE_ACQUIRED_FOR_DESTROY;
113e5c31af7Sopenharmony_ci		return true;
114e5c31af7Sopenharmony_ci	}
115e5c31af7Sopenharmony_ci	else
116e5c31af7Sopenharmony_ci		return false;
117e5c31af7Sopenharmony_ci}
118e5c31af7Sopenharmony_ci
119e5c31af7Sopenharmony_ci// WindowRegistry
120e5c31af7Sopenharmony_ci
121e5c31af7Sopenharmony_ciWindowRegistry::WindowRegistry (void)
122e5c31af7Sopenharmony_ci{
123e5c31af7Sopenharmony_ci}
124e5c31af7Sopenharmony_ci
125e5c31af7Sopenharmony_ciWindowRegistry::~WindowRegistry (void)
126e5c31af7Sopenharmony_ci{
127e5c31af7Sopenharmony_ci	for (vector<Window*>::const_iterator winIter = m_windows.begin(); winIter != m_windows.end(); winIter++)
128e5c31af7Sopenharmony_ci	{
129e5c31af7Sopenharmony_ci		Window* const window = *winIter;
130e5c31af7Sopenharmony_ci
131e5c31af7Sopenharmony_ci		if (window->tryAcquireForDestroy(false))
132e5c31af7Sopenharmony_ci			delete window;
133e5c31af7Sopenharmony_ci		else
134e5c31af7Sopenharmony_ci		{
135e5c31af7Sopenharmony_ci			print("ERROR: Window was not available for deletion, leaked tcu::Android::Window!\n");
136e5c31af7Sopenharmony_ci			DE_FATAL("Window leaked");
137e5c31af7Sopenharmony_ci		}
138e5c31af7Sopenharmony_ci	}
139e5c31af7Sopenharmony_ci}
140e5c31af7Sopenharmony_ci
141e5c31af7Sopenharmony_civoid WindowRegistry::addWindow (ANativeWindow* window)
142e5c31af7Sopenharmony_ci{
143e5c31af7Sopenharmony_ci	m_windows.reserve(m_windows.size()+1);
144e5c31af7Sopenharmony_ci	m_windows.push_back(new Window(window));
145e5c31af7Sopenharmony_ci}
146e5c31af7Sopenharmony_ci
147e5c31af7Sopenharmony_civoid WindowRegistry::destroyWindow (ANativeWindow* rawHandle)
148e5c31af7Sopenharmony_ci{
149e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
150e5c31af7Sopenharmony_ci	{
151e5c31af7Sopenharmony_ci		Window* const window = m_windows[ndx];
152e5c31af7Sopenharmony_ci
153e5c31af7Sopenharmony_ci		if (window->getNativeWindow() == rawHandle)
154e5c31af7Sopenharmony_ci		{
155e5c31af7Sopenharmony_ci			if (window->tryAcquireForDestroy(false))
156e5c31af7Sopenharmony_ci			{
157e5c31af7Sopenharmony_ci				delete window;
158e5c31af7Sopenharmony_ci				m_windows[ndx] = m_windows.back();
159e5c31af7Sopenharmony_ci				m_windows.pop_back();
160e5c31af7Sopenharmony_ci			}
161e5c31af7Sopenharmony_ci			else
162e5c31af7Sopenharmony_ci				window->markForDestroy();
163e5c31af7Sopenharmony_ci
164e5c31af7Sopenharmony_ci			return;
165e5c31af7Sopenharmony_ci		}
166e5c31af7Sopenharmony_ci	}
167e5c31af7Sopenharmony_ci
168e5c31af7Sopenharmony_ci	throw tcu::InternalError("Window not registered", DE_NULL, __FILE__, __LINE__);
169e5c31af7Sopenharmony_ci}
170e5c31af7Sopenharmony_ci
171e5c31af7Sopenharmony_ciWindow* WindowRegistry::tryAcquireWindow (void)
172e5c31af7Sopenharmony_ci{
173e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
174e5c31af7Sopenharmony_ci	{
175e5c31af7Sopenharmony_ci		Window* const window = m_windows[ndx];
176e5c31af7Sopenharmony_ci
177e5c31af7Sopenharmony_ci		if (window->tryAcquire())
178e5c31af7Sopenharmony_ci			return window;
179e5c31af7Sopenharmony_ci	}
180e5c31af7Sopenharmony_ci
181e5c31af7Sopenharmony_ci	return DE_NULL;
182e5c31af7Sopenharmony_ci}
183e5c31af7Sopenharmony_ci
184e5c31af7Sopenharmony_civoid WindowRegistry::garbageCollect (void)
185e5c31af7Sopenharmony_ci{
186e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
187e5c31af7Sopenharmony_ci	{
188e5c31af7Sopenharmony_ci		Window* const window = m_windows[ndx];
189e5c31af7Sopenharmony_ci
190e5c31af7Sopenharmony_ci		if (window->tryAcquireForDestroy(true))
191e5c31af7Sopenharmony_ci		{
192e5c31af7Sopenharmony_ci			delete window;
193e5c31af7Sopenharmony_ci			m_windows[ndx] = m_windows.back();
194e5c31af7Sopenharmony_ci			m_windows.pop_back();
195e5c31af7Sopenharmony_ci			ndx -= 1;
196e5c31af7Sopenharmony_ci		}
197e5c31af7Sopenharmony_ci	}
198e5c31af7Sopenharmony_ci}
199e5c31af7Sopenharmony_ci
200e5c31af7Sopenharmony_ci} // Android
201e5c31af7Sopenharmony_ci} // tcu
202