Abstract selector of translator or host GL libs a bit more

This commit is contained in:
Simon Fels 2017-01-20 18:05:40 +01:00
commit 30c2186826
13 changed files with 130 additions and 57 deletions

View file

@ -71,7 +71,7 @@ std::ostream& operator<<(std::ostream& out,
// We are imposing size constraints to ensure a consistent CLI layout.
typedef SizeConstrainedString<20> Name;
typedef SizeConstrainedString<60> Usage;
typedef SizeConstrainedString<60> Description;
typedef SizeConstrainedString<80> Description;
/// @brief Flag models an input parameter to a command.
class Flag : public DoNotCopyOrMove {

View file

@ -63,6 +63,17 @@ class NullConnectionCreator : public anbox::network::ConnectionCreator<
socket->close();
}
};
std::istream& operator>>(std::istream& in, anbox::graphics::GLRendererServer::Config::Driver& driver) {
std::string str(std::istreambuf_iterator<char>(in), {});
if (str.empty() || str == "translator")
driver = anbox::graphics::GLRendererServer::Config::Driver::Translator;
else if (str == "host")
driver = anbox::graphics::GLRendererServer::Config::Driver::Host;
else
BOOST_THROW_EXCEPTION(std::runtime_error("Invalid GLES driver value provided"));
return in;
}
}
anbox::cmds::Run::BusFactory anbox::cmds::Run::session_bus_factory() {
@ -81,6 +92,9 @@ anbox::cmds::Run::Run(const BusFactory &bus_factory)
flag(cli::make_flag(cli::Name{"desktop_file_hint"},
cli::Description{"Desktop file hint for QtMir/Unity8"},
desktop_file_hint_));
flag(cli::make_flag(cli::Name{"gles-driver"},
cli::Description{"Which GLES driver to use. Possible values are 'host' or'translator'"},
gles_driver_));
action([this](const cli::Command::Context &) {
auto trap = core::posix::trap_signals_for_process(
@ -119,8 +133,8 @@ anbox::cmds::Run::Run(const BusFactory &bus_factory)
xdg::data().home() / "applications" / "anbox",
xdg::data().home() / "anbox" / "icons");
auto gl_server =
std::make_shared<graphics::GLRendererServer>(window_manager);
auto gl_server = std::make_shared<graphics::GLRendererServer>(
graphics::GLRendererServer::Config{gles_driver_}, window_manager);
policy->set_renderer(gl_server->renderer());

View file

@ -26,6 +26,8 @@
#include <core/dbus/bus.h>
#include "anbox/graphics/gl_renderer_server.h"
namespace anbox {
namespace cmds {
class Run : public cli::CommandWithFlagsAndAction {
@ -39,6 +41,7 @@ class Run : public cli::CommandWithFlagsAndAction {
private:
BusFactory bus_factory_;
std::string desktop_file_hint_;
graphics::GLRendererServer::Config::Driver gles_driver_;
};
} // namespace cmds
} // namespace anbox

View file

@ -30,19 +30,50 @@
GLESv2Dispatch s_gles2;
GLESv1Dispatch s_gles1;
namespace {
constexpr const char *default_egl_lib{"libEGL.so.1"};
constexpr const char *default_glesv1_lib{"libGLESv1_CM.so.1"};
constexpr const char *default_glesv2_lib{"libGLESv2.so.2"};
}
namespace anbox {
namespace graphics {
namespace emugl {
bool initialize(emugl_logger_struct log_funcs, emugl_crash_func_t crash_func) {
std::vector<GLLibrary> default_gl_libraries() {
return std::vector<GLLibrary>{
{GLLibrary::Type::EGL, default_egl_lib},
{GLLibrary::Type::GLESv1, default_glesv1_lib},
{GLLibrary::Type::GLESv2, default_glesv2_lib},
};
}
bool initialize(const std::vector<GLLibrary> &libs, emugl_logger_struct log_funcs, emugl_crash_func_t crash_func) {
set_emugl_crash_reporter(crash_func);
set_emugl_logger(log_funcs.coarse);
set_emugl_cxt_logger(log_funcs.fine);
if (!init_egl_dispatch()) return false;
for (const auto &lib : libs) {
const auto path = lib.path.c_str();
switch (lib.type) {
case GLLibrary::Type::EGL:
if (!init_egl_dispatch(path))
return false;
break;
case GLLibrary::Type::GLESv1:
if (!gles1_dispatch_init(path, &s_gles1))
return false;
break;
case GLLibrary::Type::GLESv2:
if (!gles2_dispatch_init(path, &s_gles2))
return false;
break;
default:
break;
}
}
if (!gles1_dispatch_init(&s_gles1)) return false;
if (!gles2_dispatch_init(&s_gles2)) return false;
if (!s_egl.initialized || !s_gles1.initialized || !s_gles2.initialized)
return false;
return true;
}

View file

@ -17,6 +17,10 @@
#ifndef RENDER_API_H
#define RENDER_API_H
#include <string>
#include <boost/filesystem/path.hpp>
typedef void (*emugl_logger_func_t)(const char* fmt, ...);
typedef void (*emugl_crash_func_t)(const char* format, ...);
@ -28,7 +32,15 @@ typedef struct {
namespace anbox {
namespace graphics {
namespace emugl {
bool initialize(emugl_logger_struct log_funcs, emugl_crash_func_t crash_func);
struct GLLibrary {
enum class Type { EGL, GLESv1, GLESv2 };
Type type;
boost::filesystem::path path;
};
std::vector<GLLibrary> default_gl_libraries();
bool initialize(const std::vector<GLLibrary> &libs, emugl_logger_struct log_funcs, emugl_crash_func_t crash_func);
} // namespace emugl
} // namespace graphics
} // namespace anbox

View file

@ -24,6 +24,7 @@
#include "anbox/wm/manager.h"
#include <boost/throw_exception.hpp>
#include <boost/filesystem.hpp>
#include <cstdarg>
#include <stdexcept>
@ -42,39 +43,27 @@ void logger_write(const char *format, ...) {
namespace anbox {
namespace graphics {
GLRendererServer::GLRendererServer(const std::shared_ptr<wm::Manager> &wm)
GLRendererServer::GLRendererServer(const Config &config, const std::shared_ptr<wm::Manager> &wm)
: renderer_(std::make_shared<::Renderer>()),
wm_(wm),
composer_(std::make_shared<LayerComposer>(renderer_, wm)) {
if (utils::is_env_set("USE_HOST_GLES")) {
// Force the host EGL/GLES libraries as translator implementation
::setenv("ANDROID_EGL_LIB", "libEGL.so.1", 0);
::setenv("ANDROID_GLESv1_LIB", "libGLESv2.so.2", 0);
::setenv("ANDROID_GLESv2_LIB", "libGLESv2.so.2", 0);
} else {
auto translator_dir =
utils::prefix_dir_from_env(TRANSLATOR_INSTALL_DIR, "SNAP");
::setenv(
"ANDROID_EGL_LIB",
utils::string_format("%s/libEGL_translator.so", translator_dir).c_str(),
0);
::setenv("ANDROID_GLESv1_LIB",
utils::string_format("%s/libGLES_CM_translator.so", translator_dir)
.c_str(),
0);
::setenv("ANDROID_GLESv2_LIB",
utils::string_format("%s/libGLES_V2_translator.so", translator_dir)
.c_str(),
0);
std::vector<emugl::GLLibrary> gl_libs = emugl::default_gl_libraries();
if (config.driver == Config::Driver::Translator) {
DEBUG("Using GLES-to-GL translator for rendering");
boost::filesystem::path translator_dir = utils::prefix_dir_from_env(TRANSLATOR_INSTALL_DIR, "SNAP");
gl_libs.push_back(emugl::GLLibrary{emugl::GLLibrary::Type::EGL, (translator_dir / "libEGL_translator.so")});
gl_libs.push_back(emugl::GLLibrary{emugl::GLLibrary::Type::GLESv1, (translator_dir / "libGLES_CM_translator.so")});
gl_libs.push_back(emugl::GLLibrary{emugl::GLLibrary::Type::GLESv2, (translator_dir / "libGLES_V2_translator.so")});
}
emugl_logger_struct log_funcs;
log_funcs.coarse = logger_write;
log_funcs.fine = logger_write;
if (!emugl::initialize(log_funcs, nullptr))
BOOST_THROW_EXCEPTION(
std::runtime_error("Failed to initialize OpenGL renderer"));
if (!emugl::initialize(gl_libs, log_funcs, nullptr))
BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize OpenGL renderer"));
renderer_->initialize(0);

View file

@ -34,7 +34,12 @@ namespace graphics {
class LayerComposer;
class GLRendererServer {
public:
GLRendererServer(const std::shared_ptr<wm::Manager> &wm);
struct Config {
enum class Driver { Translator, Host };
Driver driver;
};
GLRendererServer(const Config &config, const std::shared_ptr<wm::Manager> &wm);
~GLRendererServer();
std::shared_ptr<Renderer> renderer() const { return renderer_; }