aboutsummaryrefslogtreecommitdiffstats
path: root/android/opengles.c
diff options
context:
space:
mode:
Diffstat (limited to 'android/opengles.c')
-rw-r--r--android/opengles.c220
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