+bool Window::tryAcquire (void)
+{
+ de::ScopedLock lock(m_stateLock);
+
+ if (m_state == STATE_AVAILABLE)
+ {
+ m_state = STATE_IN_USE;
+ return true;
+ }
+ else
+ return false;
+}
+
+void Window::release (void)
+{
+ de::ScopedLock lock(m_stateLock);
+
+ if (m_state == STATE_IN_USE)
+ m_state = STATE_AVAILABLE;
+ else if (m_state == STATE_PENDING_DESTROY)
+ m_state = STATE_READY_FOR_DESTROY;
+ else
+ DE_ASSERT(!"Invalid window state");
+}
+
+void Window::markForDestroy (void)
+{
+ de::ScopedLock lock(m_stateLock);
+
+ if (m_state == STATE_AVAILABLE)
+ m_state = STATE_READY_FOR_DESTROY;
+ else if (m_state == STATE_IN_USE)
+ m_state = STATE_PENDING_DESTROY;
+ else
+ DE_ASSERT(!"Invalid window state");
+}
+
+bool Window::isPendingDestroy (void) const
+{
+ de::ScopedLock lock(m_stateLock);
+ return m_state == STATE_PENDING_DESTROY;
+}
+
+bool Window::tryAcquireForDestroy (bool onlyMarked)
+{
+ de::ScopedLock lock(m_stateLock);
+
+ if (m_state == STATE_READY_FOR_DESTROY ||
+ (!onlyMarked && m_state == STATE_AVAILABLE))
+ {
+ m_state = STATE_ACQUIRED_FOR_DESTROY;
+ return true;
+ }
+ else
+ return false;
+}
+
+// WindowRegistry
+
+WindowRegistry::WindowRegistry (void)
+{
+}
+
+WindowRegistry::~WindowRegistry (void)
+{
+ for (vector<Window*>::const_iterator winIter = m_windows.begin(); winIter != m_windows.end(); winIter++)
+ {
+ Window* const window = *winIter;
+
+ if (window->tryAcquireForDestroy(false))
+ delete window;
+ else
+ {
+ print("ERROR: Window was not available for deletion, leaked tcu::Android::Window!\n");
+ DE_ASSERT(!"Window leaked");
+ }
+ }
+}
+
+void WindowRegistry::addWindow (ANativeWindow* window)
+{
+ m_windows.reserve(m_windows.size()+1);
+ m_windows.push_back(new Window(window));
+}
+
+void WindowRegistry::destroyWindow (ANativeWindow* rawHandle)
+{
+ for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
+ {
+ Window* const window = m_windows[ndx];
+
+ if (window->getNativeWindow() == rawHandle)
+ {
+ if (window->tryAcquireForDestroy(false))
+ {
+ delete window;
+ m_windows[ndx] = m_windows.back();
+ m_windows.pop_back();
+ }
+ else
+ window->markForDestroy();
+
+ return;
+ }
+ }
+
+ throw tcu::InternalError("Window not registered", DE_NULL, __FILE__, __LINE__);
+}
+
+Window* WindowRegistry::tryAcquireWindow (void)
+{
+ for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
+ {
+ Window* const window = m_windows[ndx];
+
+ if (window->tryAcquire())
+ return window;
+ }
+
+ return DE_NULL;
+}
+
+void WindowRegistry::garbageCollect (void)
+{
+ for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
+ {
+ Window* const window = m_windows[ndx];
+
+ if (window->tryAcquireForDestroy(true))
+ {
+ delete window;
+ m_windows[ndx] = m_windows.back();
+ m_windows.pop_back();
+ ndx -= 1;
+ }
+ }
+}
+