From 6f91b7bcfa983711f0a08868ad66a76d2660fc33 Mon Sep 17 00:00:00 2001 From: Daniel Wallner Date: Fri, 11 Mar 2016 10:33:46 +0100 Subject: [PATCH 1/3] iOS SwapChain support --- src/glcontext_eagl.h | 8 +- src/glcontext_eagl.mm | 186 +++++++++++++++++++++++++++++++++++++++--- src/renderer_gl.cpp | 11 +-- 3 files changed, 182 insertions(+), 23 deletions(-) diff --git a/src/glcontext_eagl.h b/src/glcontext_eagl.h index a4786c498..33099ea1d 100644 --- a/src/glcontext_eagl.h +++ b/src/glcontext_eagl.h @@ -15,7 +15,11 @@ namespace bgfx { namespace gl struct GlContext { GlContext() - : m_context(0) + : m_current(0) + , m_context(0) + , m_fbo(0) + , m_colorRbo(0) + , m_depthStencilRbo(0) { } @@ -41,7 +45,7 @@ namespace bgfx { namespace gl return 0 != m_context; } - void* m_view; + SwapChainGL* m_current; void* m_context; GLuint m_fbo; diff --git a/src/glcontext_eagl.mm b/src/glcontext_eagl.mm index 544fe0373..ea086db18 100644 --- a/src/glcontext_eagl.mm +++ b/src/glcontext_eagl.mm @@ -17,6 +17,142 @@ namespace bgfx { namespace gl static void* s_opengles = NULL; + struct SwapChainGL + { + SwapChainGL(EAGLContext *_context, CAEAGLLayer *_layer) + : m_context(_context) + , m_fbo(0) + , m_colorRbo(0) + , m_depthStencilRbo(0) + { + _layer.contentsScale = [UIScreen mainScreen].scale; + + _layer.opaque = true; + + _layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys + : [NSNumber numberWithBool:false] + , kEAGLDrawablePropertyRetainedBacking + , kEAGLColorFormatRGBA8 + , kEAGLDrawablePropertyColorFormat + , nil + ]; + + + [EAGLContext setCurrentContext:_context]; + + GL_CHECK(glGenFramebuffers(1, &m_fbo) ); + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) ); + + GL_CHECK(glGenRenderbuffers(1, &m_colorRbo) ); + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) ); + + [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_layer]; + GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRbo) ); + + GLint width; + GLint height; + GL_CHECK(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width) ); + GL_CHECK(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height) ); + BX_TRACE("Screen size: %d x %d", width, height); + + m_width = width; + m_height = height; + m_layer = _layer; + + createFrameBuffers(m_width, m_height); + } + + ~SwapChainGL() + { + destroyFrameBuffers(); + } + + void destroyFrameBuffers() + { + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) ); + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0) ); + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0) ); + if (0 != m_fbo) + { + GL_CHECK(glDeleteFramebuffers(1, &m_fbo) ); + m_fbo = 0; + } + + if (0 != m_colorRbo) + { + GL_CHECK(glDeleteRenderbuffers(1, &m_colorRbo) ); + m_colorRbo = 0; + } + + if (0 != m_depthStencilRbo) + { + GL_CHECK(glDeleteRenderbuffers(1, &m_depthStencilRbo) ); + m_depthStencilRbo = 0; + } + } + + void createFrameBuffers(GLint _width, GLint _height) + { + GL_CHECK(glGenRenderbuffers(1, &m_depthStencilRbo) ); + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_depthStencilRbo) ); + GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _width, _height) ); // from OES_packed_depth_stencil + GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilRbo) ); + GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilRbo) ); + + BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER) + , "glCheckFramebufferStatus failed 0x%08x" + , glCheckFramebufferStatus(GL_FRAMEBUFFER) + ); + + makeCurrent(); + GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 0.0f) ); + GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); + swapBuffers(); + GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); + swapBuffers(); + } + + void makeCurrent() + { + [EAGLContext setCurrentContext:m_context]; + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) ); + + GLint newWidth = m_layer.bounds.size.width*[UIScreen mainScreen].scale; + GLint newHeight = m_layer.bounds.size.height*[UIScreen mainScreen].scale; + resize(newWidth, newHeight); + } + + void resize(GLint _width, GLint _height) + { + if(m_width == _width && m_height == _height) + { + return; + } + + destroyFrameBuffers(); + + m_width = _width; + m_height = _height; + + createFrameBuffers(m_width, m_height); + } + + void swapBuffers() + { + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) ); + [m_context presentRenderbuffer:GL_RENDERBUFFER]; + } + + EAGLContext* m_context; + + CAEAGLLayer *m_layer; + GLuint m_fbo; + GLuint m_colorRbo; + GLuint m_depthStencilRbo; + GLint m_width; + GLint m_height; + }; + void GlContext::create(uint32_t _width, uint32_t _height) { s_opengles = bx::dlopen("/System/Library/Frameworks/OpenGLES.framework/OpenGLES"); @@ -65,6 +201,13 @@ namespace bgfx { namespace gl , glCheckFramebufferStatus(GL_FRAMEBUFFER) ); + makeCurrent(); + GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 0.0f) ); + GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); + swap(NULL); + GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); + swap(NULL); + import(); g_internalData.context = m_context; @@ -148,30 +291,51 @@ namespace bgfx { namespace gl uint64_t GlContext::getCaps() const { - return 0; + return BGFX_CAPS_SWAP_CHAIN; } - SwapChainGL* GlContext::createSwapChain(void* /*_nwh*/) + SwapChainGL* GlContext::createSwapChain(void* _nwh) { - BX_CHECK(false, "Shouldn't be called!"); - return NULL; + return BX_NEW(g_allocator, SwapChainGL)(/*m_display, m_config,*/ (EAGLContext*)m_context, (CAEAGLLayer*)_nwh); } - void GlContext::destroySwapChain(SwapChainGL* /*_swapChain*/) + void GlContext::destroySwapChain(SwapChainGL* _swapChain) { - BX_CHECK(false, "Shouldn't be called!"); + BX_DELETE(g_allocator, _swapChain); } void GlContext::swap(SwapChainGL* _swapChain) { - BX_CHECK(NULL == _swapChain, "Shouldn't be called!"); BX_UNUSED(_swapChain); - GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) ); - EAGLContext* context = (EAGLContext*)m_context; - [context presentRenderbuffer:GL_RENDERBUFFER]; + makeCurrent(_swapChain); + + if (NULL == _swapChain) + { + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) ); + EAGLContext* context = (EAGLContext*)m_context; + [context presentRenderbuffer:GL_RENDERBUFFER]; + } + else + { + _swapChain->swapBuffers(); + } } - void GlContext::makeCurrent(SwapChainGL* /*_swapChain*/) + void GlContext::makeCurrent(SwapChainGL* _swapChain) { + if (m_current != _swapChain) + { + m_current = _swapChain; + + if (NULL == _swapChain) + { + [EAGLContext setCurrentContext:(EAGLContext*)m_context]; + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) ); + } + else + { + _swapChain->makeCurrent(); + } + } } void GlContext::import() diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index cd750514f..0f5d7ddb6 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -2562,16 +2562,7 @@ namespace bgfx { namespace gl { FrameBufferGL& frameBuffer = m_frameBuffers[_fbh.idx]; _height = frameBuffer.m_height; - if (UINT16_MAX != frameBuffer.m_denseIdx) - { - m_glctx.makeCurrent(frameBuffer.m_swapChain); - GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) ); - } - else - { - m_glctx.makeCurrent(NULL); - GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.m_fbo[0]) ); - } + m_glctx.makeCurrent(frameBuffer.m_swapChain); } m_fbh = _fbh; From 43748d5d5f32a4b856ea8d7d36aebbdadfeec032 Mon Sep 17 00:00:00 2001 From: Pacemaker Date: Mon, 14 Mar 2016 21:31:31 +0100 Subject: [PATCH 2/3] Do not break regular frame buffers. --- src/renderer_gl.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 0f5d7ddb6..8efc4b672 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -2562,7 +2562,15 @@ namespace bgfx { namespace gl { FrameBufferGL& frameBuffer = m_frameBuffers[_fbh.idx]; _height = frameBuffer.m_height; - m_glctx.makeCurrent(frameBuffer.m_swapChain); + if (UINT16_MAX != frameBuffer.m_denseIdx) + { + m_glctx.makeCurrent(frameBuffer.m_swapChain); + } + else + { + m_glctx.makeCurrent(NULL); + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.m_fbo[0]) ); + } } m_fbh = _fbh; From 34822357b461ae571ba529c5a6ccae3b90ce55a6 Mon Sep 17 00:00:00 2001 From: Pacemaker Date: Tue, 15 Mar 2016 17:30:57 +0100 Subject: [PATCH 3/3] Fixed noise. --- src/glcontext_eagl.mm | 204 +++++++++++++++++++++--------------------- src/renderer_gl.cpp | 18 ++-- 2 files changed, 110 insertions(+), 112 deletions(-) diff --git a/src/glcontext_eagl.mm b/src/glcontext_eagl.mm index ea086db18..1092b6259 100644 --- a/src/glcontext_eagl.mm +++ b/src/glcontext_eagl.mm @@ -30,127 +30,125 @@ namespace bgfx { namespace gl _layer.opaque = true; _layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys - : [NSNumber numberWithBool:false] - , kEAGLDrawablePropertyRetainedBacking - , kEAGLColorFormatRGBA8 - , kEAGLDrawablePropertyColorFormat - , nil - ]; + : [NSNumber numberWithBool:false] + , kEAGLDrawablePropertyRetainedBacking + , kEAGLColorFormatRGBA8 + , kEAGLDrawablePropertyColorFormat + , nil]; + [EAGLContext setCurrentContext:_context]; - [EAGLContext setCurrentContext:_context]; + GL_CHECK(glGenFramebuffers(1, &m_fbo) ); + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) ); - GL_CHECK(glGenFramebuffers(1, &m_fbo) ); - GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) ); + GL_CHECK(glGenRenderbuffers(1, &m_colorRbo) ); + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) ); - GL_CHECK(glGenRenderbuffers(1, &m_colorRbo) ); - GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) ); + [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_layer]; + GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRbo) ); - [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_layer]; - GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRbo) ); + GLint width; + GLint height; + GL_CHECK(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width) ); + GL_CHECK(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height) ); + BX_TRACE("Screen size: %d x %d", width, height); - GLint width; - GLint height; - GL_CHECK(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width) ); - GL_CHECK(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height) ); - BX_TRACE("Screen size: %d x %d", width, height); + m_width = width; + m_height = height; + m_layer = _layer; - m_width = width; - m_height = height; - m_layer = _layer; - - createFrameBuffers(m_width, m_height); + createFrameBuffers(m_width, m_height); } ~SwapChainGL() { - destroyFrameBuffers(); + destroyFrameBuffers(); } - void destroyFrameBuffers() - { - GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) ); - GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0) ); - GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0) ); - if (0 != m_fbo) - { - GL_CHECK(glDeleteFramebuffers(1, &m_fbo) ); - m_fbo = 0; - } + void destroyFrameBuffers() + { + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) ); + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0) ); + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0) ); + if (0 != m_fbo) + { + GL_CHECK(glDeleteFramebuffers(1, &m_fbo) ); + m_fbo = 0; + } - if (0 != m_colorRbo) - { - GL_CHECK(glDeleteRenderbuffers(1, &m_colorRbo) ); - m_colorRbo = 0; - } + if (0 != m_colorRbo) + { + GL_CHECK(glDeleteRenderbuffers(1, &m_colorRbo) ); + m_colorRbo = 0; + } - if (0 != m_depthStencilRbo) - { - GL_CHECK(glDeleteRenderbuffers(1, &m_depthStencilRbo) ); - m_depthStencilRbo = 0; - } - } + if (0 != m_depthStencilRbo) + { + GL_CHECK(glDeleteRenderbuffers(1, &m_depthStencilRbo) ); + m_depthStencilRbo = 0; + } + } - void createFrameBuffers(GLint _width, GLint _height) - { - GL_CHECK(glGenRenderbuffers(1, &m_depthStencilRbo) ); - GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_depthStencilRbo) ); - GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _width, _height) ); // from OES_packed_depth_stencil - GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilRbo) ); - GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilRbo) ); + void createFrameBuffers(GLint _width, GLint _height) + { + GL_CHECK(glGenRenderbuffers(1, &m_depthStencilRbo) ); + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_depthStencilRbo) ); + GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _width, _height) ); // from OES_packed_depth_stencil + GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilRbo) ); + GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilRbo) ); - BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER) - , "glCheckFramebufferStatus failed 0x%08x" - , glCheckFramebufferStatus(GL_FRAMEBUFFER) - ); + BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER) + , "glCheckFramebufferStatus failed 0x%08x" + , glCheckFramebufferStatus(GL_FRAMEBUFFER) + ); - makeCurrent(); - GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 0.0f) ); - GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); - swapBuffers(); - GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); - swapBuffers(); - } + makeCurrent(); + GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 0.0f) ); + GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); + swapBuffers(); + GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); + swapBuffers(); + } void makeCurrent() { - [EAGLContext setCurrentContext:m_context]; - GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) ); + [EAGLContext setCurrentContext:m_context]; + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) ); - GLint newWidth = m_layer.bounds.size.width*[UIScreen mainScreen].scale; - GLint newHeight = m_layer.bounds.size.height*[UIScreen mainScreen].scale; - resize(newWidth, newHeight); + GLint newWidth = m_layer.bounds.size.width*[UIScreen mainScreen].scale; + GLint newHeight = m_layer.bounds.size.height*[UIScreen mainScreen].scale; + resize(newWidth, newHeight); } - void resize(GLint _width, GLint _height) - { - if(m_width == _width && m_height == _height) - { - return; - } + void resize(GLint _width, GLint _height) + { + if(m_width == _width && m_height == _height) + { + return; + } - destroyFrameBuffers(); + destroyFrameBuffers(); - m_width = _width; - m_height = _height; + m_width = _width; + m_height = _height; - createFrameBuffers(m_width, m_height); - } + createFrameBuffers(m_width, m_height); + } void swapBuffers() { - GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) ); - [m_context presentRenderbuffer:GL_RENDERBUFFER]; + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) ); + [m_context presentRenderbuffer:GL_RENDERBUFFER]; } EAGLContext* m_context; - CAEAGLLayer *m_layer; + CAEAGLLayer *m_layer; GLuint m_fbo; GLuint m_colorRbo; GLuint m_depthStencilRbo; - GLint m_width; - GLint m_height; + GLint m_width; + GLint m_height; }; void GlContext::create(uint32_t _width, uint32_t _height) @@ -201,12 +199,12 @@ namespace bgfx { namespace gl , glCheckFramebufferStatus(GL_FRAMEBUFFER) ); - makeCurrent(); - GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 0.0f) ); - GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); - swap(NULL); - GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); - swap(NULL); + makeCurrent(); + GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 0.0f) ); + GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); + swap(NULL); + GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) ); + swap(NULL); import(); @@ -306,18 +304,18 @@ namespace bgfx { namespace gl void GlContext::swap(SwapChainGL* _swapChain) { - makeCurrent(_swapChain); + makeCurrent(_swapChain); - if (NULL == _swapChain) - { - GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) ); - EAGLContext* context = (EAGLContext*)m_context; - [context presentRenderbuffer:GL_RENDERBUFFER]; - } - else - { - _swapChain->swapBuffers(); - } + if (NULL == _swapChain) + { + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) ); + EAGLContext* context = (EAGLContext*)m_context; + [context presentRenderbuffer:GL_RENDERBUFFER]; + } + else + { + _swapChain->swapBuffers(); + } } void GlContext::makeCurrent(SwapChainGL* _swapChain) @@ -328,8 +326,8 @@ namespace bgfx { namespace gl if (NULL == _swapChain) { - [EAGLContext setCurrentContext:(EAGLContext*)m_context]; - GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) ); + [EAGLContext setCurrentContext:(EAGLContext*)m_context]; + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) ); } else { diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 8efc4b672..24ef4c423 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -2562,15 +2562,15 @@ namespace bgfx { namespace gl { FrameBufferGL& frameBuffer = m_frameBuffers[_fbh.idx]; _height = frameBuffer.m_height; - if (UINT16_MAX != frameBuffer.m_denseIdx) - { - m_glctx.makeCurrent(frameBuffer.m_swapChain); - } - else - { - m_glctx.makeCurrent(NULL); - GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.m_fbo[0]) ); - } + if (UINT16_MAX != frameBuffer.m_denseIdx) + { + m_glctx.makeCurrent(frameBuffer.m_swapChain); + } + else + { + m_glctx.makeCurrent(NULL); + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.m_fbo[0]) ); + } } m_fbh = _fbh;