You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
4.2 KiB
201 lines
4.2 KiB
/*------------------------------------------------------------------------- |
|
* drawElements Quality Program Tester Core |
|
* ---------------------------------------- |
|
* |
|
* Copyright 2014 The Android Open Source Project |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
*//*! |
|
* \file |
|
* \brief Android window. |
|
*//*--------------------------------------------------------------------*/ |
|
|
|
#include "tcuAndroidWindow.hpp" |
|
|
|
namespace tcu |
|
{ |
|
namespace Android |
|
{ |
|
|
|
using std::vector; |
|
|
|
// Window |
|
|
|
Window::Window (ANativeWindow* window) |
|
: m_window (window) |
|
, m_state (STATE_AVAILABLE) |
|
{ |
|
} |
|
|
|
Window::~Window (void) |
|
{ |
|
} |
|
|
|
void Window::setBuffersGeometry (int width, int height, int32_t format) |
|
{ |
|
ANativeWindow_setBuffersGeometry(m_window, width, height, format); |
|
} |
|
|
|
IVec2 Window::getSize (void) const |
|
{ |
|
const int32_t width = ANativeWindow_getWidth(m_window); |
|
const int32_t height = ANativeWindow_getHeight(m_window); |
|
return IVec2(width, height); |
|
} |
|
|
|
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) |
|
{ |
|
// Reset buffer size and format back to initial state |
|
ANativeWindow_setBuffersGeometry(m_window, 0, 0, 0); |
|
|
|
m_state = STATE_AVAILABLE; |
|
} |
|
else if (m_state == STATE_PENDING_DESTROY) |
|
m_state = STATE_READY_FOR_DESTROY; |
|
else |
|
DE_FATAL("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_FATAL("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_FATAL("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; |
|
} |
|
} |
|
} |
|
|
|
} // Android |
|
} // tcu
|
|
|