diff options
Diffstat (limited to 'android/opengles.c')
-rw-r--r-- | android/opengles.c | 220 |
1 files changed, 171 insertions, 49 deletions
diff --git a/android/opengles.c b/android/opengles.c index f116f25..1fa6421 100644 --- a/android/opengles.c +++ b/android/opengles.c @@ -12,20 +12,28 @@ #include "config-host.h" #include "android/opengles.h" +#include <assert.h> + +/* Declared in "android/globals.h" */ +int android_gles_fast_pipes = 1; + +#if CONFIG_ANDROID_OPENGLES + #include "android/globals.h" #include <android/utils/debug.h> #include <android/utils/path.h> #include <android/utils/bufprint.h> #include <android/utils/dll.h> + +#define RENDER_API_NO_PROTOTYPES 1 +#include <libOpenglRender/render_api.h> + #include <stdio.h> #include <stdlib.h> #define D(...) VERBOSE_PRINT(init,__VA_ARGS__) #define DD(...) VERBOSE_PRINT(gles,__VA_ARGS__) -/* Declared in "android/globals.h" */ -int android_gles_fast_pipes = 1; - /* Name of the GLES rendering library we're going to use */ #if HOST_LONG_BITS == 32 #define RENDERER_LIB_NAME "libOpenglRender" @@ -35,22 +43,16 @@ int android_gles_fast_pipes = 1; #error Unknown HOST_LONG_BITS #endif -/* These definitions *must* match those under: - * development/tools/emulator/opengl/host/include/libOpenglRender/render_api.h - */ #define DYNLINK_FUNCTIONS \ - DYNLINK_FUNC(int,initLibrary,(void),(),return) \ - DYNLINK_FUNC(int,setStreamMode,(int a),(a),return) \ - DYNLINK_FUNC(int,initOpenGLRenderer,(int width, int height, int port, OnPostFn onPost, void* onPostContext),(width,height,port,onPost,onPostContext),return) \ - DYNLINK_FUNC(int,createOpenGLSubwindow,(void* window, int x, int y, int width, int height, float zRot),(window,x,y,width,height,zRot),return)\ - DYNLINK_FUNC(int,destroyOpenGLSubwindow,(void),(),return)\ - DYNLINK_FUNC(void,repaintOpenGLDisplay,(void),(),)\ - DYNLINK_FUNC(void,stopOpenGLRenderer,(void),(),) - -#define STREAM_MODE_DEFAULT 0 -#define STREAM_MODE_TCP 1 -#define STREAM_MODE_UNIX 2 -#define STREAM_MODE_PIPE 3 + DYNLINK_FUNC(initLibrary) \ + DYNLINK_FUNC(setStreamMode) \ + DYNLINK_FUNC(initOpenGLRenderer) \ + DYNLINK_FUNC(setPostCallback) \ + DYNLINK_FUNC(getHardwareStrings) \ + DYNLINK_FUNC(createOpenGLSubwindow) \ + DYNLINK_FUNC(destroyOpenGLSubwindow) \ + DYNLINK_FUNC(repaintOpenGLDisplay) \ + DYNLINK_FUNC(stopOpenGLRenderer) #ifndef CONFIG_STANDALONE_UI /* Defined in android/hw-pipe-net.c */ @@ -58,16 +60,13 @@ extern int android_init_opengles_pipes(void); #endif static ADynamicLibrary* rendererLib; +static int rendererStarted; +static char rendererAddress[256]; -/* Define the pointers and the wrapper functions to call them */ -#define DYNLINK_FUNC(result,name,sig,params,ret) \ - static result (*_ptr_##name) sig; \ - static result name sig { \ - ret (*_ptr_##name) params ; \ - } - +/* Define the function pointers */ +#define DYNLINK_FUNC(name) \ + static name##Fn name = NULL; DYNLINK_FUNCTIONS - #undef DYNLINK_FUNC static int @@ -75,10 +74,11 @@ initOpenglesEmulationFuncs(ADynamicLibrary* rendererLib) { void* symbol; char* error; -#define DYNLINK_FUNC(result,name,sig,params,ret) \ - symbol = adynamicLibrary_findSymbol( rendererLib, #name, &error ); \ + +#define DYNLINK_FUNC(name) \ + symbol = adynamicLibrary_findSymbol(rendererLib, #name, &error); \ if (symbol != NULL) { \ - _ptr_##name = symbol; \ + name = symbol; \ } else { \ derror("GLES emulation: Could not find required symbol (%s): %s", #name, error); \ free(error); \ @@ -86,6 +86,7 @@ initOpenglesEmulationFuncs(ADynamicLibrary* rendererLib) } DYNLINK_FUNCTIONS #undef DYNLINK_FUNC + return 0; } @@ -126,10 +127,10 @@ android_initOpenglesEmulation(void) /* XXX: NEED Win32 pipe implementation */ setStreamMode(STREAM_MODE_TCP); #else - setStreamMode(STREAM_MODE_UNIX); + setStreamMode(STREAM_MODE_UNIX); #endif } else { - setStreamMode(STREAM_MODE_TCP); + setStreamMode(STREAM_MODE_TCP); } return 0; @@ -141,33 +142,113 @@ BAD_EXIT: } int -android_startOpenglesRenderer(int width, int height, OnPostFn onPost, void* onPostContext) +android_startOpenglesRenderer(int width, int height) { if (!rendererLib) { D("Can't start OpenGLES renderer without support libraries"); return -1; } - if (initOpenGLRenderer(width, height, ANDROID_OPENGLES_BASE_PORT, onPost, onPostContext) != 0) { + if (rendererStarted) { + return 0; + } + + if (!initOpenGLRenderer(width, height, rendererAddress, sizeof(rendererAddress))) { D("Can't start OpenGLES renderer?"); return -1; } + + rendererStarted = 1; return 0; } void -android_stopOpenglesRenderer(void) +android_setPostCallback(OnPostFunc onPost, void* onPostContext) { if (rendererLib) { + setPostCallback(onPost, onPostContext); + } +} + +static void strncpy_safe(char* dst, const char* src, size_t n) +{ + strncpy(dst, src, n); + dst[n-1] = '\0'; +} + +static void extractBaseString(char* dst, const char* src, size_t dstSize) +{ + const char* begin = strchr(src, '('); + const char* end = strrchr(src, ')'); + + if (!begin || !end) { + strncpy_safe(dst, src, dstSize); + return; + } + begin += 1; + + // "foo (bar)" + // ^ ^ + // b e + // = 5 8 + // substring with NUL-terminator is end-begin+1 bytes + if (end - begin + 1 > dstSize) { + end = begin + dstSize - 1; + } + + strncpy_safe(dst, begin, end - begin + 1); +} + +void +android_getOpenglesHardwareStrings(char* vendor, size_t vendorBufSize, + char* renderer, size_t rendererBufSize, + char* version, size_t versionBufSize) +{ + const char *vendorSrc, *rendererSrc, *versionSrc; + + assert(vendorBufSize > 0 && rendererBufSize > 0 && versionBufSize > 0); + assert(vendor != NULL && renderer != NULL && version != NULL); + + if (!rendererStarted) { + D("Can't get OpenGL ES hardware strings when renderer not started"); + vendor[0] = renderer[0] = version[0] = '\0'; + return; + } + + getHardwareStrings(&vendorSrc, &rendererSrc, &versionSrc); + if (!vendorSrc) vendorSrc = ""; + if (!rendererSrc) rendererSrc = ""; + if (!versionSrc) versionSrc = ""; + + /* Special case for the default ES to GL translators: extract the strings + * of the underlying OpenGL implementation. */ + if (strncmp(vendorSrc, "Google", 6) == 0 && + strncmp(rendererSrc, "Android Emulator OpenGL ES Translator", 37) == 0) { + extractBaseString(vendor, vendorSrc, vendorBufSize); + extractBaseString(renderer, rendererSrc, rendererBufSize); + extractBaseString(version, versionSrc, versionBufSize); + } else { + strncpy_safe(vendor, vendorSrc, vendorBufSize); + strncpy_safe(renderer, rendererSrc, rendererBufSize); + strncpy_safe(version, versionSrc, versionBufSize); + } +} + +void +android_stopOpenglesRenderer(void) +{ + if (rendererStarted) { stopOpenGLRenderer(); + rendererStarted = 0; } } int android_showOpenglesWindow(void* window, int x, int y, int width, int height, float rotation) { - if (rendererLib) { - return createOpenGLSubwindow(window, x, y, width, height, rotation); + if (rendererStarted) { + int success = createOpenGLSubwindow((FBNativeWindowType)window, x, y, width, height, rotation); + return success ? 0 : -1; } else { return -1; } @@ -176,8 +257,9 @@ android_showOpenglesWindow(void* window, int x, int y, int width, int height, fl int android_hideOpenglesWindow(void) { - if (rendererLib) { - return destroyOpenGLSubwindow(); + if (rendererStarted) { + int success = destroyOpenGLSubwindow(); + return success ? 0 : -1; } else { return -1; } @@ -186,22 +268,62 @@ android_hideOpenglesWindow(void) void android_redrawOpenglesWindow(void) { - if (rendererLib) { + if (rendererStarted) { repaintOpenGLDisplay(); } } void -android_gles_unix_path(char* buff, size_t buffsize, int port) +android_gles_server_path(char* buff, size_t buffsize) { - const char* user = getenv("USER"); - char *p = buff, *end = buff + buffsize; + strncpy_safe(buff, rendererAddress, buffsize); +} - /* The logic here must correspond to the one inside - * development/tools/emulator/opengl/shared/libOpenglCodecCommon/UnixStream.cpp */ - p = bufprint(p, end, "/tmp/"); - if (user && user[0]) { - p = bufprint(p, end, "android-%s/", user); - } - p = bufprint(p, end, "qemu-gles-%d", port); +#else // CONFIG_ANDROID_OPENGLES + +int android_initOpenglesEmulation(void) +{ + return -1; +} + +int android_startOpenglesRenderer(int width, int height) +{ + return -1; +} + +void +android_setPostCallback(OnPostFunc onPost, void* onPostContext) +{ +} + +void android_getOpenglesHardwareStrings(char* vendor, size_t vendorBufSize, + char* renderer, size_t rendererBufSize, + char* version, size_t versionBufSize) +{ + assert(vendorBufSize > 0 && rendererBufSize > 0 && versionBufSize > 0); + assert(vendor != NULL && renderer != NULL && version != NULL); + vendor[0] = renderer[0] = version[0] = 0; +} + +void android_stopOpenglesRenderer(void) +{} + +int android_showOpenglesWindow(void* window, int x, int y, int width, int height, float rotation) +{ + return -1; +} + +int android_hideOpenglesWindow(void) +{ + return -1; } + +void android_redrawOpenglesWindow(void) +{} + +void android_gles_server_path(char* buff, size_t buffsize) +{ + buff[0] = '\0'; +} + +#endif // !CONFIG_ANDROID_OPENGLES |