summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2016-07-03 14:02:52 +0200
committerIvo van Dongen <info@ivovandongen.nl>2016-07-07 10:08:45 +0200
commite673f6e2faad93531373d046f6a66254bc3515c2 (patch)
treeef764cbf2c9af6cd542d65ce80b6c5cdcb49172d
parent353061b8641f35b99c5ba1ef17961fb93872a6b9 (diff)
downloadqtlocation-mapboxgl-e673f6e2faad93531373d046f6a66254bc3515c2.tar.gz
[android] #5456 - Updated the headless renderer
-rw-r--r--include/mbgl/platform/default/headless_view.hpp1
-rw-r--r--platform/android/src/headless_view_egl.cpp154
2 files changed, 155 insertions, 0 deletions
diff --git a/include/mbgl/platform/default/headless_view.hpp b/include/mbgl/platform/default/headless_view.hpp
index b8b91213c2..44e1e71dc3 100644
--- a/include/mbgl/platform/default/headless_view.hpp
+++ b/include/mbgl/platform/default/headless_view.hpp
@@ -83,6 +83,7 @@ private:
#if MBGL_USE_EGL
EGLDisplay glDisplay = EGL_NO_DISPLAY;
+ EGLConfig glConfig = nullptr;
EGLSurface glSurface = EGL_NO_SURFACE;
EGLContext glContext = EGL_NO_CONTEXT;
#endif
diff --git a/platform/android/src/headless_view_egl.cpp b/platform/android/src/headless_view_egl.cpp
new file mode 100644
index 0000000000..9ceec8f885
--- /dev/null
+++ b/platform/android/src/headless_view_egl.cpp
@@ -0,0 +1,154 @@
+#include <mbgl/platform/default/headless_view.hpp>
+#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/log.hpp>
+
+#include <cassert>
+
+#include <EGL/egl.h>
+
+namespace mbgl {
+
+static const EGLint configAttribs[] = {
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+ EGL_BLUE_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_RED_SIZE, 8,
+ EGL_DEPTH_SIZE, 8,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+ EGL_NONE
+};
+
+
+gl::glProc HeadlessView::initializeExtension(const char* name) {
+ Log::Info(Event::Android, "Initialize extension: %s", name);
+ return eglGetProcAddress(name);
+}
+
+void HeadlessView::createContext() {
+ Log::Info(Event::Android, "Create context");
+
+ glDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+ EGLint major, minor;
+ eglInitialize(glDisplay, &major, &minor);
+
+ EGLint numConfigs;
+ eglChooseConfig(glDisplay, configAttribs, &glConfig, 1, &numConfigs);
+
+ eglBindAPI(EGL_OPENGL_API);
+
+ glContext = eglCreateContext(glDisplay, glConfig, EGL_NO_CONTEXT, NULL);
+}
+
+void HeadlessView::destroyContext() {
+ Log::Info(Event::Android, "Destroy context");
+ if (glContext != EGL_NO_CONTEXT) {
+ eglDestroyContext(glDisplay, glContext);
+ glContext = EGL_NO_CONTEXT;
+ }
+
+ //Destroy surface?
+ /*
+ if (glSurface != EGL_NO_SURFACE) {
+ eglDestroySurface(glDisplay, glSurface);
+ glSurface = EGL_NO_SURFACE;
+ }
+ */
+ //Terminate display?
+ /*
+ if(glDisplay != EGL_NO_DISPLAY) {
+ eglTerminate(glDisplay);
+ glDisplay = EGL_NO_DISPLAY;
+ }
+ */
+
+ //Release thread?
+ //eglReleaseThread();
+}
+
+void HeadlessView::resizeFramebuffer() {
+ const unsigned int w = dimensions[0] * pixelRatio;
+ const unsigned int h = dimensions[1] * pixelRatio;
+
+ // Create depth/stencil buffer
+ MBGL_CHECK_ERROR(glGenRenderbuffers(1, &fboDepthStencil));
+ MBGL_CHECK_ERROR(glBindRenderbuffer(GL_RENDERBUFFER, fboDepthStencil));
+ MBGL_CHECK_ERROR(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, w, h));
+ MBGL_CHECK_ERROR(glBindRenderbuffer(GL_RENDERBUFFER, 0));
+
+ MBGL_CHECK_ERROR(glGenRenderbuffers(1, &fboColor));
+ MBGL_CHECK_ERROR(glBindRenderbuffer(GL_RENDERBUFFER, fboColor));
+ MBGL_CHECK_ERROR(glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, w, h));
+ MBGL_CHECK_ERROR(glBindRenderbuffer(GL_RENDERBUFFER, 0));
+
+ MBGL_CHECK_ERROR(glGenFramebuffers(1, &fbo));
+ MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fbo));
+
+ MBGL_CHECK_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fboColor));
+ MBGL_CHECK_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fboDepthStencil));
+ MBGL_CHECK_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fboDepthStencil));
+
+ GLenum status = MBGL_CHECK_ERROR(glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ std::string error("Couldn't create framebuffer: ");
+ switch (status) {
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: (error += "incomplete attachment"); break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: error += "incomplete missing attachment"; break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: error += "incomplete dimensions"; break;
+ case GL_FRAMEBUFFER_UNSUPPORTED: error += "unsupported"; break;
+ default: error += "other"; break;
+ }
+ throw std::runtime_error(error);
+ }
+
+ MBGL_CHECK_ERROR(glViewport(0, 0, w, h));
+}
+
+/*
+void HeadlessView::resizeFramebuffer() {
+ Log::Info(Event::Android, "Resize FB");
+
+ //Make sure we're clean
+ if(glSurface != EGL_NO_SURFACE) {
+ eglDestroySurface(glDisplay, glSurface);
+ }
+
+ const int32_t w = dimensions[0] * pixelRatio;
+ const int32_t h = dimensions[1] * pixelRatio;
+
+ const EGLint pbufferAttribs[] = {
+ EGL_WIDTH, w,
+ EGL_HEIGHT, h,
+ EGL_NONE,
+ };
+
+ Log::Info(Event::Android, "Resizing pbuffer to %dx%d", w, h);
+
+ glSurface = eglCreatePbufferSurface(glDisplay, glConfig, pbufferAttribs);
+
+ this->activateContext();
+}
+*/
+
+void HeadlessView::clearBuffers() {
+ Log::Info(Event::Android, "Clear buffers");
+}
+
+void HeadlessView::activateContext() {
+ Log::Info(Event::Android, "Activate context");
+ if(eglMakeCurrent(glDisplay, glSurface, glSurface, glContext) != EGL_TRUE) {
+ Log::Info(Event::Android, "Error activating context");
+ throw std::runtime_error("Error activating context");
+ }
+}
+
+void HeadlessView::deactivateContext() {
+ Log::Info(Event::Android, "Deactivate context");
+ if(eglMakeCurrent(glDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE) {
+ Log::Info(Event::Android, "Error deactivating context");
+ throw std::runtime_error("Error deactivating context");
+ }
+}
+
+} // namespace mbgl