1 #ifndef _TCUANDROIDRENDERACTIVITY_HPP 2 #define _TCUANDROIDRENDERACTIVITY_HPP 3 /*------------------------------------------------------------------------- 4 * drawElements Quality Program Tester Core 5 * ---------------------------------------- 6 * 7 * Copyright 2014 The Android Open Source Project 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief RenderActivity base class. 24 *//*--------------------------------------------------------------------*/ 25 26 #include "tcuDefs.hpp" 27 #include "tcuAndroidNativeActivity.hpp" 28 #include "deThread.hpp" 29 #include "deThreadSafeRingBuffer.hpp" 30 31 namespace tcu 32 { 33 namespace Android 34 { 35 36 enum MessageType 37 { 38 // Execution control messages. No data argument. 39 MESSAGE_RESUME = 0, 40 MESSAGE_PAUSE, 41 MESSAGE_FINISH, 42 43 // Window messages. Argument is ANativeWindow pointer. 44 MESSAGE_WINDOW_CREATED, 45 MESSAGE_WINDOW_RESIZED, 46 MESSAGE_WINDOW_DESTROYED, 47 48 // Input queue messages. Argument is AInputQueue pointer. 49 MESSAGE_INPUT_QUEUE_CREATED, 50 MESSAGE_INPUT_QUEUE_DESTROYED, 51 52 MESSAGE_SYNC, //!< Main thread requests sync. Data argument is de::Semaphore* that needs to be incremented. 53 54 MESSAGETYPE_LAST 55 }; 56 57 struct Message 58 { 59 MessageType type; //!< Message type. 60 union 61 { 62 ANativeWindow* window; 63 AInputQueue* inputQueue; 64 de::Semaphore* semaphore; 65 } payload; //!< Optional data argument. 66 Messagetcu::Android::Message67 Message (void) 68 : type(MESSAGETYPE_LAST) 69 { 70 } 71 Messagetcu::Android::Message72 explicit Message (MessageType type_) 73 : type(type_) 74 { 75 DE_ASSERT(type_ == MESSAGE_RESUME || 76 type_ == MESSAGE_PAUSE || 77 type_ == MESSAGE_FINISH); 78 } 79 Messagetcu::Android::Message80 Message (MessageType type_, ANativeWindow* window) 81 : type(type_) 82 { 83 DE_ASSERT(type_ == MESSAGE_WINDOW_CREATED || 84 type_ == MESSAGE_WINDOW_DESTROYED || 85 type_ == MESSAGE_WINDOW_RESIZED); 86 DE_ASSERT(window); 87 payload.window = window; 88 } 89 Messagetcu::Android::Message90 Message (MessageType type_, AInputQueue* inputQueue) 91 : type(type_) 92 { 93 DE_ASSERT(type_ == MESSAGE_INPUT_QUEUE_CREATED || 94 type_ == MESSAGE_INPUT_QUEUE_DESTROYED); 95 DE_ASSERT(inputQueue); 96 payload.inputQueue = inputQueue; 97 } 98 Messagetcu::Android::Message99 Message (MessageType type_, de::Semaphore* semaphore) 100 : type(type_) 101 { 102 DE_ASSERT(type_ == MESSAGE_SYNC); 103 DE_ASSERT(semaphore); 104 payload.semaphore = semaphore; 105 } 106 }; 107 108 enum WindowState 109 { 110 WINDOWSTATE_NOT_CREATED = 0, //!< Framework hasn't signaled window creation. 111 WINDOWSTATE_NOT_INITIALIZED, //!< Framework hasn't signaled first resize after creation and thus size is not final. 112 WINDOWSTATE_READY, //!< Window is ready for use. 113 WINDOWSTATE_DESTROYED, //!< Window has been destroyed. 114 115 WINDOWSTATE_LAST 116 }; 117 118 typedef de::ThreadSafeRingBuffer<Message> MessageQueue; 119 120 class RenderThread : private de::Thread 121 { 122 public: 123 RenderThread (NativeActivity& activity); 124 ~RenderThread (void); 125 126 void start (void); 127 void resume (void); 128 void pause (void); 129 void stop (void); 130 131 void enqueue (const Message& message); 132 void sync (void); 133 134 void run (void); 135 136 protected: onInputEvent(AInputEvent * event)137 virtual void onInputEvent (AInputEvent* event) { DE_UNREF(event); } 138 virtual void onWindowCreated (ANativeWindow* window) = 0; 139 virtual void onWindowResized (ANativeWindow* window) = 0; 140 virtual void onWindowDestroyed (ANativeWindow* window) = 0; 141 virtual bool render (void) = 0; 142 getNativeActivity(void)143 NativeActivity& getNativeActivity (void) { return m_activity; } 144 145 private: 146 void processMessage (const Message& message); 147 148 // Shared state. 149 NativeActivity& m_activity; 150 MessageQueue m_msgQueue; 151 152 // Parent thread state. 153 bool m_threadRunning; 154 155 // Thread state. 156 AInputQueue* m_inputQueue; 157 WindowState m_windowState; 158 ANativeWindow* m_window; 159 bool m_paused; //!< Is rendering paused? 160 bool m_finish; //!< Has thread received FINISH message? 161 bool m_receivedFirstResize; //!< Has the first onWindowResized been processed? 162 }; 163 164 class RenderActivity : public NativeActivity 165 { 166 public: 167 RenderActivity (ANativeActivity* activity); 168 virtual ~RenderActivity (void); 169 170 virtual void onStart (void); 171 virtual void onResume (void); 172 virtual void onPause (void); 173 virtual void onStop (void); 174 virtual void onDestroy (void); 175 176 virtual void onNativeWindowCreated (ANativeWindow* window); 177 virtual void onNativeWindowResized (ANativeWindow* window); 178 virtual void onNativeWindowRedrawNeeded (ANativeWindow* window); 179 virtual void onNativeWindowDestroyed (ANativeWindow* window); 180 181 virtual void onInputQueueCreated (AInputQueue* queue); 182 virtual void onInputQueueDestroyed (AInputQueue* queue); 183 184 protected: 185 //! Set rendering thread. Must be called at construction time. 186 void setThread (RenderThread* thread); 187 188 private: 189 RenderActivity (const RenderActivity& other); 190 RenderActivity& operator= (const RenderActivity& other); 191 192 RenderThread* m_thread; 193 }; 194 195 } // Android 196 } // tcu 197 198 #endif // _TCUANDROIDRENDERACTIVITY_HPP 199