Skip to content

Commit

Permalink
Restructured the order in which application lifecycle events occur. F…
Browse files Browse the repository at this point in the history
…ixed a bug Fixed a bug in OpenGL graphics system regarding FBOs.
  • Loading branch information
pboechat committed Nov 30, 2024
1 parent 4fbf744 commit bdfa06c
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 73 deletions.
3 changes: 1 addition & 2 deletions FastCG/include/FastCG/Graphics/BaseGraphicsSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ namespace FastCG
inline const Shader *FindShader(const std::string &rName) const;
inline const Texture *GetMissingTexture(TextureType textureType) const;
inline void Synchronize();
inline void OnPostWindowInitialize();
inline void OnPreWindowTerminate();
inline void OnPostWindowInitialize(void *pWindow);

protected:
const GraphicsSystemArgs mArgs;
Expand Down
6 changes: 5 additions & 1 deletion FastCG/include/FastCG/Graphics/OpenGL/OpenGLGraphicsSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <cstring>
#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>

namespace FastCG
Expand Down Expand Up @@ -74,8 +75,10 @@ namespace FastCG
EGLContext mContext{EGL_NO_CONTEXT};
EGLSurface mSurface{EGL_NO_SURFACE};
#endif
using Fbo = std::pair<size_t, GLuint>;
std::unordered_map<size_t, GLuint, IdentityHasher<size_t>> mFboIds;
std::unordered_map<GLint, std::vector<size_t>, IdentityHasher<GLint>> mTextureToFboHashes;
std::unordered_map<GLint, std::vector<Fbo>, IdentityHasher<GLint>> mTextureIdToFbos;
std::unordered_map<GLuint, std::vector<GLint>, IdentityHasher<GLuint>> mFboIdToTextureIds;
std::unordered_map<size_t, GLuint, IdentityHasher<size_t>> mVaoIds;
DeviceProperties mDeviceProperties{};
GLsync mFrameFences[2]{nullptr, nullptr}; // double-buffered
Expand All @@ -95,6 +98,7 @@ namespace FastCG
GLuint GetOrCreateFramebuffer(const OpenGLTexture *const *pRenderTargets, uint32_t renderTargetCount,
const OpenGLTexture *pDepthStencilBuffer);
GLuint GetOrCreateVertexArray(const OpenGLBuffer *const *pBuffers, uint32_t bufferCount);
void DeleteFbo(const Fbo &rFbo);
void NotifyPreContextCreate();
void NotifyPostContextCreate();

Expand Down
4 changes: 3 additions & 1 deletion FastCG/include/FastCG/Graphics/Vulkan/VulkanGraphicsSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ namespace FastCG
void Submit();
void WaitPreviousFrame();
void OnPostWindowInitialize(void *pWindow);
void OnPreWindowTerminate(void *pWindow);
void OnPreWindowTerminate(void *pWindow)
{
}

protected:
using Super = BaseGraphicsSystem<VulkanBuffer, VulkanGraphicsContext, VulkanShader, VulkanTexture>;
Expand Down
2 changes: 1 addition & 1 deletion FastCG/include/FastCG/Platform/Linux/X11Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace FastCG
protected:
void OnPreInitialize() override;
void OnPostInitialize() override;
void OnPreFinalize() override;
void OnPostFinalize() override;
void RunMainLoop() override;
void RunConsoleMainLoop();
void RunWindowedMainLoop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace FastCG

protected:
void OnPostInitialize() override;
void OnPreFinalize() override;
void OnPostFinalize() override;
void RunMainLoop() override;

private:
Expand Down
103 changes: 66 additions & 37 deletions FastCG/src/Graphics/OpenGL/OpenGLGraphicsSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,19 @@ namespace
FASTCG_THROW_EXCEPTION(FastCG::Exception, "GLX: GLX_ARB_create_context extension not supported");
}

const int contextAttribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB,
4,
GLX_CONTEXT_MINOR_VERSION_ARB,
3,
GLX_CONTEXT_PROFILE_MASK_ARB,
GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
GLX_CONTEXT_FLAGS_ARB,
GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
const int contextAttribs[] = {GLX_CONTEXT_MAJOR_VERSION_ARB,
4,
GLX_CONTEXT_MINOR_VERSION_ARB,
3,
GLX_CONTEXT_PROFILE_MASK_ARB,
GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
GLX_CONTEXT_FLAGS_ARB,
GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
#if _DEBUG
| GLX_CONTEXT_DEBUG_BIT_ARB
| GLX_CONTEXT_DEBUG_BIT_ARB
#endif
,
0
};
,
0};

auto *pOldErrorHandler = XSetErrorHandler(&GLXContextErrorHandler);
auto context = glXCreateContextAttribsARB(pDisplay, fbConfig, oldContext, True, contextAttribs);
Expand Down Expand Up @@ -139,21 +137,19 @@ namespace
FASTCG_THROW_EXCEPTION(FastCG::Exception, "WGL: WGL_ARB_create_context extension not supported");
}

const int contextAttribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB,
4,
WGL_CONTEXT_MINOR_VERSION_ARB,
3,
WGL_CONTEXT_PROFILE_MASK_ARB,
WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_CONTEXT_FLAGS_ARB,
WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
const int contextAttribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB,
4,
WGL_CONTEXT_MINOR_VERSION_ARB,
3,
WGL_CONTEXT_PROFILE_MASK_ARB,
WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_CONTEXT_FLAGS_ARB,
WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
#if _DEBUG
| WGL_CONTEXT_DEBUG_BIT_ARB
| WGL_CONTEXT_DEBUG_BIT_ARB
#endif
,
0
};
,
0};

auto context = wglCreateContextAttribsARB(deviceContext, parentContext, contextAttribs);
if (context == nullptr)
Expand Down Expand Up @@ -257,16 +253,13 @@ namespace FastCG
assert(pTexture != nullptr);
// delete fbos that reference the texture to be deleted
{
auto it = mTextureToFboHashes.find(*pTexture);
if (it != mTextureToFboHashes.end())
auto it1 = mTextureIdToFbos.find(*pTexture);
if (it1 != mTextureIdToFbos.end())
{
for (auto fboHash : it->second)
auto fbos = it1->second;
for (auto &rFbo : fbos)
{
if (mFboIds.find(fboHash) != mFboIds.end())
{
FASTCG_CHECK_OPENGL_CALL(glDeleteFramebuffers(1, &mFboIds[fboHash]));
mFboIds.erase(fboHash);
}
DeleteFbo(rFbo);
}
}
}
Expand Down Expand Up @@ -385,12 +378,17 @@ namespace FastCG

mFboIds.emplace(fboHash, fboId);

std::for_each(pRenderTargets, pRenderTargets + renderTargetCount,
[&](const auto *pRenderTarget) { mTextureToFboHashes[*pRenderTarget].emplace_back(fboHash); });
std::for_each(pRenderTargets, pRenderTargets + renderTargetCount, [&](const auto *pRenderTarget) {
auto renderTargetId = (GLint)(*pRenderTarget);
mTextureIdToFbos[renderTargetId].emplace_back(fboHash, fboId);
mFboIdToTextureIds[fboId].emplace_back(renderTargetId);
});

if (pDepthStencilBuffer != nullptr)
{
mTextureToFboHashes[*pDepthStencilBuffer].emplace_back(fboHash);
auto depthStencilBufferId = (GLint)(*pDepthStencilBuffer);
mTextureIdToFbos[depthStencilBufferId].emplace_back(fboHash, fboId);
mFboIdToTextureIds[fboId].emplace_back(depthStencilBufferId);
}

FASTCG_CHECK_OPENGL_CALL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oldFboId));
Expand Down Expand Up @@ -445,6 +443,35 @@ namespace FastCG
return vaoId;
}

void OpenGLGraphicsSystem::DeleteFbo(const Fbo &rFbo)
{
assert(rFbo.second > 0);
FASTCG_CHECK_OPENGL_CALL(glDeleteFramebuffers(1, &rFbo.second));
auto it1 = mFboIdToTextureIds.find(rFbo.second);
if (it1 != mFboIdToTextureIds.end())
{
for (auto textureId : it1->second)
{
auto it2 = mTextureIdToFbos.find(textureId);
assert(it2 != mTextureIdToFbos.end());
auto &rFbos = it2->second;
auto it3 = std::find_if(rFbos.begin(), rFbos.end(), [&rFbo](const Fbo &rOtherFbo) {
return rOtherFbo.first == rFbo.first && rOtherFbo.second == rFbo.second;
});
assert(it3 != rFbos.end());
rFbos.erase(it3);
if (rFbos.empty())
{
mTextureIdToFbos.erase(it2);
}
}
mFboIdToTextureIds.erase(it1);
}
auto it4 = mFboIds.find(rFbo.first);
assert(it4 != mFboIds.end());
mFboIds.erase(it4);
}

void OpenGLGraphicsSystem::CreateOpenGLHeadlessContext()
{
NotifyPreContextCreate();
Expand Down Expand Up @@ -1088,6 +1115,8 @@ namespace FastCG
FASTCG_CHECK_OPENGL_CALL(glDeleteFramebuffers(1, &rKvp.second));
}
mFboIds.clear();
mTextureIdToFbos.clear();
mFboIdToTextureIds.clear();

for (const auto &rKvp : mVaoIds)
{
Expand Down
14 changes: 4 additions & 10 deletions FastCG/src/Graphics/Vulkan/VulkanGraphicsSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ namespace FastCG
DestroySurface();
DestroyInstance();

mSurfaceCapabilities = {};
mPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
mSurfaceSwapChainFormat = {};

BaseGraphicsSystem::OnPostFinalize();
}

Expand Down Expand Up @@ -2035,16 +2039,6 @@ namespace FastCG
RecreateSwapChain();
}

void VulkanGraphicsSystem::OnPreWindowTerminate(void *pWindow)
{
mSurfaceCapabilities = {};
mPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
mSurfaceSwapChainFormat = {};
DestroySwapChain();
DestroySurface();
CreateSurfacelessSwapChain();
}

void VulkanGraphicsSystem::Submit()
{
GetImmediateGraphicsContext()->End();
Expand Down
12 changes: 6 additions & 6 deletions FastCG/src/Platform/BaseApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,6 @@ namespace FastCG

void BaseApplication::Initialize()
{
FASTCG_LOG_DEBUG(BaseApplication, "Pre-initializing application");
OnPreInitialize();

{
FASTCG_LOG_DEBUG(BaseApplication, "Creating systems");

Expand All @@ -168,6 +165,9 @@ namespace FastCG
WorldSystem::Create({mScreenWidth, mScreenHeight});
}

FASTCG_LOG_DEBUG(BaseApplication, "Pre-initializing application");
OnPreInitialize();

{
FASTCG_LOG_DEBUG(BaseApplication, "Initializing systems");

Expand Down Expand Up @@ -200,6 +200,9 @@ namespace FastCG
GraphicsSystem::GetInstance()->Finalize();
}

FASTCG_LOG_DEBUG(BaseApplication, "Post-finalizing application");
OnPostFinalize();

{
FASTCG_LOG_DEBUG(BaseApplication, "Destroying systems");
WorldSystem::Destroy();
Expand All @@ -212,9 +215,6 @@ namespace FastCG
#endif
AssetSystem::Destroy();
}

FASTCG_LOG_DEBUG(BaseApplication, "Post-finalizing application");
OnPostFinalize();
}

void BaseApplication::RunMainLoopIteration(double osTime)
Expand Down
11 changes: 4 additions & 7 deletions FastCG/src/Platform/Linux/X11Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ namespace
#undef MAP_KEY
#endif

#define MAP_KEY(a, b) \
{ \
(uint64_t) a, FastCG::Key::b \
}
#define MAP_KEY(a, b) {(uint64_t)a, FastCG::Key::b}

std::unordered_map<uint64_t, FastCG::Key> KEY_LUT = {MAP_KEY(XK_BackSpace, BACKSPACE),
MAP_KEY(XK_Return, RETURN),
Expand Down Expand Up @@ -178,10 +175,8 @@ namespace FastCG
BaseApplication::OnPostInitialize();
}

void X11Application::OnPreFinalize()
void X11Application::OnPostFinalize()
{
BaseApplication::OnPreFinalize();

if (!mSettings.graphics.headless)
{
// NOTE: on X11 the graphics system is responsible for creating the window
Expand All @@ -194,6 +189,8 @@ namespace FastCG
XCloseDisplay(mpDisplay);
mpDisplay = nullptr;
}

BaseApplication::OnPostFinalize();
}

void X11Application::RunMainLoop()
Expand Down
11 changes: 4 additions & 7 deletions FastCG/src/Platform/Windows/WindowsApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ namespace
#undef MAP_KEY
#endif

#define MAP_KEY(a, b) \
{ \
(uint64_t) a, FastCG::Key::b \
}
#define MAP_KEY(a, b) {(uint64_t)a, FastCG::Key::b}

const std::unordered_map<uint64_t, FastCG::Key> VIRTUAL_KEY_LUT = {MAP_KEY(VK_LEFT, LEFT_ARROW),
MAP_KEY(VK_UP, UP_ARROW),
Expand Down Expand Up @@ -165,15 +162,15 @@ namespace FastCG
BaseApplication::OnPostInitialize();
}

void WindowsApplication::OnPreFinalize()
void WindowsApplication::OnPostFinalize()
{
BaseApplication::OnPreFinalize();

if (!mSettings.graphics.headless && IsWindow(mHWnd))
{
GraphicsSystem::GetInstance()->OnPreWindowTerminate(mHWnd);
TerminateWindow();
}

BaseApplication::OnPostFinalize();
}

void WindowsApplication::RunMainLoop()
Expand Down

0 comments on commit bdfa06c

Please sign in to comment.