bkaradzic 12 rokov pred
rodič
commit
767df6c5e6

+ 189 - 4
examples/common/entry_android.cpp

@@ -7,18 +7,193 @@
 
 #if BX_PLATFORM_ANDROID
 
+#include "entry_p.h"
+
 #include <stdio.h>
-#include "entry.h"
+#include <bx/thread.h>
+
+#include <android/input.h>
+#include <android/log.h>
+#include <android/looper.h>
+#include <android/window.h>
+#include <android_native_app_glue.h>
+extern "C"
+{
+#include <android_native_app_glue.c>
+} // extern "C"
+
+extern int _main_(int _argc, char** _argv);
 
 namespace entry
 {
+	struct MainThreadEntry
+	{
+		int m_argc;
+		char** m_argv;
+
+		static int32_t threadFunc(void* _userData);
+	};
+
+	struct Context
+	{
+		Context()
+		{
+		}
+
+		void run(android_app* _app)
+		{
+			m_app = _app;
+			m_app->userData = (void*)this;
+			m_app->onAppCmd = onAppCmdCB;
+			m_app->onInputEvent = onInputEventCB;
+
+			bgfx::androidSetWindow(m_app->window);
+
+			const char* argv[1] = { "android.so" };
+			MainThreadEntry mte;
+			mte.m_argc = 1;
+			mte.m_argv = const_cast<char**>(argv);
+
+			bx::Thread thread;
+			thread.init(mte.threadFunc, &mte);
+
+			while (0 == m_app->destroyRequested)
+			{
+				int32_t num;
+				android_poll_source* source;
+				/*int32_t id =*/ ALooper_pollAll(-1, NULL, &num, (void**)&source);
+
+				if (NULL != source)
+				{
+					source->process(m_app, source);
+				}
+			}
+
+			thread.shutdown();
+		}
+
+		void onAppCmd(int32_t _cmd)
+		{
+			switch (_cmd)
+			{
+				case APP_CMD_INPUT_CHANGED:
+					// Command from main thread: the AInputQueue has changed.  Upon processing
+					// this command, android_app->inputQueue will be updated to the new queue
+					// (or NULL).
+					break;
+
+				case APP_CMD_INIT_WINDOW:
+					// Command from main thread: a new ANativeWindow is ready for use.  Upon
+					// receiving this command, android_app->window will contain the new window
+					// surface.
+					break;
+
+				case APP_CMD_TERM_WINDOW:
+					// Command from main thread: the existing ANativeWindow needs to be
+					// terminated.  Upon receiving this command, android_app->window still
+					// contains the existing window; after calling android_app_exec_cmd
+					// it will be set to NULL.
+					break;
+
+				case APP_CMD_WINDOW_RESIZED:
+					// Command from main thread: the current ANativeWindow has been resized.
+					// Please redraw with its new size.
+					break;
+
+				case APP_CMD_WINDOW_REDRAW_NEEDED:
+					// Command from main thread: the system needs that the current ANativeWindow
+					// be redrawn.  You should redraw the window before handing this to
+					// android_app_exec_cmd() in order to avoid transient drawing glitches.
+					break;
+
+				case APP_CMD_CONTENT_RECT_CHANGED:
+					// Command from main thread: the content area of the window has changed,
+					// such as from the soft input window being shown or hidden.  You can
+					// find the new content rect in android_app::contentRect.
+					break;
+
+				case APP_CMD_GAINED_FOCUS:
+					// Command from main thread: the app's activity window has gained
+					// input focus.
+					break;
+
+				case APP_CMD_LOST_FOCUS:
+					// Command from main thread: the app's activity window has lost
+					// input focus.
+					break;
+
+				case APP_CMD_CONFIG_CHANGED:
+					// Command from main thread: the current device configuration has changed.
+					break;
+
+				case APP_CMD_LOW_MEMORY:
+					// Command from main thread: the system is running low on memory.
+					// Try to reduce your memory use.
+					break;
+
+				case APP_CMD_START:
+					// Command from main thread: the app's activity has been started.
+					break;
+
+				case APP_CMD_RESUME:
+					// Command from main thread: the app's activity has been resumed.
+					break;
+
+				case APP_CMD_SAVE_STATE:
+					// Command from main thread: the app should generate a new saved state
+					// for itself, to restore from later if needed.  If you have saved state,
+					// allocate it with malloc and place it in android_app.savedState with
+					// the size in android_app.savedStateSize.  The will be freed for you
+					// later.
+					break;
+
+				case APP_CMD_PAUSE:
+					// Command from main thread: the app's activity has been paused.
+					break;
+
+				case APP_CMD_STOP:
+					// Command from main thread: the app's activity has been stopped.
+					break;
+
+				case APP_CMD_DESTROY:
+					// Command from main thread: the app's activity is being destroyed,
+					// and waiting for the app thread to clean up and exit before proceeding.
+					m_eventQueue.postExitEvent();
+					break;
+			}
+		}
+
+		int32_t onInputEvent(AInputEvent* _event)
+		{
+			return 0;
+		}
+
+		static void onAppCmdCB(struct android_app* _app, int32_t _cmd)
+		{
+			Context* self = (Context*)_app->userData;
+			self->onAppCmd(_cmd);
+		}
+
+		static int32_t onInputEventCB(struct android_app* _app, AInputEvent* _event)
+		{
+			Context* self = (Context*)_app->userData;
+			return self->onInputEvent(_event);
+		}
+
+		EventQueue m_eventQueue;
+		android_app* m_app;
+	};
+
+	static Context s_ctx;
+
 	const Event* poll()
 	{
-		return NULL;
+		return s_ctx.m_eventQueue.poll();
 	}
 
 	void release(const Event* _event)
 	{
+		s_ctx.m_eventQueue.release(_event);
 	}
 
 	void setWindowSize(uint32_t _width, uint32_t _height)
@@ -33,13 +208,23 @@ namespace entry
 	{
 	}
 
+	int32_t MainThreadEntry::threadFunc(void* _userData)
+	{
+		MainThreadEntry* self = (MainThreadEntry*)_userData;
+		int32_t result = _main_(self->m_argc, self->m_argv);
+//		PostMessage(s_ctx.m_hwnd, WM_QUIT, 0, 0);
+		return result;
+	}
+
 } // namespace entry
 
 extern int _main_(int _argc, char** _argv);
 
-int main(int _argc, char** _argv)
+extern "C" void android_main(android_app* _app)
 {
-	_main_(_argc, _argv);
+	using namespace entry;
+	app_dummy();
+	s_ctx.run(_app);
 }
 
 #endif // BX_PLATFORM_ANDROID

+ 2 - 2
examples/common/entry_windows.cpp

@@ -154,7 +154,7 @@ namespace entry
 			s_translateKey['Z']          = Key::KeyZ;
 		}
 
-		int32_t main(int _argc, char** _argv)
+		int32_t run(int _argc, char** _argv)
 		{
 			HINSTANCE instance = (HINSTANCE)GetModuleHandle(NULL);
 
@@ -636,7 +636,7 @@ namespace entry
 int main(int _argc, char** _argv)
 {
 	using namespace entry;
-	return s_ctx.main(_argc, _argv);
+	return s_ctx.run(_argc, _argv);
 }
 
 #endif // BX_PLATFORM_WINDOWS

+ 9 - 9
include/bgfxplatform.h

@@ -13,11 +13,11 @@
 #include <bx/bx.h>
 
 #if BX_PLATFORM_ANDROID
-struct android_app;
+#	include <android/native_window.h>
 
 namespace bgfx
 {
-	androidSetAndroidApp(struct android_app* _app);
+	void androidSetWindow(::ANativeWindow* _window);
 } // namespace bgfx
 
 #elif BX_PLATFORM_LINUX
@@ -38,21 +38,21 @@ namespace bgfx
 	void naclSetIntefraces(::PP_Instance, const ::PPB_Instance*, const ::PPB_Graphics3D*, PostSwapBuffersFn);
 } // namespace bgfx
 
-#elif BX_PLATFORM_WINDOWS
-#	include <windows.h>
+#elif BX_PLATFORM_OSX
+#	include <Cocoa/Cocoa.h>
+#	include <stdlib.h>
 
 namespace bgfx
 {
-	void winSetHwnd(::HWND _hwnd);
+	void osxSetNSWindow(void* _nsWindow);
 } // namespace bgfx
 
-#elif BX_PLATFORM_OSX
-#	include <Cocoa/Cocoa.h>
-#	include <stdlib.h>
+#elif BX_PLATFORM_WINDOWS
+#	include <windows.h>
 
 namespace bgfx
 {
-	void osxSetNSWindow(void* _nsWindow);
+	void winSetHwnd(::HWND _hwnd);
 } // namespace bgfx
 
 #endif // BX_PLATFORM_

+ 11 - 5
src/bgfx.cpp

@@ -33,12 +33,11 @@ namespace bgfx
 #	define BGFX_CHECK_RENDER_THREAD()
 #endif // BGFX_CONFIG_MULTITHREADED
 
-#if BX_PLATFORM_WINDOWS
-	HWND g_bgfxHwnd = NULL;
-
-	void winSetHwnd(::HWND _hwnd)
+#if BX_PLATFORM_ANDROID
+	::ANativeWindow* g_bgfxAndroidWindow = NULL;
+	void androidSetWindow(ANativeWindow* _window)
 	{
-		g_bgfxHwnd = _hwnd;
+		g_bgfxAndroidWindow = _window;
 	}
 #elif BX_PLATFORM_OSX
 	void* g_bgfxNSWindow = NULL;
@@ -47,6 +46,13 @@ namespace bgfx
 	{
 		g_bgfxNSWindow = _nsWindow;
 	}
+#elif BX_PLATFORM_WINDOWS
+	::HWND g_bgfxHwnd = NULL;
+
+	void winSetHwnd(::HWND _hwnd)
+	{
+		g_bgfxHwnd = _hwnd;
+	}
 #endif // BX_PLATFORM_*
 
 	struct CallbackStub : public CallbackI

+ 7 - 3
src/bgfx_p.h

@@ -100,7 +100,9 @@ namespace stl {
 #endif // BGFX_CONFIG_USE_TINYSTL
 #include <list>
 
-#if BX_PLATFORM_WINDOWS
+#if BX_PLATFORM_ANDROID
+#	include <android/native_window.h>
+#elif BX_PLATFORM_WINDOWS
 #	include <windows.h>
 #elif BX_PLATFORM_XBOX360
 #	include <malloc.h>
@@ -152,10 +154,12 @@ namespace stl {
 
 namespace bgfx
 {
-#if BX_PLATFORM_WINDOWS
-	extern HWND g_bgfxHwnd;
+#if BX_PLATFORM_ANDROID
+	extern ::ANativeWindow* g_bgfxAndroidWindow;
 #elif BX_PLATFORM_OSX
 	extern void* g_bgfxNSWindow;
+#elif BX_PLATFORM_WINDOWS
+	extern ::HWND g_bgfxHwnd;
 #endif // BX_PLATFORM_*
 
 	struct Clear

+ 7 - 0
src/glcontext_egl.cpp

@@ -50,6 +50,13 @@ namespace bgfx
 		success = eglChooseConfig(m_display, attrs, &config, 1, &numConfig);
 		BGFX_FATAL(success, Fatal::UnableToInitialize, "eglChooseConfig");
 
+#	if BX_PLATFORM_ANDROID
+		EGLint format;
+		eglGetConfigAttrib(m_display, config, EGL_NATIVE_VISUAL_ID, &format);
+		ANativeWindow_setBuffersGeometry(g_bgfxAndroidWindow, 0, 0, format);
+		nwt = g_bgfxAndroidWindow;
+#	endif // BX_PLATFORM_ANDROID
+
 		m_surface = eglCreateWindowSurface(m_display, config, nwt, NULL);
 		BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");