aboutsummaryrefslogtreecommitdiffstats
path: root/android/opengles.c
diff options
context:
space:
mode:
Diffstat (limited to 'android/opengles.c')
-rw-r--r--android/opengles.c166
1 files changed, 131 insertions, 35 deletions
diff --git a/android/opengles.c b/android/opengles.c
index 4913d0c..521dc03 100644
--- a/android/opengles.c
+++ b/android/opengles.c
@@ -12,39 +12,45 @@
#include "config-host.h"
#include "android/opengles.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"
+#elif HOST_LONG_BITS == 64
+#define RENDERER_LIB_NAME "lib64OpenglRender"
+#else
+#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),(width,height,port),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(getHardwareStrings) \
+ DYNLINK_FUNC(createOpenGLSubwindow) \
+ DYNLINK_FUNC(destroyOpenGLSubwindow) \
+ DYNLINK_FUNC(repaintOpenGLDisplay) \
+ DYNLINK_FUNC(stopOpenGLRenderer)
#ifndef CONFIG_STANDALONE_UI
/* Defined in android/hw-pipe-net.c */
@@ -53,15 +59,10 @@ extern int android_init_opengles_pipes(void);
static ADynamicLibrary* rendererLib;
-/* 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
@@ -69,10 +70,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); \
@@ -80,6 +82,7 @@ initOpenglesEmulationFuncs(ADynamicLibrary* rendererLib)
}
DYNLINK_FUNCTIONS
#undef DYNLINK_FUNC
+
return 0;
}
@@ -120,10 +123,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;
@@ -135,20 +138,76 @@ BAD_EXIT:
}
int
-android_startOpenglesRenderer(int width, int height)
+android_startOpenglesRenderer(int width, int height, OnPostFunc onPost, void* onPostContext)
{
if (!rendererLib) {
D("Can't start OpenGLES renderer without support libraries");
return -1;
}
- if (initOpenGLRenderer(width, height,ANDROID_OPENGLES_BASE_PORT) != 0) {
+ if (!initOpenGLRenderer(width, height, ANDROID_OPENGLES_BASE_PORT, onPost, onPostContext)) {
D("Can't start OpenGLES renderer?");
return -1;
}
return 0;
}
+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)
+{
+ size_t len = strlen(src);
+ 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;
+
+ 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)
{
@@ -161,7 +220,8 @@ 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);
+ int success = createOpenGLSubwindow((FBNativeWindowType)window, x, y, width, height, rotation);
+ return success ? 0 : -1;
} else {
return -1;
}
@@ -171,7 +231,8 @@ int
android_hideOpenglesWindow(void)
{
if (rendererLib) {
- return destroyOpenGLSubwindow();
+ int success = destroyOpenGLSubwindow();
+ return success ? 0 : -1;
} else {
return -1;
}
@@ -199,3 +260,38 @@ android_gles_unix_path(char* buff, size_t buffsize, int port)
}
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, OnPostFunc onPost, void* onPostContext)
+{
+ return -1;
+}
+
+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_unix_path(char* buff, size_t buffsize, int port)
+{
+ buff[0] = '\0';
+}
+
+#endif // !CONFIG_ANDROID_OPENGLES