fix: memory leaks and heavily optimize the game (#117)

* fixed performance issue on getting texture height for rendering the player model as it loades the player texture on every frame

* updated the lifetime of the texture

* fixed 20 MB memory leak

* delay window display until engine init is done
This commit is contained in:
Joud Kandeel 2026-05-25 21:13:28 +02:00 committed by GitHub
parent 6ed34078fd
commit ef0dad4ffc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 33 additions and 6 deletions

View file

@ -10,7 +10,14 @@ public:
int id;
bool isLoaded;
int ticksSinceLastUse;
static const int UNUSED_TICKS_TO_FREE = 20;
// @CDevJoud
// changing the lifetime of the texture from 20 ticks(1 sec) to 200 ticks (10 sec)
// as it helps the texture to have longer lifetime and reducing the usage of loadTexture for every second/frame
// note that we dont remove the code that removes the textures from `tick()` as it is required in memory limited environment such as older Consoles(PS3/XBOX360)
static const int UNUSED_TICKS_TO_FREE = 200;
//default ctor for int Texture::getHeight(const wstring& url, int backup)
MemTexture() = default;
MemTexture(const wstring& _name, PBYTE pbData, DWORD dwBytes, MemTextureProcessor *processor);
~MemTexture();

View file

@ -1256,8 +1256,14 @@ int Textures::getHeight(const wstring& url, int backup)
if (img)
{
MemTexture* _texture = new MemTexture();
_texture->loadedImage = img;
_texture->isLoaded = true;
_texture->id = getTexture(_texture->loadedImage, C4JRender::TEXTURE_FORMAT_RxGyBzAw, MIPMAP);
int h = img->getHeight();
delete img;
//delete img; // commenting this out and inserting the loaded texture to memTextures unordered_map
this->memTextures[url] = _texture;
return h;
}

View file

@ -824,8 +824,7 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
return FALSE;
}
ShowWindow(g_hWnd, (nCmdShow != SW_HIDE) ? SW_SHOWMAXIMIZED : nCmdShow);
UpdateWindow(g_hWnd);
return TRUE;
}
@ -1456,8 +1455,9 @@ void CleanupDevice()
static Minecraft* InitialiseMinecraftRuntime()
{
app.loadMediaArchive();
RenderManager.Initialise(g_pd3dDevice, g_pSwapChain);
// @CDevJoud: No need to call this method as it gets called once in `InitDevice()`
// Calling it again and it results of 20MB of memory leak!
//RenderManager.Initialise(g_pd3dDevice, g_pSwapChain);
app.loadStringTable();
ui.init(g_pd3dDevice, g_pImmediateContext, g_pRenderTargetView, g_pDepthStencilView, g_rScreenWidth, g_rScreenHeight);
@ -1790,6 +1790,20 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
hr = XuiTimersRun();
}
#endif
// @CDevJoud The window should only be shown after the engine/game
// initialization has fully completed.
//
// Showing the window too early especially on low end devices,
// may cause windows to display a "Not Responding" state while
// initialization is still in progress.
//
// This creates an unprofessional first impression for the player.
// Instead, initialize all engine systems first, then display the
// window once everything is ready.
ShowWindow(g_hWnd, (nCmdShow != SW_HIDE) ? SW_SHOWMAXIMIZED : nCmdShow);
UpdateWindow(g_hWnd);
MSG msg = {0};
while( WM_QUIT != msg.message && !app.m_bShutdown)
{