From 01ef1d23dee29e50d324c5146f45af1e81e899f1 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 15 May 2018 08:53:21 +0200 Subject: [PATCH] graphics: use dummy GLESv1 by default Newer Ubuntu systems tend to not provide a libGLESv1_CM.so.1 anymore. As we're not required to have a GLESv1 implementation (only a few older Android apps are using GLESv1) we can as easy fix avoid loading a real GLESv1 implementation and assign dummy functions instead to all relevant GLESv1 API calls. In the future we want to switch to a GLESv1->GLESv2 translator as the Android emulator does. --- .../libOpenGLESDispatch/GLESv1Dispatch.cpp | 43 +++++++++++-------- src/anbox/graphics/emugl/RenderApi.cpp | 14 +++--- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/external/android-emugl/host/libs/libOpenGLESDispatch/GLESv1Dispatch.cpp b/external/android-emugl/host/libs/libOpenGLESDispatch/GLESv1Dispatch.cpp index b7e43dd..52be3d4 100644 --- a/external/android-emugl/host/libs/libOpenGLESDispatch/GLESv1Dispatch.cpp +++ b/external/android-emugl/host/libs/libOpenGLESDispatch/GLESv1Dispatch.cpp @@ -25,24 +25,40 @@ extern EGLDispatch s_egl; static emugl::SharedLibrary *s_gles1_lib = NULL; -// An unimplemented function which prints out an error message. -// To make it consistent with the guest, all GLES1 functions not supported by -// the driver should be redirected to this function. - static void gles1_unimplemented() { fprintf(stderr, "Called unimplemented GLESv1 API\n"); } -// -// This function is called only once during initialiation before -// any thread has been created - hence it should NOT be thread safe. -// +static void gles1_dummy() {} + +#define ASSIGN_DUMMY(return_type, function_name, signature, call_args) do { \ + dispatch_table-> function_name = reinterpret_cast(gles1_dummy); \ + } while(0); + + +#define LOOKUP_SYMBOL(return_type,function_name,signature,callargs) \ + dispatch_table-> function_name = reinterpret_cast< function_name ## _t >( \ + s_gles1_lib->findSymbol(#function_name)); + +#define LOOKUP_EXT_SYMBOL(return_type,function_name,signature,callargs) \ + dispatch_table-> function_name = reinterpret_cast< function_name ## _t >( \ + s_egl.eglGetProcAddress(#function_name)); namespace { constexpr const char *glesv1_lib_env_var{"ANBOX_GLESv1_LIB"}; } bool gles1_dispatch_init(const char *path, GLESv1Dispatch* dispatch_table) { + if (!dispatch_table) + return false; + + // If no path is given we assign dummy functions to all GL calls + // we would have loaded from a real implementation. + if (!path) { + LIST_GLES1_FUNCTIONS(ASSIGN_DUMMY, ASSIGN_DUMMY); + return true; + } + const char* libName = getenv(glesv1_lib_env_var); if (!libName) libName = path; @@ -57,17 +73,6 @@ bool gles1_dispatch_init(const char *path, GLESv1Dispatch* dispatch_table) { return false; } - // - // init the GLES dispatch table - // -#define LOOKUP_SYMBOL(return_type,function_name,signature,callargs) \ - dispatch_table-> function_name = reinterpret_cast< function_name ## _t >( \ - s_gles1_lib->findSymbol(#function_name)); - -#define LOOKUP_EXT_SYMBOL(return_type,function_name,signature,callargs) \ - dispatch_table-> function_name = reinterpret_cast< function_name ## _t >( \ - s_egl.eglGetProcAddress(#function_name)); - LIST_GLES1_FUNCTIONS(LOOKUP_SYMBOL,LOOKUP_EXT_SYMBOL) dispatch_table->initialized = true; diff --git a/src/anbox/graphics/emugl/RenderApi.cpp b/src/anbox/graphics/emugl/RenderApi.cpp index cad1bf7..b798c29 100644 --- a/src/anbox/graphics/emugl/RenderApi.cpp +++ b/src/anbox/graphics/emugl/RenderApi.cpp @@ -40,10 +40,6 @@ namespace emugl { std::vector default_gl_libraries() { return std::vector{ {GLLibrary::Type::EGL, default_egl_lib}, - // If environment doesn't provide a GLESv1 .so file we use the GLESv2 - // implementation instead. If our stack allows it we can try to get - // rid of GLESv1 completely at a later point. - {GLLibrary::Type::GLESv1, default_glesv1_lib}, {GLLibrary::Type::GLESv2, default_glesv2_lib}, }; } @@ -75,7 +71,15 @@ bool initialize(const std::vector &libs, emugl_logger_struct *log_fun } } - if (!s_egl.initialized || !s_gles1.initialized || !s_gles2.initialized) + // If we are not provided with a link to a OpenGL ES v1 implementation + // we assign dummy functions to all of the functions we would call. + // This allows us to still manage the major chunk of Android applications + // which are all >= GLESv2 until we have a proper GLESv1->GLESv2 + // translation mechanism in place. + if (!s_gles1.initialized) + gles1_dispatch_init(nullptr, &s_gles1); + + if (!s_egl.initialized || !s_gles2.initialized) return false; return true;