From 5ec3b442e5ecdfdf162309d763037191eb5d3d63 Mon Sep 17 00:00:00 2001 From: Laura Hermanns Date: Wed, 3 Jul 2024 12:54:45 -0400 Subject: [PATCH] [SwapChain] Make default surface visible at creation time with an auto-generated title when creating a swap-chain. The rationale of making the surface invisible when creating a swap-chain was to prevent the window to be visible before it has a valid title. The client programmer was responsible for changing the title and then making the window (or canvas on mobile) visible. This is not an issue when a custom surface is passed into the CreateSwapChain() function, but the default surface never had an initial title. With this change, the default surface is always visible at creation time and an auto-generated title is used to initialzie the window/canvas. If this behavior is undesired, the client programmer can continue to use a custom surface but the default surface is supposed to make things easier. --- .../Renderer/Direct3D11/D3D11SwapChain.cpp | 2 +- .../Renderer/Direct3D12/D3D12SwapChain.cpp | 2 +- sources/Renderer/Metal/MTRenderSystem.mm | 2 +- sources/Renderer/Metal/MTSwapChain.h | 3 +- sources/Renderer/Metal/MTSwapChain.mm | 5 ++-- sources/Renderer/Null/NullRenderSystem.cpp | 6 ++-- sources/Renderer/Null/NullSwapChain.cpp | 8 ++++-- sources/Renderer/Null/NullSwapChain.h | 6 +++- sources/Renderer/OpenGL/GLRenderSystem.cpp | 7 +++++ sources/Renderer/OpenGL/GLSwapChain.cpp | 28 +++++++++++++++++-- sources/Renderer/OpenGL/GLSwapChain.h | 3 ++ sources/Renderer/SwapChain.cpp | 28 ++++++++++++++++++- sources/Renderer/Vulkan/VKRenderSystem.cpp | 2 +- sources/Renderer/Vulkan/VKSwapChain.cpp | 5 ++-- sources/Renderer/Vulkan/VKSwapChain.h | 3 +- 15 files changed, 90 insertions(+), 20 deletions(-) diff --git a/sources/Renderer/Direct3D11/D3D11SwapChain.cpp b/sources/Renderer/Direct3D11/D3D11SwapChain.cpp index fc3d99572d..2107c6d9a3 100644 --- a/sources/Renderer/Direct3D11/D3D11SwapChain.cpp +++ b/sources/Renderer/Direct3D11/D3D11SwapChain.cpp @@ -35,7 +35,7 @@ D3D11SwapChain::D3D11SwapChain( depthBufferLocator_ { ResourceType::Texture, BindFlags::DepthStencilAttachment } { /* Setup surface for the swap-chain */ - SetOrCreateSurface(surface, desc.resolution, desc.fullscreen, nullptr); + SetOrCreateSurface(surface, SwapChain::BuildDefaultSurfaceTitle(renderSystem.GetRendererInfo()), desc.resolution, desc.fullscreen); /* Create D3D objects */ CreateSwapChain(factory, GetResolution(), desc.samples, desc.swapBuffers); diff --git a/sources/Renderer/Direct3D12/D3D12SwapChain.cpp b/sources/Renderer/Direct3D12/D3D12SwapChain.cpp index 789a612870..8b9934654c 100644 --- a/sources/Renderer/Direct3D12/D3D12SwapChain.cpp +++ b/sources/Renderer/Direct3D12/D3D12SwapChain.cpp @@ -44,7 +44,7 @@ D3D12SwapChain::D3D12SwapChain( commandQueue_ = LLGL_CAST(D3D12CommandQueue*, renderSystem_.GetCommandQueue()); /* Setup surface for the swap-chain */ - SetOrCreateSurface(surface, desc.resolution, desc.fullscreen, nullptr); + SetOrCreateSurface(surface, SwapChain::BuildDefaultSurfaceTitle(renderSystem.GetRendererInfo()), desc.resolution, desc.fullscreen); /* Create device resources and window dependent resource */ CreateDescriptorHeaps(renderSystem.GetDevice(), desc.samples); diff --git a/sources/Renderer/Metal/MTRenderSystem.mm b/sources/Renderer/Metal/MTRenderSystem.mm index da82543f57..28e64fdc5f 100644 --- a/sources/Renderer/Metal/MTRenderSystem.mm +++ b/sources/Renderer/Metal/MTRenderSystem.mm @@ -49,7 +49,7 @@ SwapChain* MTRenderSystem::CreateSwapChain(const SwapChainDescriptor& swapChainDesc, const std::shared_ptr& surface) { - return swapChains_.emplace(device_, swapChainDesc, surface); + return swapChains_.emplace(device_, swapChainDesc, surface, GetRendererInfo()); } void MTRenderSystem::Release(SwapChain& swapChain) diff --git a/sources/Renderer/Metal/MTSwapChain.h b/sources/Renderer/Metal/MTSwapChain.h index 8c8ea48833..e23b594a6f 100644 --- a/sources/Renderer/Metal/MTSwapChain.h +++ b/sources/Renderer/Metal/MTSwapChain.h @@ -36,7 +36,8 @@ class MTSwapChain final : public SwapChain MTSwapChain( id device, const SwapChainDescriptor& desc, - const std::shared_ptr& surface + const std::shared_ptr& surface, + const RendererInfo& rendererInfo ); void Present() override; diff --git a/sources/Renderer/Metal/MTSwapChain.mm b/sources/Renderer/Metal/MTSwapChain.mm index 97f323c359..a71075d921 100644 --- a/sources/Renderer/Metal/MTSwapChain.mm +++ b/sources/Renderer/Metal/MTSwapChain.mm @@ -52,13 +52,14 @@ - (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size MTSwapChain::MTSwapChain( id device, const SwapChainDescriptor& desc, - const std::shared_ptr& surface) + const std::shared_ptr& surface, + const RendererInfo& rendererInfo) : SwapChain { desc }, renderPass_ { device, desc } { /* Initialize surface for MetalKit view */ - SetOrCreateSurface(surface, desc.resolution, desc.fullscreen, nullptr); + SetOrCreateSurface(surface, SwapChain::BuildDefaultSurfaceTitle(rendererInfo), desc.resolution, desc.fullscreen); /* Allocate and initialize MetalKit view */ view_ = AllocMTKViewAndInitWithSurface(device, GetSurface()); diff --git a/sources/Renderer/Null/NullRenderSystem.cpp b/sources/Renderer/Null/NullRenderSystem.cpp index 5d4bb2743f..c21c8eb1fb 100644 --- a/sources/Renderer/Null/NullRenderSystem.cpp +++ b/sources/Renderer/Null/NullRenderSystem.cpp @@ -108,7 +108,7 @@ static RenderingCapabilities GetNullRenderingCaps() return caps; } -static RendererInfo GetNullRenderInfo() +static RendererInfo GetNullRendererInfo() { RendererInfo info; info.rendererName = "Null"; @@ -122,7 +122,7 @@ NullRenderSystem::NullRenderSystem(const RenderSystemDescriptor& renderSystemDes desc_ { renderSystemDesc }, commandQueue_ { MakeUnique() } { - SetRendererInfo(GetNullRenderInfo()); + SetRendererInfo(GetNullRendererInfo()); SetRenderingCaps(GetNullRenderingCaps()); } @@ -130,7 +130,7 @@ NullRenderSystem::NullRenderSystem(const RenderSystemDescriptor& renderSystemDes SwapChain* NullRenderSystem::CreateSwapChain(const SwapChainDescriptor& swapChainDesc, const std::shared_ptr& surface) { - return swapChains_.emplace(swapChainDesc, surface); + return swapChains_.emplace(swapChainDesc, surface, GetNullRendererInfo()); } void NullRenderSystem::Release(SwapChain& swapChain) diff --git a/sources/Renderer/Null/NullSwapChain.cpp b/sources/Renderer/Null/NullSwapChain.cpp index 2ea222119a..baadf4062d 100644 --- a/sources/Renderer/Null/NullSwapChain.cpp +++ b/sources/Renderer/Null/NullSwapChain.cpp @@ -35,13 +35,17 @@ static Format ChooseDepthStencilFormat(int depthBits, int stencilBits) } } -NullSwapChain::NullSwapChain(const SwapChainDescriptor& desc, const std::shared_ptr& surface) : +NullSwapChain::NullSwapChain( + const SwapChainDescriptor& desc, + const std::shared_ptr& surface, + const RendererInfo& rendererInfo) +: SwapChain { desc }, samples_ { desc.samples }, colorFormat_ { ChooseColorFormat(desc.colorBits) }, depthStencilFormat_ { ChooseDepthStencilFormat(desc.depthBits, desc.stencilBits) } { - SetOrCreateSurface(surface, desc.resolution, desc.fullscreen, nullptr); + SetOrCreateSurface(surface, SwapChain::BuildDefaultSurfaceTitle(rendererInfo), desc.resolution, desc.fullscreen); if (desc.debugName != nullptr) SetDebugName(desc.debugName); } diff --git a/sources/Renderer/Null/NullSwapChain.h b/sources/Renderer/Null/NullSwapChain.h index 6973fe61eb..468c80c911 100644 --- a/sources/Renderer/Null/NullSwapChain.h +++ b/sources/Renderer/Null/NullSwapChain.h @@ -22,7 +22,11 @@ class NullSwapChain final : public SwapChain public: - NullSwapChain(const SwapChainDescriptor& desc, const std::shared_ptr& surface); + NullSwapChain( + const SwapChainDescriptor& desc, + const std::shared_ptr& surface, + const RendererInfo& rendererInfo + ); public: diff --git a/sources/Renderer/OpenGL/GLRenderSystem.cpp b/sources/Renderer/OpenGL/GLRenderSystem.cpp index cf8b05d05f..58eeb1d9e7 100644 --- a/sources/Renderer/OpenGL/GLRenderSystem.cpp +++ b/sources/Renderer/OpenGL/GLRenderSystem.cpp @@ -77,6 +77,13 @@ SwapChain* GLRenderSystem::CreateSwapChain(const SwapChainDescriptor& swapChainD if (isFirstSwapChain) CreateGLContextDependentDevices(swapChainGL->GetStateManager()); + /* + If no surface was specified, set a default title to the automatically created one now + as we need a valid GL context to query the renderer information for the default title. + */ + if (!surface) + swapChainGL->BuildAndSetDefaultSurfaceTitle(GetRendererInfo()); + return swapChainGL; } diff --git a/sources/Renderer/OpenGL/GLSwapChain.cpp b/sources/Renderer/OpenGL/GLSwapChain.cpp index a2d8507371..db9e75f3a2 100644 --- a/sources/Renderer/OpenGL/GLSwapChain.cpp +++ b/sources/Renderer/OpenGL/GLSwapChain.cpp @@ -8,10 +8,17 @@ #include "GLSwapChain.h" #include "../TextureUtils.h" #include "Platform/GLContextManager.h" +#include #include +#ifdef LLGL_MOBILE_PLATFORM +# include +#else +# include +#endif + #ifdef LLGL_OS_LINUX -#include +# include #endif @@ -38,12 +45,12 @@ GLSwapChain::GLSwapChain( /* Set up surface for the swap-chain and pass native context handle */ NativeHandle windowContext = {}; ChooseGLXVisualAndGetX11WindowContext(pixelFormat, windowContext); - SetOrCreateSurface(surface, desc.resolution, desc.fullscreen, &windowContext, sizeof(windowContext)); + SetOrCreateSurface(surface, UTF8String{}, desc.resolution, desc.fullscreen, &windowContext, sizeof(windowContext)); #else /* Setup surface for the swap-chain */ - SetOrCreateSurface(surface, desc.resolution, desc.fullscreen); + SetOrCreateSurface(surface, UTF8String{}, desc.resolution, desc.fullscreen); #endif @@ -115,6 +122,21 @@ bool GLSwapChain::MakeCurrent(GLSwapChain* swapChain) return GLSwapChainContext::MakeCurrent(nullptr); } +void GLSwapChain::BuildAndSetDefaultSurfaceTitle(const RendererInfo& info) +{ + #ifdef LLGL_MOBILE_PLATFORM + + /* Set Canvas title for mobile platforms */ + CastTo(GetSurface()).SetTitle(SwapChain::BuildDefaultSurfaceTitle(info)); + + #else // LLGL_MOBILE_PLATFORM + + /* Set Window title for desktop platforms */ + CastTo(GetSurface()).SetTitle(SwapChain::BuildDefaultSurfaceTitle(info)); + + #endif // /LLGL_MOBILE_PLATFORM +} + /* * ======= Private: ======= diff --git a/sources/Renderer/OpenGL/GLSwapChain.h b/sources/Renderer/OpenGL/GLSwapChain.h index 8c8eade311..dcdd7e8a3f 100644 --- a/sources/Renderer/OpenGL/GLSwapChain.h +++ b/sources/Renderer/OpenGL/GLSwapChain.h @@ -60,6 +60,9 @@ class GLSwapChain final : public SwapChain // Makes the swap-chain's GL context current and updates the renger-target height in the linked GL state manager. static bool MakeCurrent(GLSwapChain* swapChain); + // Make this function public for GLSwapChain as the default title has to be set outside its constructor due to GL context management. + void BuildAndSetDefaultSurfaceTitle(const RendererInfo& info); + // Returns the state manager of the swap chain's GL context. inline GLStateManager& GetStateManager() { diff --git a/sources/Renderer/SwapChain.cpp b/sources/Renderer/SwapChain.cpp index 266953420d..6db73e7147 100644 --- a/sources/Renderer/SwapChain.cpp +++ b/sources/Renderer/SwapChain.cpp @@ -146,6 +146,7 @@ Surface& SwapChain::GetSurface() const void SwapChain::SetOrCreateSurface( const std::shared_ptr& surface, + const UTF8String& title, const Extent2D& size, bool fullscreen, const void* windowContext, @@ -163,6 +164,7 @@ void SwapChain::SetOrCreateSurface( /* Create new canvas for this swap-chain */ CanvasDescriptor canvasDesc; { + canvasDesc.title = title; canvasDesc.flags = (fullscreen ? CanvasFlags::Borderless : 0); } pimpl_->surface = Canvas::Create(canvasDesc); @@ -172,8 +174,9 @@ void SwapChain::SetOrCreateSurface( /* Create new window for this swap-chain */ WindowDescriptor windowDesc; { + windowDesc.title = title; windowDesc.size = size; - windowDesc.flags = (fullscreen ? WindowFlags::Borderless : WindowFlags::Centered) | WindowFlags::DisableSizeScaling; + windowDesc.flags = WindowFlags::Visible | WindowFlags::DisableSizeScaling | (fullscreen ? WindowFlags::Borderless : WindowFlags::Centered); windowDesc.windowContext = windowContext; windowDesc.windowContextSize = windowContextSize; } @@ -224,6 +227,29 @@ bool SwapChain::ResetDisplayFullscreenMode() return false; } +UTF8String SwapChain::BuildDefaultSurfaceTitle(const RendererInfo& info) +{ + UTF8String title = "LLGL"; + + /* Append surface typename */ + #ifdef LLGL_MOBILE_PLATFORM + title += " Canvas "; + #else + title += " Window "; + #endif + + /* Append swap-chain number */ + static int swapChainCounter; + title += UTF8String{ std::to_string(++swapChainCounter) }; + + /* Append renderer name */ + title += " ( "; + title += UTF8String{ info.rendererName }; + title += " )"; + + return title; +} + /* * ======= Private: ======= diff --git a/sources/Renderer/Vulkan/VKRenderSystem.cpp b/sources/Renderer/Vulkan/VKRenderSystem.cpp index ff920f1ee1..4adad273fc 100644 --- a/sources/Renderer/Vulkan/VKRenderSystem.cpp +++ b/sources/Renderer/Vulkan/VKRenderSystem.cpp @@ -89,7 +89,7 @@ VKRenderSystem::~VKRenderSystem() SwapChain* VKRenderSystem::CreateSwapChain(const SwapChainDescriptor& swapChainDesc, const std::shared_ptr& surface) { - return swapChains_.emplace(instance_, physicalDevice_, device_, *deviceMemoryMngr_, swapChainDesc, surface); + return swapChains_.emplace(instance_, physicalDevice_, device_, *deviceMemoryMngr_, swapChainDesc, surface, GetRendererInfo()); } void VKRenderSystem::Release(SwapChain& swapChain) diff --git a/sources/Renderer/Vulkan/VKSwapChain.cpp b/sources/Renderer/Vulkan/VKSwapChain.cpp index ad1ecf77b8..4d98c5d7c7 100644 --- a/sources/Renderer/Vulkan/VKSwapChain.cpp +++ b/sources/Renderer/Vulkan/VKSwapChain.cpp @@ -54,7 +54,8 @@ VKSwapChain::VKSwapChain( VkDevice device, VKDeviceMemoryManager& deviceMemoryMngr, const SwapChainDescriptor& desc, - const std::shared_ptr& surface) + const std::shared_ptr& surface, + const RendererInfo& rendererInfo) : SwapChain { desc }, instance_ { instance }, @@ -84,7 +85,7 @@ VKSwapChain::VKSwapChain( NullVkFence(device_), NullVkFence(device_) } { - SetOrCreateSurface(surface, desc.resolution, desc.fullscreen, nullptr); + SetOrCreateSurface(surface, SwapChain::BuildDefaultSurfaceTitle(rendererInfo), desc.resolution, desc.fullscreen); CreatePresentSemaphoresAndFences(); CreateGpuSurface(); diff --git a/sources/Renderer/Vulkan/VKSwapChain.h b/sources/Renderer/Vulkan/VKSwapChain.h index afcb2357fb..52a25bcd4e 100644 --- a/sources/Renderer/Vulkan/VKSwapChain.h +++ b/sources/Renderer/Vulkan/VKSwapChain.h @@ -40,7 +40,8 @@ class VKSwapChain final : public SwapChain VkDevice device, VKDeviceMemoryManager& deviceMemoryMngr, const SwapChainDescriptor& desc, - const std::shared_ptr& surface + const std::shared_ptr& surface, + const RendererInfo& rendererInfo ); void Present() override;