mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-28 10:35:43 -05:00
Android plumbing.
This commit is contained in:
parent
247a3004ef
commit
767df6c5e6
6 changed files with 226 additions and 24 deletions
|
@ -7,18 +7,193 @@
|
||||||
|
|
||||||
#if BX_PLATFORM_ANDROID
|
#if BX_PLATFORM_ANDROID
|
||||||
|
|
||||||
|
#include "entry_p.h"
|
||||||
|
|
||||||
#include <stdio.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
|
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()
|
const Event* poll()
|
||||||
{
|
{
|
||||||
return NULL;
|
return s_ctx.m_eventQueue.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void release(const Event* _event)
|
void release(const Event* _event)
|
||||||
{
|
{
|
||||||
|
s_ctx.m_eventQueue.release(_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowSize(uint32_t _width, uint32_t _height)
|
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
|
} // namespace entry
|
||||||
|
|
||||||
extern int _main_(int _argc, char** _argv);
|
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
|
#endif // BX_PLATFORM_ANDROID
|
||||||
|
|
|
@ -154,7 +154,7 @@ namespace entry
|
||||||
s_translateKey['Z'] = Key::KeyZ;
|
s_translateKey['Z'] = Key::KeyZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t main(int _argc, char** _argv)
|
int32_t run(int _argc, char** _argv)
|
||||||
{
|
{
|
||||||
HINSTANCE instance = (HINSTANCE)GetModuleHandle(NULL);
|
HINSTANCE instance = (HINSTANCE)GetModuleHandle(NULL);
|
||||||
|
|
||||||
|
@ -636,7 +636,7 @@ namespace entry
|
||||||
int main(int _argc, char** _argv)
|
int main(int _argc, char** _argv)
|
||||||
{
|
{
|
||||||
using namespace entry;
|
using namespace entry;
|
||||||
return s_ctx.main(_argc, _argv);
|
return s_ctx.run(_argc, _argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BX_PLATFORM_WINDOWS
|
#endif // BX_PLATFORM_WINDOWS
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
#include <bx/bx.h>
|
#include <bx/bx.h>
|
||||||
|
|
||||||
#if BX_PLATFORM_ANDROID
|
#if BX_PLATFORM_ANDROID
|
||||||
struct android_app;
|
# include <android/native_window.h>
|
||||||
|
|
||||||
namespace bgfx
|
namespace bgfx
|
||||||
{
|
{
|
||||||
androidSetAndroidApp(struct android_app* _app);
|
void androidSetWindow(::ANativeWindow* _window);
|
||||||
} // namespace bgfx
|
} // namespace bgfx
|
||||||
|
|
||||||
#elif BX_PLATFORM_LINUX
|
#elif BX_PLATFORM_LINUX
|
||||||
|
@ -38,14 +38,6 @@ namespace bgfx
|
||||||
void naclSetIntefraces(::PP_Instance, const ::PPB_Instance*, const ::PPB_Graphics3D*, PostSwapBuffersFn);
|
void naclSetIntefraces(::PP_Instance, const ::PPB_Instance*, const ::PPB_Graphics3D*, PostSwapBuffersFn);
|
||||||
} // namespace bgfx
|
} // namespace bgfx
|
||||||
|
|
||||||
#elif BX_PLATFORM_WINDOWS
|
|
||||||
# include <windows.h>
|
|
||||||
|
|
||||||
namespace bgfx
|
|
||||||
{
|
|
||||||
void winSetHwnd(::HWND _hwnd);
|
|
||||||
} // namespace bgfx
|
|
||||||
|
|
||||||
#elif BX_PLATFORM_OSX
|
#elif BX_PLATFORM_OSX
|
||||||
# include <Cocoa/Cocoa.h>
|
# include <Cocoa/Cocoa.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
|
@ -55,6 +47,14 @@ namespace bgfx
|
||||||
void osxSetNSWindow(void* _nsWindow);
|
void osxSetNSWindow(void* _nsWindow);
|
||||||
} // namespace bgfx
|
} // namespace bgfx
|
||||||
|
|
||||||
|
#elif BX_PLATFORM_WINDOWS
|
||||||
|
# include <windows.h>
|
||||||
|
|
||||||
|
namespace bgfx
|
||||||
|
{
|
||||||
|
void winSetHwnd(::HWND _hwnd);
|
||||||
|
} // namespace bgfx
|
||||||
|
|
||||||
#endif // BX_PLATFORM_
|
#endif // BX_PLATFORM_
|
||||||
|
|
||||||
#endif // __BGFXPLATFORM_H__
|
#endif // __BGFXPLATFORM_H__
|
||||||
|
|
16
src/bgfx.cpp
16
src/bgfx.cpp
|
@ -33,12 +33,11 @@ namespace bgfx
|
||||||
# define BGFX_CHECK_RENDER_THREAD()
|
# define BGFX_CHECK_RENDER_THREAD()
|
||||||
#endif // BGFX_CONFIG_MULTITHREADED
|
#endif // BGFX_CONFIG_MULTITHREADED
|
||||||
|
|
||||||
#if BX_PLATFORM_WINDOWS
|
#if BX_PLATFORM_ANDROID
|
||||||
HWND g_bgfxHwnd = NULL;
|
::ANativeWindow* g_bgfxAndroidWindow = NULL;
|
||||||
|
void androidSetWindow(ANativeWindow* _window)
|
||||||
void winSetHwnd(::HWND _hwnd)
|
|
||||||
{
|
{
|
||||||
g_bgfxHwnd = _hwnd;
|
g_bgfxAndroidWindow = _window;
|
||||||
}
|
}
|
||||||
#elif BX_PLATFORM_OSX
|
#elif BX_PLATFORM_OSX
|
||||||
void* g_bgfxNSWindow = NULL;
|
void* g_bgfxNSWindow = NULL;
|
||||||
|
@ -47,6 +46,13 @@ namespace bgfx
|
||||||
{
|
{
|
||||||
g_bgfxNSWindow = _nsWindow;
|
g_bgfxNSWindow = _nsWindow;
|
||||||
}
|
}
|
||||||
|
#elif BX_PLATFORM_WINDOWS
|
||||||
|
::HWND g_bgfxHwnd = NULL;
|
||||||
|
|
||||||
|
void winSetHwnd(::HWND _hwnd)
|
||||||
|
{
|
||||||
|
g_bgfxHwnd = _hwnd;
|
||||||
|
}
|
||||||
#endif // BX_PLATFORM_*
|
#endif // BX_PLATFORM_*
|
||||||
|
|
||||||
struct CallbackStub : public CallbackI
|
struct CallbackStub : public CallbackI
|
||||||
|
|
10
src/bgfx_p.h
10
src/bgfx_p.h
|
@ -100,7 +100,9 @@ namespace stl {
|
||||||
#endif // BGFX_CONFIG_USE_TINYSTL
|
#endif // BGFX_CONFIG_USE_TINYSTL
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#if BX_PLATFORM_WINDOWS
|
#if BX_PLATFORM_ANDROID
|
||||||
|
# include <android/native_window.h>
|
||||||
|
#elif BX_PLATFORM_WINDOWS
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#elif BX_PLATFORM_XBOX360
|
#elif BX_PLATFORM_XBOX360
|
||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
|
@ -152,10 +154,12 @@ namespace stl {
|
||||||
|
|
||||||
namespace bgfx
|
namespace bgfx
|
||||||
{
|
{
|
||||||
#if BX_PLATFORM_WINDOWS
|
#if BX_PLATFORM_ANDROID
|
||||||
extern HWND g_bgfxHwnd;
|
extern ::ANativeWindow* g_bgfxAndroidWindow;
|
||||||
#elif BX_PLATFORM_OSX
|
#elif BX_PLATFORM_OSX
|
||||||
extern void* g_bgfxNSWindow;
|
extern void* g_bgfxNSWindow;
|
||||||
|
#elif BX_PLATFORM_WINDOWS
|
||||||
|
extern ::HWND g_bgfxHwnd;
|
||||||
#endif // BX_PLATFORM_*
|
#endif // BX_PLATFORM_*
|
||||||
|
|
||||||
struct Clear
|
struct Clear
|
||||||
|
|
|
@ -50,6 +50,13 @@ namespace bgfx
|
||||||
success = eglChooseConfig(m_display, attrs, &config, 1, &numConfig);
|
success = eglChooseConfig(m_display, attrs, &config, 1, &numConfig);
|
||||||
BGFX_FATAL(success, Fatal::UnableToInitialize, "eglChooseConfig");
|
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);
|
m_surface = eglCreateWindowSurface(m_display, config, nwt, NULL);
|
||||||
BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");
|
BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue