[PATCH] Android: glretracer for Android.
Juha-Pekka Heikkila
juha-pekka.heikkila at linux.intel.com
Thu Jun 27 04:17:12 PDT 2013
I made the glretracer to work with Android using Waffle library.
There is still issue with multiple windows on Android, otherwise this
seems to work nicely. I am not so experienced with cmake thus if there
is something that look weird with the CMakeLists it probably is weird.
I limited glws_waffle.cpp strictly to Android only but it probably would
start to work quite easily also on desktop. Before Waffle port of glretrace
for desktop could work Waffle need waffle_window_resize API call to be
implemented for other plarforms than Android.
To build for Android Waffle need to be build first.
Waffle can be obtained from:
http://cgit.freedesktop.org/~chadversary/waffle/
Make sure these patches are in place for Waffle before compiling
(at time of writing they are still stuck on the list)
http://lists.freedesktop.org/archives/waffle/2013-June/000167.html
http://lists.freedesktop.org/archives/waffle/2013-June/000168.html
Known issues:
glretracer seems to launch multiple windows with some traces from
Android. These multiple windows sometime segfault on Android, need
to look into this yet. I remember SurfaceFlinger wasn't maybe too
happy with such behaviour.
Signed-off-by: Juha-Pekka Heikkila <juha-pekka.heikkila at linux.intel.com>
---
CMakeLists.txt | 26 +++++-
dispatch/glproc_gl.cpp | 8 ++
retrace/CMakeLists.txt | 120 +++++++++++++++++++------
retrace/glws_waffle.cpp | 227 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 354 insertions(+), 27 deletions(-)
create mode 100644 retrace/glws_waffle.cpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d819be2..1642b01 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,6 @@
cmake_minimum_required (VERSION 2.8)
+include(CheckIncludeFiles)
# Use clang on MacOSX. gcc doesn't support __thread key, and Apple has
# abandoned it for clang. This must be done before the project is defined.
@@ -61,7 +62,18 @@ else ()
endif ()
find_host_package (PythonInterp REQUIRED)
-find_package (Threads)
+if (NOT ANDROID)
+ find_package (Threads)
+endif ()
+
+if (ANDROID)
+#########
+# In following the name waffle-1 should be fixed to found out properly.
+ find_path (Waffle_INCLUDE_DIRS NAMES waffle.h PATHS "$ENV{OUT}/obj/include/waffle-1" "$ENV{OUT}/obj/lib" "$ENV{ANDROID_BUILD_TOP}/external/waffle" NO_CMAKE_FIND_ROOT_PATH )
+
+ find_library (Waffle NAMES "waffle-1" PATHS "$ENV{OUT}/obj/include/waffle-1" "$ENV{OUT}/obj/lib" "$ENV{ANDROID_BUILD_TOP}/external/waffle" REQUIRED NO_CMAKE_FIND_ROOT_PATH NO_DEFAULT_PATH)
+ include_directories (${Waffle_INCLUDE_DIRS})
+endif ()
if (ENABLE_GUI)
if (NOT (ENABLE_GUI STREQUAL "AUTO"))
@@ -294,6 +306,12 @@ include_directories (
${CMAKE_CURRENT_SOURCE_DIR}/common
)
+#if (ANDROID)
+# include_directories ( BEFORE
+# $ENV{ANDROID_BUILD_TOP}/external/ltp/tools/top-LTP
+# )
+#endif ()
+
if (WIN32)
set (os os_win32.cpp)
set (glws_os glws_wgl.cpp)
@@ -302,7 +320,11 @@ else ()
if (APPLE)
set (glws_os glws_cocoa.mm)
else ()
- set (glws_os glws_glx.cpp)
+ if (ANDROID)
+ set (glws_os glws_waffle.cpp)
+ else ()
+ set (glws_os glws_glx.cpp)
+ endif ()
endif ()
endif ()
diff --git a/dispatch/glproc_gl.cpp b/dispatch/glproc_gl.cpp
index 2516dab..f793d1c 100644
--- a/dispatch/glproc_gl.cpp
+++ b/dispatch/glproc_gl.cpp
@@ -26,6 +26,9 @@
#include "glproc.hpp"
+#if defined(__ANDROID__)
+#include <waffle.h>
+#endif
#if !defined(_WIN32)
#include <unistd.h> // for symlink
@@ -272,7 +275,12 @@ _getPublicProcAddress(const char *procName)
void *
_getPrivateProcAddress(const char *procName)
{
+#ifdef __ANDROID__
+ extern int waffle_gl_api;
+ return waffle_dl_sym(waffle_gl_api, procName);
+#else
return (void *)_glXGetProcAddressARB((const GLubyte *)procName);
+#endif
}
diff --git a/retrace/CMakeLists.txt b/retrace/CMakeLists.txt
index 78cceae..c2de4fc 100644
--- a/retrace/CMakeLists.txt
+++ b/retrace/CMakeLists.txt
@@ -9,6 +9,12 @@ include_directories (
${CMAKE_SOURCE_DIR}/image
)
+if (ANDROID)
+ include_directories ( BEFORE
+ $ENV{ANDROID_BUILD_TOP}/external/ltp/tools/top-LTP
+ )
+endif ()
+
add_definitions (-DRETRACE)
add_custom_command (
@@ -40,13 +46,55 @@ add_library (retrace_common STATIC
retrace_swizzle.cpp
json.cpp
)
-target_link_libraries (retrace_common
- image
- common
- ${ZLIB_LIBRARIES}
- ${SNAPPY_LIBRARIES}
- ${GETOPT_LIBRARIES}
-)
+
+if (ANDROID)
+
+#########
+# In following the name waffle-1 should be fixed to found out properly.
+ find_path (Waffle_INCLUDE_DIRS
+ NAMES waffle.h
+ PATHS "$ENV{OUT}/obj/include/waffle-1"
+ "$ENV{OUT}/obj/lib" "$ENV{ANDROID_BUILD_TOP}/external/waffle"
+ NO_CMAKE_FIND_ROOT_PATH
+ )
+
+ find_library (Waffle
+ NAMES "waffle-1"
+ PATHS "$ENV{OUT}/obj/include/waffle-1" "$ENV{OUT}/obj/lib"
+ "$ENV{ANDROID_BUILD_TOP}/external/waffle"
+ REQUIRED NO_CMAKE_FIND_ROOT_PATH NO_DEFAULT_PATH
+ )
+
+ include_directories (${Waffle_INCLUDE_DIRS})
+
+ if (POLICY CMP0016)
+ cmake_policy (PUSH)
+ cmake_policy (SET CMP0016 OLD)
+ endif ()
+
+ target_link_libraries (retrace_common
+ image
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ ${GETOPT_LIBRARIES}
+ ${Waffle}
+ )
+
+ if (POLICY CMP0016)
+ cmake_policy (POP)
+ endif ()
+
+
+else ()
+ target_link_libraries (retrace_common
+ image
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ ${GETOPT_LIBRARIES}
+ )
+endif ()
add_library (glretrace_common STATIC
glretrace_gl.cpp
@@ -68,7 +116,7 @@ target_link_libraries (glretrace_common
)
-if (WIN32 OR APPLE OR X11_FOUND)
+if (WIN32 OR APPLE OR X11_FOUND OR ANDROID)
add_executable (glretrace
${glws_os}
)
@@ -90,19 +138,31 @@ if (WIN32 OR APPLE OR X11_FOUND)
#"-framework OpenGL" # CGL*
)
else ()
- target_link_libraries (glretrace ${X11_X11_LIB})
+ if (NOT ANDROID)
+ target_link_libraries (glretrace ${X11_X11_LIB})
+ endif()
endif ()
- target_link_libraries (glretrace
- # gdb doesn't like when pthreads is loaded through dlopen (which happens
- # when dlopen'ing libGL), so link pthreads to avoid this issue. See also
- # http://stackoverflow.com/questions/2702628/gdb-cannot-find-new-threads-generic-error
- ${CMAKE_THREAD_LIBS_INIT}
- dl
- )
+
+ if (ANDROID)
+ target_link_libraries (glretrace
+ dl
+ )
+ else()
+ target_link_libraries (glretrace
+ # gdb doesn't like when pthreads is loaded through dlopen (which happens
+ # when dlopen'ing libGL), so link pthreads to avoid this issue. See also
+ # http://stackoverflow.com/questions/2702628/gdb-cannot-find-new-threads-generic-error
+ ${CMAKE_THREAD_LIBS_INIT}
+ dl
+ )
+ endif ()
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
- target_link_libraries (glretrace rt)
+ if (NOT ANDROID)
+ target_link_libraries (glretrace rt)
+ endif ()
+
if (READPROC_H_FOUND)
target_link_libraries (glretrace ${proc_LIBRARY})
endif ()
@@ -120,14 +180,24 @@ if (ENABLE_EGL AND X11_FOUND AND NOT WIN32 AND NOT APPLE)
add_dependencies (eglretrace glproc)
- target_link_libraries (eglretrace
- retrace_common
- glretrace_common
- glproc_egl
- ${X11_X11_LIB}
- ${CMAKE_THREAD_LIBS_INIT}
- dl
- )
+ if (ANDROID)
+ target_link_libraries (eglretrace
+ retrace_common
+ glretrace_common
+ glproc_egl
+ cutils
+ dl
+ )
+ else ()
+ target_link_libraries (eglretrace
+ retrace_common
+ glretrace_common
+ glproc_egl
+ ${X11_X11_LIB}
+ ${CMAKE_THREAD_LIBS_INIT}
+ dl
+ )
+ endif ()
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
target_link_libraries (eglretrace rt)
diff --git a/retrace/glws_waffle.cpp b/retrace/glws_waffle.cpp
new file mode 100644
index 0000000..d77cff0
--- /dev/null
+++ b/retrace/glws_waffle.cpp
@@ -0,0 +1,227 @@
+#include "waffle.h"
+#include "glws.hpp"
+
+extern "C" {
+int waffle_gl_api = 0;
+};
+
+namespace glws {
+
+struct waffle_display *dpy;
+
+class WaffleVisual : public Visual
+{
+public:
+ struct waffle_config *config;
+
+ WaffleVisual()
+ {
+ this->config = NULL;
+ }
+
+ ~WaffleVisual() {
+ waffle_config_destroy(this->config);
+ }
+};
+
+class WaffleDrawable : public Drawable
+{
+public:
+
+ struct waffle_window *window;
+
+ WaffleDrawable(const Visual *vis, int w, int h, bool pbuffer) :
+ Drawable(vis, w, h, pbuffer)
+ {
+ const WaffleVisual *waffleVisual =
+ static_cast<const WaffleVisual *>(vis);
+
+ window = waffle_window_create(waffleVisual->config, w, h);
+ }
+
+ void
+ resize(int w, int h) {
+ if (w == width && h == height) {
+ return;
+ }
+
+ waffle_window_resize(window, w, h);
+ Drawable::resize(w, h);
+ }
+
+ void show(void) {
+ if (visible) {
+ return;
+ }
+
+ waffle_window_show(window);
+ Drawable::show();
+ }
+
+ void swapBuffers(void) {
+ waffle_window_swap_buffers(window);
+ }
+};
+
+class WaffleContext : public Context
+{
+public:
+ struct waffle_context *context;
+
+ WaffleContext(const Visual *vis, Profile prof,
+ struct waffle_context *ctx) :
+ Context(vis, prof),
+ context(ctx)
+ {}
+
+ ~WaffleContext() {
+ }
+};
+
+/*
+ * With waffle there is not too many events to look for..
+ */
+bool
+processEvents(void) {
+ return true;
+}
+
+void
+init(void) {
+ int i;
+ int waffle_init_attrib_list[3];
+
+ i = 0;
+ waffle_init_attrib_list[i++] = WAFFLE_PLATFORM;
+ waffle_init_attrib_list[i++] = WAFFLE_PLATFORM_ANDROID;
+ waffle_init_attrib_list[i++] = WAFFLE_NONE;
+
+ waffle_init(waffle_init_attrib_list);
+
+ dpy = waffle_display_connect(NULL);
+ if (!dpy)
+ {
+ printf("no display!!\n");
+ }
+}
+
+void
+cleanup(void) {
+ waffle_display_disconnect(dpy);
+}
+
+Visual *
+createVisual(bool doubleBuffer, Profile profile) {
+ WaffleVisual *visual = new WaffleVisual();
+
+ int config_attrib_list[64], i;
+
+ i = 0;
+ config_attrib_list[i++] = WAFFLE_CONTEXT_API;
+
+ switch (profile) {
+ case PROFILE_COMPAT:
+ if(!waffle_display_supports_context_api(dpy, WAFFLE_DL_OPENGL))
+ return NULL;
+ waffle_gl_api = config_attrib_list[i++] = WAFFLE_DL_OPENGL;
+ break;
+ case PROFILE_CORE:
+ assert(0);
+ return NULL;
+ case PROFILE_ES1:
+ if(!waffle_display_supports_context_api(dpy,
+ WAFFLE_CONTEXT_OPENGL_ES1))
+ return NULL;
+
+ config_attrib_list[i++] = WAFFLE_CONTEXT_OPENGL_ES1;
+ waffle_gl_api = WAFFLE_DL_OPENGL_ES1;
+ break;
+ case PROFILE_ES2:
+ if(!waffle_display_supports_context_api(dpy,
+ WAFFLE_CONTEXT_OPENGL_ES2))
+ return NULL;
+
+ config_attrib_list[i++] = WAFFLE_CONTEXT_OPENGL_ES2;
+ waffle_gl_api = WAFFLE_DL_OPENGL_ES2;
+ break;
+ default:
+ return NULL;
+ }
+
+ config_attrib_list[i++] = WAFFLE_RED_SIZE;
+ config_attrib_list[i++] = 8;
+ config_attrib_list[i++] = WAFFLE_GREEN_SIZE;
+ config_attrib_list[i++] = 8;
+ config_attrib_list[i++] = WAFFLE_BLUE_SIZE;
+ config_attrib_list[i++] = 8;
+ config_attrib_list[i++] = WAFFLE_DEPTH_SIZE;
+ config_attrib_list[i++] = 8;
+ config_attrib_list[i++] = WAFFLE_ALPHA_SIZE;
+ config_attrib_list[i++] = 8;
+ config_attrib_list[i++] = WAFFLE_STENCIL_SIZE;
+ config_attrib_list[i++] = 8;
+ config_attrib_list[i++] = WAFFLE_DOUBLE_BUFFERED;
+ config_attrib_list[i++] = true;
+ config_attrib_list[i++] = 0;
+
+ visual->config = waffle_config_choose(dpy, config_attrib_list);
+ if (!visual->config)
+ {
+ printf("Error in %s waffle_config_choose(dpy, config_attrib_list)\n",
+ __FILE__);
+ return NULL;
+ }
+
+ return visual;
+}
+
+Drawable *
+createDrawable(const Visual *visual, int width, int height, bool pbuffer)
+{
+ return new WaffleDrawable(visual, width, height, pbuffer);
+}
+
+Context *
+createContext(const Visual *visual, Context *shareContext, Profile profile,
+ bool debug)
+{
+ struct waffle_context *ctx;
+ const WaffleVisual *waffleVisual =
+ static_cast<const WaffleVisual *>(visual);
+
+ ctx = waffle_context_create(waffleVisual->config, NULL);
+ if (!ctx)
+ {
+ printf("Error in %s waffle_context_create(config, NULL)\n",
+ __FILE__);
+ return NULL;
+ }
+ return new WaffleContext(visual, profile, ctx );
+}
+
+bool
+makeCurrent(Drawable *drawable, Context *context)
+{
+
+ if (!drawable || !context) {
+ /*
+ * hm.
+ * Following cause inside waffle
+ * eglMakeCurrent(dpy, NULL, NULL, NULL) which equal to
+ * eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, \
+ * EGL_NO_CONTEXT)
+ * Lets hope things stay that way...
+ */
+ return waffle_make_current(dpy, NULL, NULL);
+ }
+ else {
+ WaffleDrawable *waffleDrawable =
+ static_cast<WaffleDrawable *>(drawable);
+ WaffleContext *waffleContext =
+ static_cast<WaffleContext *>(context);
+ return waffle_make_current(dpy, waffleDrawable->window,
+ waffleContext->context);
+ }
+}
+
+} /* namespace glws */
--
1.8.1.2
More information about the apitrace
mailing list