xref: /aosp_15_r20/external/deqp/framework/platform/android/tcuAndroidWindow.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 window.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "tcuAndroidWindow.hpp"
25 
26 namespace tcu
27 {
28 namespace Android
29 {
30 
31 using std::vector;
32 
33 // Window
34 
Window(ANativeWindow * window)35 Window::Window(ANativeWindow *window) : m_window(window), m_state(STATE_AVAILABLE)
36 {
37 }
38 
~Window(void)39 Window::~Window(void)
40 {
41 }
42 
setBuffersGeometry(int width,int height,int32_t format)43 void Window::setBuffersGeometry(int width, int height, int32_t format)
44 {
45     ANativeWindow_setBuffersGeometry(m_window, width, height, format);
46 }
47 
getSize(void) const48 IVec2 Window::getSize(void) const
49 {
50     const int32_t width  = ANativeWindow_getWidth(m_window);
51     const int32_t height = ANativeWindow_getHeight(m_window);
52     return IVec2(width, height);
53 }
54 
tryAcquire(void)55 bool Window::tryAcquire(void)
56 {
57     de::ScopedLock lock(m_stateLock);
58 
59     if (m_state == STATE_AVAILABLE)
60     {
61         m_state = STATE_IN_USE;
62         return true;
63     }
64     else
65         return false;
66 }
67 
release(void)68 void Window::release(void)
69 {
70     de::ScopedLock lock(m_stateLock);
71 
72     if (m_state == STATE_IN_USE)
73     {
74         // Reset buffer size and format back to initial state
75         ANativeWindow_setBuffersGeometry(m_window, 0, 0, 0);
76 
77         m_state = STATE_AVAILABLE;
78     }
79     else if (m_state == STATE_PENDING_DESTROY)
80         m_state = STATE_READY_FOR_DESTROY;
81     else
82         DE_FATAL("Invalid window state");
83 }
84 
markForDestroy(void)85 void Window::markForDestroy(void)
86 {
87     de::ScopedLock lock(m_stateLock);
88 
89     if (m_state == STATE_AVAILABLE)
90         m_state = STATE_READY_FOR_DESTROY;
91     else if (m_state == STATE_IN_USE)
92         m_state = STATE_PENDING_DESTROY;
93     else
94         DE_FATAL("Invalid window state");
95 }
96 
isPendingDestroy(void) const97 bool Window::isPendingDestroy(void) const
98 {
99     de::ScopedLock lock(m_stateLock);
100     return m_state == STATE_PENDING_DESTROY;
101 }
102 
tryAcquireForDestroy(bool onlyMarked)103 bool Window::tryAcquireForDestroy(bool onlyMarked)
104 {
105     de::ScopedLock lock(m_stateLock);
106 
107     if (m_state == STATE_READY_FOR_DESTROY || (!onlyMarked && m_state == STATE_AVAILABLE))
108     {
109         m_state = STATE_ACQUIRED_FOR_DESTROY;
110         return true;
111     }
112     else
113         return false;
114 }
115 
116 // WindowRegistry
117 
WindowRegistry(void)118 WindowRegistry::WindowRegistry(void)
119 {
120 }
121 
~WindowRegistry(void)122 WindowRegistry::~WindowRegistry(void)
123 {
124     for (vector<Window *>::const_iterator winIter = m_windows.begin(); winIter != m_windows.end(); winIter++)
125     {
126         Window *const window = *winIter;
127 
128         if (window->tryAcquireForDestroy(false))
129             delete window;
130         else
131         {
132             print("ERROR: Window was not available for deletion, leaked tcu::Android::Window!\n");
133             DE_FATAL("Window leaked");
134         }
135     }
136 }
137 
addWindow(ANativeWindow * window)138 void WindowRegistry::addWindow(ANativeWindow *window)
139 {
140     m_windows.reserve(m_windows.size() + 1);
141     m_windows.push_back(new Window(window));
142 }
143 
destroyWindow(ANativeWindow * rawHandle)144 void WindowRegistry::destroyWindow(ANativeWindow *rawHandle)
145 {
146     for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
147     {
148         Window *const window = m_windows[ndx];
149 
150         if (window->getNativeWindow() == rawHandle)
151         {
152             if (window->tryAcquireForDestroy(false))
153             {
154                 delete window;
155                 m_windows[ndx] = m_windows.back();
156                 m_windows.pop_back();
157             }
158             else
159                 window->markForDestroy();
160 
161             return;
162         }
163     }
164 
165     throw tcu::InternalError("Window not registered", DE_NULL, __FILE__, __LINE__);
166 }
167 
tryAcquireWindow(void)168 Window *WindowRegistry::tryAcquireWindow(void)
169 {
170     for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
171     {
172         Window *const window = m_windows[ndx];
173 
174         if (window->tryAcquire())
175             return window;
176     }
177 
178     return DE_NULL;
179 }
180 
garbageCollect(void)181 void WindowRegistry::garbageCollect(void)
182 {
183     for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
184     {
185         Window *const window = m_windows[ndx];
186 
187         if (window->tryAcquireForDestroy(true))
188         {
189             delete window;
190             m_windows[ndx] = m_windows.back();
191             m_windows.pop_back();
192             ndx -= 1;
193         }
194     }
195 }
196 
197 } // namespace Android
198 } // namespace tcu
199