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) : type(MESSAGETYPE_LAST) 68 { 69 } 70 Messagetcu::Android::Message71 explicit Message(MessageType type_) : type(type_) 72 { 73 DE_ASSERT(type_ == MESSAGE_RESUME || type_ == MESSAGE_PAUSE || type_ == MESSAGE_FINISH); 74 } 75 Messagetcu::Android::Message76 Message(MessageType type_, ANativeWindow *window) : type(type_) 77 { 78 DE_ASSERT(type_ == MESSAGE_WINDOW_CREATED || type_ == MESSAGE_WINDOW_DESTROYED || 79 type_ == MESSAGE_WINDOW_RESIZED); 80 DE_ASSERT(window); 81 payload.window = window; 82 } 83 Messagetcu::Android::Message84 Message(MessageType type_, AInputQueue *inputQueue) : type(type_) 85 { 86 DE_ASSERT(type_ == MESSAGE_INPUT_QUEUE_CREATED || type_ == MESSAGE_INPUT_QUEUE_DESTROYED); 87 DE_ASSERT(inputQueue); 88 payload.inputQueue = inputQueue; 89 } 90 Messagetcu::Android::Message91 Message(MessageType type_, de::Semaphore *semaphore) : type(type_) 92 { 93 DE_ASSERT(type_ == MESSAGE_SYNC); 94 DE_ASSERT(semaphore); 95 payload.semaphore = semaphore; 96 } 97 }; 98 99 enum WindowState 100 { 101 WINDOWSTATE_NOT_CREATED = 0, //!< Framework hasn't signaled window creation. 102 WINDOWSTATE_NOT_INITIALIZED, //!< Framework hasn't signaled first resize after creation and thus size is not final. 103 WINDOWSTATE_READY, //!< Window is ready for use. 104 WINDOWSTATE_DESTROYED, //!< Window has been destroyed. 105 106 WINDOWSTATE_LAST 107 }; 108 109 typedef de::ThreadSafeRingBuffer<Message> MessageQueue; 110 111 class RenderThread : private de::Thread 112 { 113 public: 114 RenderThread(NativeActivity &activity); 115 ~RenderThread(void); 116 117 void start(void); 118 void resume(void); 119 void pause(void); 120 void stop(void); 121 122 void enqueue(const Message &message); 123 void sync(void); 124 125 void run(void); 126 127 protected: onInputEvent(AInputEvent * event)128 virtual void onInputEvent(AInputEvent *event) 129 { 130 DE_UNREF(event); 131 } 132 virtual void onWindowCreated(ANativeWindow *window) = 0; 133 virtual void onWindowResized(ANativeWindow *window) = 0; 134 virtual void onWindowDestroyed(ANativeWindow *window) = 0; 135 virtual bool render(void) = 0; 136 getNativeActivity(void)137 NativeActivity &getNativeActivity(void) 138 { 139 return m_activity; 140 } 141 142 private: 143 void processMessage(const Message &message); 144 145 // Shared state. 146 NativeActivity &m_activity; 147 MessageQueue m_msgQueue; 148 149 // Parent thread state. 150 bool m_threadRunning; 151 152 // Thread state. 153 AInputQueue *m_inputQueue; 154 WindowState m_windowState; 155 ANativeWindow *m_window; 156 bool m_paused; //!< Is rendering paused? 157 bool m_finish; //!< Has thread received FINISH message? 158 bool m_receivedFirstResize; //!< Has the first onWindowResized been processed? 159 }; 160 161 class RenderActivity : public NativeActivity 162 { 163 public: 164 RenderActivity(ANativeActivity *activity); 165 virtual ~RenderActivity(void); 166 167 virtual void onStart(void); 168 virtual void onResume(void); 169 virtual void onPause(void); 170 virtual void onStop(void); 171 virtual void onDestroy(void); 172 173 virtual void onNativeWindowCreated(ANativeWindow *window); 174 virtual void onNativeWindowResized(ANativeWindow *window); 175 virtual void onNativeWindowRedrawNeeded(ANativeWindow *window); 176 virtual void onNativeWindowDestroyed(ANativeWindow *window); 177 178 virtual void onInputQueueCreated(AInputQueue *queue); 179 virtual void onInputQueueDestroyed(AInputQueue *queue); 180 181 protected: 182 //! Set rendering thread. Must be called at construction time. 183 void setThread(RenderThread *thread); 184 185 private: 186 RenderActivity(const RenderActivity &other); 187 RenderActivity &operator=(const RenderActivity &other); 188 189 RenderThread *m_thread; 190 }; 191 192 } // namespace Android 193 } // namespace tcu 194 195 #endif // _TCUANDROIDRENDERACTIVITY_HPP 196