[PATCH] Android: glretracer for Android.
Juha-Pekka Heikkilä
juha-pekka.heikkila at linux.intel.com
Fri Jun 28 01:16:30 PDT 2013
Hi,
thanks for looking at the patch and for the comments. I'm away to enjoy
the sun for a while thus the fixes will be delayed few weeks. :) Just
quick comments below.
The final target for me with this is to have the remote retracing from
qapitrace to work on Android over adb instead of ssh. I did Waffle port
for Android thus I was familiar to use it here also. As a side benefit by
using Waffle here one could also have retracing working on top of Wayland
with very little extra work.
On Thu, June 27, 2013 8:29 pm, Alexander Monakov wrote:
> On Thu, 27 Jun 2013, Juha-Pekka Heikkila wrote:
>> 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)
>
> Looks unused.
>
True, it is leftovers from experimenting with cmake.
>>
>> # 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 ()
>
> I don't see why you need this change.
Things needed here are located in other libraries on Android thanks to
bionic. I was getting errors by having Threads package included thus left
it out.
>
>> +
>> +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
>
> I don't see why you're modifying glproc_gl.cpp; only glproc_egl should
> come
> into play on Android.
aha. This is where I seem to have been confused. Executable I run on
Android is glretracer, not eglretracer. I need to double check this
because it matters on where 'waffle_dl_sym' call is placed.
>
>>
>> #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 ()
>> +
>
> Unrelated change?
True, this was related to the Threads package removal but it is in wrong
place here.
>
>> 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 ()
>
> Why do you need to suppress this cmake warning?
>
This possibly is due to my lack of experience with cmake. I was getting
error on the way I include Waffle here and did not see other way around.
This did cause the compilation to stop so I had to disable the warning.
>> +
>> + 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
>
> Hm. Do you need both glretrace and eglretrace on Android?
As mention above, I seem to have had some mixup. I was running glretrace
on Android, not eglretrace.
>
>
>> ${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;
>
> createVisual code should probably go here.
>
True
>> + }
>> +
>> + ~WaffleVisual() {
>> + waffle_config_destroy(this->config);
>
> Watch indentation.
>
>> + }
>> +};
>> +
>> +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");
>
> Can you use os::log instead?
yes, need to replace all the printfs to os::log. Here should probably also
do something like exit() or so.
>
>> + }
>> +}
>> +
>> +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...
>> + */
>
> I think this comment can be safely removed :)
>
I did initially put the comment here because this is undocumented
behaviour on Waffle. As I was looking at Waffle code for this I realized
the path was not 100% trivial inside Waffle.
>> + 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 */
>>
>
More information about the apitrace
mailing list