diff options
author | Ivo van Dongen <info@ivovandongen.nl> | 2016-07-03 17:22:59 +0200 |
---|---|---|
committer | Ivo van Dongen <info@ivovandongen.nl> | 2016-07-07 10:08:45 +0200 |
commit | e37fc9bf34fa4cde58623516e3add66c4571bec3 (patch) | |
tree | edf95afd78109fe306bba83156d51f8df0f40177 | |
parent | f74c311660499786b952ee16fcce4dca047723b4 (diff) | |
download | qtlocation-mapboxgl-e37fc9bf34fa4cde58623516e3add66c4571bec3.tar.gz |
[android] #5456 - headless view egl - cleanup resources and cleanup code
-rw-r--r-- | platform/android/src/headless_view_egl.cpp | 270 |
1 files changed, 123 insertions, 147 deletions
diff --git a/platform/android/src/headless_view_egl.cpp b/platform/android/src/headless_view_egl.cpp index 928400388c..51a8509f31 100644 --- a/platform/android/src/headless_view_egl.cpp +++ b/platform/android/src/headless_view_egl.cpp @@ -7,160 +7,136 @@ #include <EGL/egl.h> namespace mbgl { - //Android seems to be very specific here..., - static const EGLint configAttribs[] = { - 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 - }; - - 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"); - - //Connect to display system - glDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if(glDisplay == EGL_NO_DISPLAY){ - throw std::runtime_error("Could not connect to display"); - } - - //Initialize - EGLint major, minor; - if(!eglInitialize(glDisplay, &major, &minor)) { - Log::Error(Event::Android, "Could not initialize egl"); - } - - EGLint numConfigs; - if(!eglChooseConfig(glDisplay, configAttribs, &glConfig, 1, &numConfigs)) { - throw std::runtime_error( "Could not choose config"); - } - - EGLint surfAttribs[] = { - EGL_WIDTH, 512, - EGL_HEIGHT, 512, - EGL_LARGEST_PBUFFER, EGL_TRUE, - EGL_NONE - }; - - glSurface = eglCreatePbufferSurface(glDisplay, glConfig, surfAttribs); - if(glSurface == EGL_NO_SURFACE) { - throw std::runtime_error("Could not create surface: " + std::to_string(eglGetError())); - } - - eglBindAPI(EGL_OPENGL_API); - - GLint contextAttrs[] = - { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; - glContext = eglCreateContext(glDisplay, glConfig, EGL_NO_CONTEXT, contextAttrs); - - if (glContext == EGL_NO_CONTEXT) { - throw std::runtime_error("Could not create context"); - } - } - - 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"); +//Android seems to be very specific here..., +static const EGLint configAttribs[] = { + 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 +}; -//Make sure we're clean -if(glSurface != EGL_NO_SURFACE) { -eglDestroySurface(glDisplay, glSurface); +gl::glProc HeadlessView::initializeExtension(const char* name) { + Log::Info(Event::Android, "Initialize extension: %s", name); + return eglGetProcAddress(name); } -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); +void HeadlessView::createContext() { + Log::Info(Event::Android, "Create context"); + + //Connect to display system + glDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if(glDisplay == EGL_NO_DISPLAY){ + throw std::runtime_error("Could not connect to display"); + } + + //Initialize + EGLint major, minor; + if(!eglInitialize(glDisplay, &major, &minor)) { + Log::Error(Event::Android, "Could not initialize egl"); + } + + //Choose a matching configuration + EGLint numConfigs; + if(!eglChooseConfig(glDisplay, configAttribs, &glConfig, 1, &numConfigs)) { + throw std::runtime_error( "Could not choose config"); + } + + //Create a PBuffer surface (in conjunction with EGL_SURFACE_TYPE, EGL_PBUFFER_BIT) + EGLint surfAttribs[] = { + EGL_WIDTH, 512, + EGL_HEIGHT, 512, + EGL_LARGEST_PBUFFER, EGL_TRUE, + EGL_NONE + }; + + glSurface = eglCreatePbufferSurface(glDisplay, glConfig, surfAttribs); + if(glSurface == EGL_NO_SURFACE) { + throw std::runtime_error("Could not create surface: " + std::to_string(eglGetError())); + } + + //Bind + eglBindAPI(EGL_OPENGL_API); + + + //And, create the context finally + GLint contextAttrs[] = + { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + glContext = eglCreateContext(glDisplay, glConfig, EGL_NO_CONTEXT, contextAttrs); + + if (glContext == EGL_NO_CONTEXT) { + throw std::runtime_error("Could not create context"); + } +} -glSurface = eglCreatePbufferSurface(glDisplay, glConfig, pbufferAttribs); +void HeadlessView::destroyContext() { + Log::Info(Event::Android, "Destroy context"); + + //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; + } +} -this->activateContext(); +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::clearBuffers() { Log::Info(Event::Android, "Clear buffers"); |