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