From 24ec0a6f372d590ad6da232a6db4cf2f961d2a30 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 3 Feb 2018 14:49:53 -0800 Subject: Reworked swap chain and context initialization on iOS --- Graphics/GraphicsEngineOpenGL/CMakeLists.txt | 10 +- .../GraphicsEngineOpenGL/include/GLContextIOS.h | 19 +--- .../GraphicsEngineOpenGL/include/SwapChainGLIOS.h | 35 +++++-- .../GraphicsEngineOpenGL/include/SwapChainGLImpl.h | 11 ++- Graphics/GraphicsEngineOpenGL/src/GLContextIOS.mm | 19 +--- .../src/RenderDeviceFactoryOpenGL.cpp | 14 ++- .../GraphicsEngineOpenGL/src/SwapChainGLIOS.mm | 104 +++++++++++++++++++-- 7 files changed, 150 insertions(+), 62 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt index 74058c91..5724d876 100644 --- a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt +++ b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt @@ -20,7 +20,6 @@ set(INCLUDE include/SamplerGLImpl.h include/ShaderGLImpl.h include/ShaderResourceBindingGLImpl.h - include/SwapChainGLImpl.h include/TexRegionRender.h include/Texture1D_OGL.h include/Texture1DArray_OGL.h @@ -67,7 +66,6 @@ set(SOURCE src/SamplerGLImpl.cpp src/ShaderGLImpl.cpp src/ShaderResourceBindingGLImpl.cpp - src/SwapChainGLImpl.cpp src/TexRegionRender.cpp src/Texture1D_OGL.cpp src/Texture1DArray_OGL.cpp @@ -83,23 +81,31 @@ set(SOURCE if(PLATFORM_WIN32) list(APPEND SOURCE src/GLContextWindows.cpp) + list(APPEND SOURCE src/SwapChainGLImpl.cpp) list(APPEND INCLUDE include/GLContextWindows.h) + list(APPEND INCLUDE include/SwapChainGLImpl.h) elseif(PLATFORM_ANDROID) list(APPEND SOURCE src/GLContextAndroid.cpp) list(APPEND SOURCE src/RenderDeviceGLESImpl.cpp) list(APPEND SOURCE src/GLStubsAndroid.cpp) + list(APPEND SOURCE src/SwapChainGLImpl.cpp) list(APPEND INCLUDE include/GLContextAndroid.h) list(APPEND INCLUDE include/GLStubsAndroid.h) list(APPEND INCLUDE include/RenderDeviceGLESImpl.h) + list(APPEND INCLUDE include/SwapChainGLImpl.h) list(APPEND INTERFACE interface/RenderDeviceGLES.h) elseif(PLATFORM_LINUX) list(APPEND SOURCE src/GLContextLinux.cpp) + list(APPEND SOURCE src/SwapChainGLImpl.cpp) list(APPEND INCLUDE include/GLContextLinux.h) + list(APPEND INCLUDE include/SwapChainGLImpl.h) elseif(PLATFORM_MACOS) list(APPEND SOURCE src/GLContextMacOS.mm) list(APPEND INCLUDE include/GLContextMacOS.h) + list(APPEND SOURCE src/SwapChainGLImpl.cpp) + list(APPEND INCLUDE include/SwapChainGLImpl.h) elseif(PLATFORM_IOS) list(APPEND SOURCE src/GLContextIOS.mm) list(APPEND INCLUDE include/GLContextIOS.h) diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h b/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h index 5ff74d56..4a343545 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h @@ -23,32 +23,15 @@ #pragma once -#include "GLObjectWrapper.h" - namespace Diligent { - struct ContextInitInfo - { - SwapChainDesc SwapChainAttribs; - void *pNativeWndHandle = nullptr; - }; - class GLContext { public: typedef void* NativeGLContextType; // EAGLContext* - GLContext(const ContextInitInfo &Info, struct DeviceCaps &DeviceCaps); - void SwapBuffers(); - - const SwapChainDesc& GetSwapChainDesc()const{ return m_SwapChainAttribs; } + GLContext(const struct EngineGLAttribs &InitAttribs, struct DeviceCaps &DeviceCaps); NativeGLContextType GetCurrentNativeGLContext(); - - private: - SwapChainDesc m_SwapChainAttribs; - GLObjectWrappers::GLRenderBufferObj m_ColorRenderBuffer; - GLObjectWrappers::GLRenderBufferObj m_DepthRenderBuffer; - GLObjectWrappers::GLFrameBufferObj m_FBO; }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h index d665f4ea..f41b5d52 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h +++ b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h @@ -23,24 +23,43 @@ #pragma once -#include "SwapChainGLImpl.h" +#include "EngineGLAttribs.h" +#include "SwapChainGL.h" +#include "SwapChainBase.h" +#include "GLObjectWrapper.h" namespace Diligent { class IMemoryAllocator; /// Implementation of the Diligent::ISwapChainGL interface on IOS -class SwapChainGLIOS final : public SwapChainGLImpl +class SwapChainGLIOS final : public SwapChainBase { public: + typedef SwapChainBase TSwapChainBase; + SwapChainGLIOS(IReferenceCounters *pRefCounters, - const SwapChainDesc& SwapChainDesc, - class RenderDeviceGLImpl* pRenderDeviceGL, - class DeviceContextGLImpl* pImmediateContextGL); + const EngineGLAttribs &InitAttribs, + const SwapChainDesc& SwapChainDesc, + class RenderDeviceGLImpl* pRenderDeviceGL, + class DeviceContextGLImpl* pImmediateContextGL); + SwapChainGLIOS(); - virtual void Present(); - - virtual void Resize( Uint32 NewWidth, Uint32 NewHeight ); + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; + + virtual void Present()override final; + + virtual void Resize( Uint32 NewWidth, Uint32 NewHeight )override final; + + virtual GLuint GetDefaultFBO()const override final; + +private: + void InitRenderBuffers(bool InitFromDrawable, Uint32 &Width, Uint32 &Height); + + GLObjectWrappers::GLRenderBufferObj m_ColorRenderBuffer; + GLObjectWrappers::GLRenderBufferObj m_DepthRenderBuffer; + GLObjectWrappers::GLFrameBufferObj m_DefaultFBO; + void *m_CALayer; }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h index 87859fb8..01630707 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h @@ -23,6 +23,7 @@ #pragma once +#include "EngineGLAttribs.h" #include "SwapChainGL.h" #include "SwapChainBase.h" #include "GLObjectWrapper.h" @@ -32,7 +33,7 @@ namespace Diligent class IMemoryAllocator; /// Implementation of the Diligent::ISwapChainGL interface -class SwapChainGLImpl : public SwapChainBase +class SwapChainGLImpl final : public SwapChainBase { public: typedef SwapChainBase TSwapChainBase; @@ -44,13 +45,13 @@ public: class DeviceContextGLImpl* pImmediateContextGL); ~SwapChainGLImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; - virtual void Present()override; + virtual void Present()override final; - virtual void Resize( Uint32 NewWidth, Uint32 NewHeight )override; + virtual void Resize( Uint32 NewWidth, Uint32 NewHeight )override final; - virtual GLuint GetDefaultFBO()const override { return 0; } + virtual GLuint GetDefaultFBO()const override final{ return 0; } }; } diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextIOS.mm b/Graphics/GraphicsEngineOpenGL/src/GLContextIOS.mm index 617dd1f8..85520f49 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextIOS.mm +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextIOS.mm @@ -24,31 +24,21 @@ #include "pch.h" #import -#import #include "GLContextIOS.h" #include "DeviceCaps.h" #include "GLTypeConversions.h" +#include "EngineGLAttribs.h" namespace Diligent { - GLContext::GLContext( const ContextInitInfo &Info, DeviceCaps &DeviceCaps ) : - m_SwapChainAttribs(Info.SwapChainAttribs), - m_ColorRenderBuffer(false), - m_DepthRenderBuffer(false), - m_FBO(false) + GLContext::GLContext( const EngineGLAttribs &Info, DeviceCaps &DeviceCaps ) { if (GetCurrentNativeGLContext() == nullptr) { LOG_ERROR_AND_THROW("No current GL context found!"); } - //Set dummy width and height until resize is called by the app - if(m_SwapChainAttribs.Width == 0) - m_SwapChainAttribs.Width = 1024; - if(m_SwapChainAttribs.Height) - m_SwapChainAttribs.Height = 768; - //Checking GL version const GLubyte *GLVersionString = glGetString( GL_VERSION ); const GLubyte *GLRenderer = glGetString(GL_RENDERER); @@ -96,11 +86,6 @@ namespace Diligent DeviceCaps.TexCaps.bTexture2DMSArraySupported = False; } - void GLContext::SwapBuffers() - { - LOG_ERROR("Swap buffers operation must be performed by the app on MacOS"); - } - GLContext::NativeGLContextType GLContext::GetCurrentNativeGLContext() { EAGLContext* CurrentCtx = [EAGLContext currentContext]; diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp index a3945fc2..15f7931b 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp @@ -28,12 +28,17 @@ #include "RenderDeviceFactoryOpenGL.h" #include "RenderDeviceGLImpl.h" #include "DeviceContextGLImpl.h" -#include "SwapChainGLImpl.h" #include "EngineMemory.h" #include "HLSL2GLSLConverterObject.h" +#ifdef PLATFORM_IOS +# include "SwapChainGLIOS.h" +#else +# include "SwapChainGLImpl.h" +#endif + #ifdef PLATFORM_ANDROID - #include "RenderDeviceGLESImpl.h" +# include "RenderDeviceGLESImpl.h" #endif namespace Diligent @@ -41,10 +46,13 @@ namespace Diligent #if defined(PLATFORM_WIN32) || defined(PLATFORM_UNIVERSAL_WINDOWS) || defined(PLATFORM_LINUX) || defined(PLATFORM_MACOS) typedef RenderDeviceGLImpl TRenderDeviceGLImpl; + typedef SwapChainGLImpl TSwapChain; #elif defined(PLATFORM_ANDROID) typedef RenderDeviceGLESImpl TRenderDeviceGLImpl; + typedef SwapChainGLImpl TSwapChain; #elif defined(PLATFORM_IOS) typedef RenderDeviceGLImpl TRenderDeviceGLImpl; + typedef SwapChainGLIOS TSwapChain; #else # error Unsupported platform #endif @@ -112,7 +120,7 @@ void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLAttribs& pDeviceContextOpenGL->QueryInterface(IID_DeviceContext, reinterpret_cast(ppImmediateContext) ); pRenderDeviceOpenGL->SetImmediateContext(pDeviceContextOpenGL); - SwapChainGLImpl *pSwapChainGL = NEW_RC_OBJ(RawMemAllocator, "SwapChainGLImpl instance", SwapChainGLImpl)(CreationAttribs, SCDesc, pRenderDeviceOpenGL, pDeviceContextOpenGL ); + TSwapChain *pSwapChainGL = NEW_RC_OBJ(RawMemAllocator, "SwapChainGLImpl instance", TSwapChain)(CreationAttribs, SCDesc, pRenderDeviceOpenGL, pDeviceContextOpenGL ); pSwapChainGL->QueryInterface(IID_SwapChain, reinterpret_cast(ppSwapChain) ); pDeviceContextOpenGL->SetSwapChain(pSwapChainGL); diff --git a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLIOS.mm b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLIOS.mm index 40f4b1ee..3da0a75b 100644 --- a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLIOS.mm +++ b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLIOS.mm @@ -22,33 +22,119 @@ */ #include "pch.h" + +#import +#import +#import + +#include "DeviceContextGLImpl.h" +#include "RenderDeviceGLImpl.h" #include "SwapChainGLIOS.h" +#include "EngineGLAttribs.h" namespace Diligent { SwapChainGLIOS::SwapChainGLIOS(IReferenceCounters *pRefCounters, - const SwapChainDesc& SCDesc, - RenderDeviceGLImpl* pRenderDeviceGL, - DeviceContextGLImpl* pImmediateContextGL) : - SwapChainGLImpl( pRefCounters, SCDesc, pRenderDeviceGL, pImmediateContextGL ) + const EngineGLAttribs &InitAttribs, + const SwapChainDesc& SCDesc, + RenderDeviceGLImpl* pRenderDeviceGL, + DeviceContextGLImpl* pImmediateContextGL) : + TSwapChainBase( pRefCounters, pRenderDeviceGL, pImmediateContextGL, SCDesc), + m_ColorRenderBuffer(false), + m_DepthRenderBuffer(false), + m_DefaultFBO(false) { + m_CALayer = InitAttribs.pNativeWndHandle; + InitRenderBuffers(true, m_SwapChainDesc.Width, m_SwapChainDesc.Height); } +IMPLEMENT_QUERY_INTERFACE( SwapChainGLIOS, IID_SwapChainGL, TSwapChainBase ) + void SwapChainGLIOS::Present() { + EAGLContext* context = [EAGLContext currentContext]; + glBindRenderbuffer(GL_RENDERBUFFER, m_ColorRenderBuffer); + [context presentRenderbuffer:GL_RENDERBUFFER]; //auto *pDeviceGL = ValidatedCast(m_pRenderDevice.RawPtr()); //pDeviceGL->m_GLContext.SwapBuffers(); } -void SwapChainGLIOS::Resize( Uint32 NewWidth, Uint32 NewHeight ) +void SwapChainGLIOS::InitRenderBuffers(bool InitFromDrawable, Uint32 &Width, Uint32 &Height) { - if( NewWidth != 0 && NewHeight != 0 && - (m_SwapChainDesc.Width != NewWidth || m_SwapChainDesc.Height != NewHeight) ) + EAGLContext* context = [EAGLContext currentContext]; + + m_DefaultFBO.Release(); + m_DefaultFBO.Create(); + glBindFramebuffer(GL_FRAMEBUFFER, m_DefaultFBO); + + m_ColorRenderBuffer.Release(); + m_ColorRenderBuffer.Create(); + glBindRenderbuffer(GL_RENDERBUFFER, m_ColorRenderBuffer); + + if(InitFromDrawable) + { + // This call associates the storage for the current render buffer with the + // EAGLDrawable (our CAEAGLLayer) allowing us to draw into a buffer that + // will later be rendered to the screen wherever the layer is (which + // corresponds with our view). + id drawable = (__bridge id)m_CALayer; + [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:drawable]; + } + else + { + CAEAGLLayer* layer = (__bridge CAEAGLLayer*)m_CALayer; + [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; + } + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_ColorRenderBuffer); + + // Get the drawable buffer's width and height so we can create a depth buffer for the FBO + GLint backingWidth; + GLint backingHeight; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight); + Width = backingWidth; + Height = backingHeight; + + // Create a depth buffer to use with our drawable FBO + m_DepthRenderBuffer.Release(); + m_DepthRenderBuffer.Create(); + glBindRenderbuffer(GL_RENDERBUFFER, m_DepthRenderBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, backingWidth, backingHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_DepthRenderBuffer); + + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - + LOG_ERROR_AND_THROW("Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); } +} + +void SwapChainGLIOS::Resize( Uint32 NewWidth, Uint32 NewHeight ) +{ + InitRenderBuffers(false, NewWidth, NewHeight); - SwapChainGLImpl::Resize(NewWidth, NewHeight); + if( TSwapChainBase::Resize( NewWidth, NewHeight ) ) + { + auto pDeviceContext = m_wpDeviceContext.Lock(); + VERIFY( pDeviceContext, "Immediate context has been released" ); + if( pDeviceContext ) + { + auto *pImmediateCtxGL = ValidatedCast( pDeviceContext.RawPtr() ); + bool bIsDefaultFBBound = pImmediateCtxGL->IsDefaultFBBound(); + + // To update the viewport is the only thing we need to do in OpenGL + if( bIsDefaultFBBound ) + { + // Update viewport + pImmediateCtxGL->SetViewports( 1, nullptr, 0, 0 ); + } + } + } } +GLuint SwapChainGLIOS::GetDefaultFBO()const +{ + return m_DefaultFBO; +} + } -- cgit v1.2.3