From 8768c3e09a97563ade4388a2bdeb2b8d4ff71092 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Wed, 16 Nov 2016 17:43:09 +0100 Subject: [android] Use pBuffer for headless EGL backend --- platform/linux/src/headless_backend_egl.cpp | 31 +++++++++++++++++++++++++---- platform/linux/src/headless_display_egl.cpp | 15 ++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/platform/linux/src/headless_backend_egl.cpp b/platform/linux/src/headless_backend_egl.cpp index 0fb33ea0e0..57abe04229 100644 --- a/platform/linux/src/headless_backend_egl.cpp +++ b/platform/linux/src/headless_backend_egl.cpp @@ -10,9 +10,24 @@ namespace mbgl { struct EGLImpl : public HeadlessBackend::Impl { - EGLImpl(EGLContext glContext_, EGLDisplay display_) + EGLImpl(EGLContext glContext_, EGLDisplay display_, EGLConfig config_) : glContext(glContext_), - display(display_) { + display(display_), + config(config_) { +#if defined(__ANDROID__) + //Create a PBuffer surface (in conjunction with EGL_SURFACE_TYPE, EGL_PBUFFER_BIT) + const EGLint surfAttribs[] = { + EGL_WIDTH, 512, + EGL_HEIGHT, 512, + EGL_LARGEST_PBUFFER, EGL_TRUE, + EGL_NONE + }; + + glSurface = eglCreatePbufferSurface(display, config, surfAttribs); + if(glSurface == EGL_NO_SURFACE) { + throw std::runtime_error("Could not create surface: " + std::to_string(eglGetError())); + } +#endif // __ANDROID__ } ~EGLImpl() { @@ -22,10 +37,16 @@ struct EGLImpl : public HeadlessBackend::Impl { if (!eglDestroyContext(display, glContext)) { throw std::runtime_error("Failed to destroy EGL context.\n"); } + if (glSurface != EGL_NO_SURFACE) { + if (!eglDestroySurface(display, glSurface)) { + throw std::runtime_error("Failed to destroy EGL context.\n"); + } + glSurface = EGL_NO_SURFACE; + } } void activateContext() final { - if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, glContext)) { + if (!eglMakeCurrent(display, glSurface, glSurface, glContext)) { throw std::runtime_error("Switching OpenGL context failed.\n"); } } @@ -38,6 +59,8 @@ struct EGLImpl : public HeadlessBackend::Impl { EGLContext glContext = EGL_NO_CONTEXT; EGLDisplay display = EGL_NO_DISPLAY; + EGLConfig config = 0; + EGLSurface glSurface = EGL_NO_SURFACE; }; gl::glProc HeadlessBackend::initializeExtension(const char* name) { @@ -74,7 +97,7 @@ void HeadlessBackend::createContext() { throw std::runtime_error("Error creating the EGL context object.\n"); } - impl.reset(new EGLImpl(glContext, display_)); + impl.reset(new EGLImpl(glContext, display_, config)); } } // namespace mbgl diff --git a/platform/linux/src/headless_display_egl.cpp b/platform/linux/src/headless_display_egl.cpp index 4be519cfcd..e3edcd1784 100644 --- a/platform/linux/src/headless_display_egl.cpp +++ b/platform/linux/src/headless_display_egl.cpp @@ -31,8 +31,23 @@ HeadlessDisplay::Impl::Impl() { throw std::runtime_error("eglBindAPI() failed"); } +#if !defined(__ANDROID__) // This shouldn't matter as we're rendering to a framebuffer. const EGLint attribs[] = { EGL_NONE }; +#else + const EGLint attribs[] = { + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 0, + EGL_STENCIL_SIZE, 0, + EGL_NONE + }; +#endif // __ANDROID__ + if (!eglChooseConfig(display, attribs, &config, 1, &numConfigs) || numConfigs != 1) { throw std::runtime_error("Failed to choose ARGB config.\n"); } -- cgit v1.2.1