From 3e126fb252ef0b76616837e455f492e87e3189ab Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 16 Nov 2016 10:29:26 +0100 Subject: [PATCH] Integrate RenderThread directly into our message processor --- src/anbox/cmds/run.cpp | 4 +- src/anbox/graphics/gl_renderer_server.cpp | 22 +-- src/anbox/graphics/gl_renderer_server.h | 3 - .../graphics/opengles_message_processor.cpp | 146 +++++++++++++++--- .../graphics/opengles_message_processor.h | 16 +- src/anbox/qemu/pipe_connection_creator.cpp | 12 +- src/anbox/qemu/pipe_connection_creator.h | 8 +- 7 files changed, 141 insertions(+), 70 deletions(-) diff --git a/src/anbox/cmds/run.cpp b/src/anbox/cmds/run.cpp index e65ce28..01bc29f 100644 --- a/src/anbox/cmds/run.cpp +++ b/src/anbox/cmds/run.cpp @@ -109,9 +109,7 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory) auto qemu_pipe_connector = std::make_shared( utils::string_format("%s/qemu_pipe", config::socket_path()), rt, - std::make_shared(rt, - renderer->socket_path(), - icon_)); + std::make_shared(rt)); auto android_api_stub = std::make_shared(); diff --git a/src/anbox/graphics/gl_renderer_server.cpp b/src/anbox/graphics/gl_renderer_server.cpp index e7cc739..00d8ec1 100644 --- a/src/anbox/graphics/gl_renderer_server.cpp +++ b/src/anbox/graphics/gl_renderer_server.cpp @@ -18,6 +18,7 @@ #include "anbox/logger.h" #include "anbox/graphics/gl_renderer_server.h" #include "anbox/graphics/window_creator.h" +#include "anbox/graphics/emugl/FrameBuffer.h" #include "OpenglRender/render_api.h" @@ -50,8 +51,8 @@ GLRendererServer::GLRendererServer(const std::shared_ptr &window_ } GLRendererServer::~GLRendererServer() { - // destroyOpenGLSubwindow(); - stopOpenGLRenderer(); + if (const auto fb = FrameBuffer::getFB()) + fb->finalize(); } void logger_write(const char *format, ...) { @@ -70,22 +71,7 @@ void GLRendererServer::start() { log_funcs.coarse = logger_write; log_funcs.fine = logger_write; - auto display_info = window_creator_->display_info(); - const auto width = display_info.horizontal_resolution; - const auto height = display_info.vertical_resolution; - - char server_addr[256] = { 0 }; - // The width & height we supply here are the dimensions the internal framebuffer - // will use. Making this static prevents us for now to resize the window we create - // later for the actual display. - if (!initOpenGLRenderer(window_creator_->native_display(), server_addr, sizeof(server_addr), log_funcs, logger_write)) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to setup OpenGL renderer")); - - socket_path_ = server_addr; -} - -std::string GLRendererServer::socket_path() const { - return socket_path_; + FrameBuffer::initialize(window_creator_->native_display()); } } // namespace graphics } // namespace anbox diff --git a/src/anbox/graphics/gl_renderer_server.h b/src/anbox/graphics/gl_renderer_server.h index 4b5fad9..3dedb36 100644 --- a/src/anbox/graphics/gl_renderer_server.h +++ b/src/anbox/graphics/gl_renderer_server.h @@ -34,10 +34,7 @@ public: void start(); - std::string socket_path() const; - private: - std::string socket_path_; std::shared_ptr window_creator_; }; diff --git a/src/anbox/graphics/opengles_message_processor.cpp b/src/anbox/graphics/opengles_message_processor.cpp index 6f5a26d..3452eff 100644 --- a/src/anbox/graphics/opengles_message_processor.cpp +++ b/src/anbox/graphics/opengles_message_processor.cpp @@ -20,39 +20,139 @@ #include "anbox/network/local_socket_messenger.h" #include "anbox/network/connections.h" #include "anbox/network/delegate_message_processor.h" +#include "anbox/graphics/emugl/RenderThread.h" + +#include "external/android-emugl/host/include/libOpenglRender/IOStream.h" + +#include +#include + +namespace { +class DirectIOStream : public IOStream { +public: + explicit DirectIOStream(const std::shared_ptr &messenger, + const size_t &buffer_size = 10000) : + IOStream(buffer_size), + messenger_(messenger) { + } + + virtual ~DirectIOStream() { + if (send_buffer_ != nullptr) { + free(send_buffer_); + send_buffer_ = nullptr; + } + } + + void* allocBuffer(size_t min_size) override { + size_t size = (send_buffer_size_ < min_size ? min_size : send_buffer_size_); + if (!send_buffer_) + send_buffer_ = (unsigned char *) malloc(size); + else if (send_buffer_size_ < size) { + unsigned char *p = (unsigned char *)realloc(send_buffer_, size); + if (p != NULL) { + send_buffer_ = p; + send_buffer_size_ = size; + } else { + free(send_buffer_); + send_buffer_ = NULL; + send_buffer_size_ = 0; + } + } + return send_buffer_; + } + + int commitBuffer(size_t size) override { + messenger_->send(reinterpret_cast(send_buffer_), size); + return size; + } + + const unsigned char* readFully(void*, size_t) override { + ERROR("Not implemented"); + return nullptr; + } + + const unsigned char* read(void *data, size_t *size) override { + if (!wait_for_data() || buffer_.size() == 0) { + *size = 0; + return nullptr; + } + + auto bytes_to_read = *size; + if (bytes_to_read > buffer_.size()) + bytes_to_read = buffer_.size(); + + ::memcpy(data, buffer_.data(), bytes_to_read); + buffer_.erase(buffer_.begin(), buffer_.begin() + bytes_to_read); + + *size = bytes_to_read; + + return static_cast(data); + } + + int writeFully(const void*, size_t) override { + ERROR("Not implemented"); + return 0; + } + + void forceStop() override { + std::unique_lock l(mutex_); + buffer_.clear(); + } + + void submitData(const std::vector &data) { + std::unique_lock l(mutex_); + for (const auto &byte : data) + buffer_.push_back(byte); + // buffer_.insert(buffer_.end(), data.begin(), data.end()); + lock_.notify_one(); + } + +private: + bool wait_for_data() { + std::unique_lock l(mutex_); + + if (!l.owns_lock()) + return false; + + lock_.wait(l, [&]() { return !buffer_.empty(); }); + return true; + } + + std::shared_ptr messenger_; + std::mutex mutex_; + std::condition_variable lock_; + std::vector buffer_; + unsigned char *send_buffer_ = nullptr; + size_t send_buffer_size_ = 0; +}; +} namespace anbox { namespace graphics { -OpenGlesMessageProcessor::OpenGlesMessageProcessor(const std::string &renderer_socket_path, - const std::shared_ptr &rt, - const std::shared_ptr &messenger) : - client_messenger_(messenger) { +emugl::Mutex OpenGlesMessageProcessor::global_lock{}; - connect_and_attach(renderer_socket_path, rt); +OpenGlesMessageProcessor::OpenGlesMessageProcessor(const std::shared_ptr &messenger) : + messenger_(messenger), + stream_(std::make_shared(messenger_)), + renderer_(RenderThread::create(stream_.get(), &global_lock)) { + + // We have to read the client flags first before we can continue + // processing the actual commands + std::array buffer; + messenger_->receive_msg(boost::asio::buffer(buffer)); + + renderer_->start(); } OpenGlesMessageProcessor::~OpenGlesMessageProcessor() { -} - -void OpenGlesMessageProcessor::connect_and_attach(const std::string &socket_path, - const std::shared_ptr &rt) { - - auto socket = std::make_shared(rt->service()); - socket->connect(boost::asio::local::stream_protocol::endpoint(socket_path)); - - messenger_ = std::make_shared(socket); - renderer_ = std::make_shared( - messenger_, messenger_, 0, nullptr, - std::make_shared([&](const std::vector &data) { - client_messenger_->send(reinterpret_cast(data.data()), data.size()); - return true; - })); - renderer_->set_name("opengles-renderer"); - renderer_->read_next_message(); + DEBUG(""); + renderer_->forceStop(); + renderer_->wait(nullptr); } bool OpenGlesMessageProcessor::process_data(const std::vector &data) { - messenger_->send(reinterpret_cast(data.data()), data.size()); + auto stream = std::static_pointer_cast(stream_); + stream->submitData(data); return true; } } // namespace graphics diff --git a/src/anbox/graphics/opengles_message_processor.h b/src/anbox/graphics/opengles_message_processor.h index 05612cf..374af97 100644 --- a/src/anbox/graphics/opengles_message_processor.h +++ b/src/anbox/graphics/opengles_message_processor.h @@ -27,24 +27,26 @@ #include "anbox/network/socket_messenger.h" #include "anbox/network/socket_connection.h" +#include "external/android-emugl/shared/emugl/common/mutex.h" + +class IOStream; +class RenderThread; + namespace anbox { namespace graphics { class OpenGlesMessageProcessor : public network::MessageProcessor { public: - OpenGlesMessageProcessor(const std::string &renderer_socket_path, - const std::shared_ptr &rt, - const std::shared_ptr &messenger); + OpenGlesMessageProcessor(const std::shared_ptr &messenger); ~OpenGlesMessageProcessor(); bool process_data(const std::vector &data) override; private: - void connect_and_attach(const std::string &socket_path, - const std::shared_ptr &rt); + static emugl::Mutex global_lock; - std::shared_ptr client_messenger_; std::shared_ptr messenger_; - std::shared_ptr renderer_; + std::shared_ptr stream_; + std::shared_ptr renderer_; }; } // namespace graphics } // namespace anbox diff --git a/src/anbox/qemu/pipe_connection_creator.cpp b/src/anbox/qemu/pipe_connection_creator.cpp index 5d81e89..7c31eb3 100644 --- a/src/anbox/qemu/pipe_connection_creator.cpp +++ b/src/anbox/qemu/pipe_connection_creator.cpp @@ -62,14 +62,10 @@ std::string client_type_to_string(const anbox::qemu::PipeConnectionCreator::clie } namespace anbox { namespace qemu { -PipeConnectionCreator::PipeConnectionCreator(const std::shared_ptr &rt, - const std::string &renderer_socket_path, - const std::string &boot_animation_icon_path) : +PipeConnectionCreator::PipeConnectionCreator(const std::shared_ptr &rt) : runtime_(rt), next_connection_id_(0), - connections_(std::make_shared>()), - renderer_socket_path_(renderer_socket_path), - boot_animation_icon_path_(boot_animation_icon_path) { + connections_(std::make_shared>()) { } PipeConnectionCreator::~PipeConnectionCreator() { @@ -137,7 +133,7 @@ PipeConnectionCreator::client_type PipeConnectionCreator::identify_client( std::shared_ptr PipeConnectionCreator::create_processor(const client_type &type, const std::shared_ptr &messenger) { if (type == client_type::opengles) - return std::make_shared(renderer_socket_path_, runtime_, messenger); + return std::make_shared(messenger); else if (type == client_type::qemud_boot_properties) return std::make_shared(messenger); else if (type == client_type::qemud_hw_control) @@ -150,8 +146,6 @@ std::shared_ptr PipeConnectionCreator::create_process return std::make_shared(messenger); else if (type == client_type::qemud_gsm) return std::make_shared(messenger); - else if (type == client_type::bootanimation) - return std::make_shared(messenger, boot_animation_icon_path_); else if (type == client_type::qemud_adb) return std::make_shared(runtime_, messenger); diff --git a/src/anbox/qemu/pipe_connection_creator.h b/src/anbox/qemu/pipe_connection_creator.h index 391fedf..e652e58 100644 --- a/src/anbox/qemu/pipe_connection_creator.h +++ b/src/anbox/qemu/pipe_connection_creator.h @@ -33,10 +33,7 @@ namespace anbox { namespace qemu { class PipeConnectionCreator : public network::ConnectionCreator { public: - PipeConnectionCreator( - const std::shared_ptr &rt, - const std::string &renderer_socket_path, - const std::string &boot_animation_icon_path); + PipeConnectionCreator(const std::shared_ptr &rt); ~PipeConnectionCreator() noexcept; void create_connection_for( @@ -65,9 +62,6 @@ private: std::shared_ptr runtime_; std::atomic next_connection_id_; std::shared_ptr> const connections_; - - std::string renderer_socket_path_; - std::string boot_animation_icon_path_; }; } // namespace qemu } // namespace anbox