Skip to content

Commit

Permalink
Bugfix: NetImguiServer memory leak
Browse files Browse the repository at this point in the history
-Was leaking ImDrawList object, since ImDrawData doesn't take care of delete them on free
  • Loading branch information
sammyfreg committed Jan 31, 2022
1 parent cbed2ef commit 8883df5
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 18 deletions.
8 changes: 4 additions & 4 deletions Code/Client/NetImgui_Api.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
//! @Name : NetImgui
//=================================================================================================
//! @author : Sammy Fatnassi
//! @date : 2022/01/30
//! @version : v1.7.4
//! @date : 2022/01/31
//! @version : v1.7.5
//! @Details : For integration info : https://github.com/sammyfreg/netImgui/wiki
//=================================================================================================
#define NETIMGUI_VERSION "1.7.4"
#define NETIMGUI_VERSION_NUM 10704
#define NETIMGUI_VERSION "1.7.5"
#define NETIMGUI_VERSION_NUM 10705


#ifdef NETIMGUI_IMPLEMENTATION
Expand Down
26 changes: 16 additions & 10 deletions Code/ServerApp/Source/NetImguiServer_RemoteClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ namespace NetImguiServer { namespace RemoteClient
static Client* gpClients = nullptr; // Table of all potentially connected clients to this server
static uint32_t gClientCountMax = 0;

NetImguiImDrawData::NetImguiImDrawData()
: mCommandList(nullptr)
{
CmdListsCount = 1; // All draws collapsed in same CmdList
mpCommandList = &mCommandList;
CmdLists = &mpCommandList;
}


Client::Client()
: mPendingTextureReadIndex(0)
, mPendingTextureWriteIndex(0)
Expand Down Expand Up @@ -60,8 +69,8 @@ void Client::ReceiveDrawFrame(NetImgui::Internal::CmdDrawFrame* pFrameData)
{
// Convert DrawFrame command to Dear Imgui DrawData,
// and make it available for main thread to use in rendering
mpFrameDrawPrev = pFrameData;
ImDrawData* pNewDrawData = ConvertToImguiDrawData(pFrameData);
mpFrameDrawPrev = pFrameData;
NetImguiImDrawData* pNewDrawData = ConvertToImguiDrawData(pFrameData);
mPendingImguiDrawDataIn.Assign(pNewDrawData);

// Update framerate
Expand Down Expand Up @@ -206,10 +215,10 @@ uint32_t Client::GetFreeIndex()
//=================================================================================================
// Get the current Dear Imgui drawdata to use for this client rendering content
//=================================================================================================
ImDrawData* Client::GetImguiDrawData(void* pEmtpyTextureHAL)
NetImguiImDrawData* Client::GetImguiDrawData(void* pEmtpyTextureHAL)
{
// Check if a new frame has been added. If yes, then take ownership of it.
ImDrawData* pPendingDrawData = mPendingImguiDrawDataIn.Release();
NetImguiImDrawData* pPendingDrawData = mPendingImguiDrawDataIn.Release();
if( pPendingDrawData )
{
NetImgui::Internal::netImguiDeleteSafe( mpImguiDrawData );
Expand Down Expand Up @@ -244,7 +253,7 @@ ImDrawData* Client::GetImguiDrawData(void* pEmtpyTextureHAL)
//=================================================================================================
// Create a new Dear Imgui DrawData ready to be submitted for rendering
//=================================================================================================
ImDrawData* Client::ConvertToImguiDrawData(const NetImgui::Internal::CmdDrawFrame* pCmdDrawFrame)
NetImguiImDrawData* Client::ConvertToImguiDrawData(const NetImgui::Internal::CmdDrawFrame* pCmdDrawFrame)
{
constexpr float kPosRangeMin = static_cast<float>(NetImgui::Internal::ImguiVert::kPosRange_Min);
constexpr float kPosRangeMax = static_cast<float>(NetImgui::Internal::ImguiVert::kPosRange_Max);
Expand All @@ -256,9 +265,9 @@ ImDrawData* Client::ConvertToImguiDrawData(const NetImgui::Internal::CmdDrawFram
}
mMouseCursor = static_cast<ImGuiMouseCursor>(pCmdDrawFrame->mMouseCursor);

ImDrawData* pDrawData = NetImgui::Internal::netImguiNew<ImDrawData>();
NetImguiImDrawData* pDrawData = NetImgui::Internal::netImguiNew<NetImguiImDrawData>();
ImDrawList* pCmdList = pDrawData->CmdLists[0];
pDrawData->Valid = true;
pDrawData->CmdListsCount = 1; // All draws collapsed in same CmdList
pDrawData->TotalVtxCount = static_cast<int>(pCmdDrawFrame->mTotalVerticeCount);
pDrawData->TotalIdxCount = static_cast<int>(pCmdDrawFrame->mTotalIndiceCount);
pDrawData->DisplayPos.x = pCmdDrawFrame->mDisplayArea[0];
Expand All @@ -267,9 +276,6 @@ ImDrawData* Client::ConvertToImguiDrawData(const NetImgui::Internal::CmdDrawFram
pDrawData->DisplaySize.y = pCmdDrawFrame->mDisplayArea[3] - pCmdDrawFrame->mDisplayArea[1];
pDrawData->FramebufferScale = ImVec2(1,1); //! @sammyfreg Currently untested, so force set to 1
pDrawData->OwnerViewport = nullptr;
pDrawData->CmdLists = NetImgui::Internal::netImguiNew<ImDrawList*>();
pDrawData->CmdLists[0] = NetImgui::Internal::netImguiNew<ImDrawList>(nullptr);
ImDrawList* pCmdList = pDrawData->CmdLists[0];

uint32_t indexOffset(0), vertexOffset(0);
pCmdList->IdxBuffer.resize(pCmdDrawFrame->mTotalIndiceCount);
Expand Down
26 changes: 22 additions & 4 deletions Code/ServerApp/Source/NetImguiServer_RemoteClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,30 @@
namespace NetImguiServer { namespace RemoteClient
{

//=================================================================================================
// ImDrawData wrapper
//
// Allocate a single ImDrawList and assign it to itself.
//
// This child class leave the original ImDrawData behavior intact, but add the proper
// memory freeing of the ImDrawList member.
//=================================================================================================
struct NetImguiImDrawData : ImDrawData
{
NetImguiImDrawData();
ImDrawList mCommandList;
ImDrawList* mpCommandList = nullptr;
};

//=================================================================================================
// All info needed by the server to communicate with a remote client, and render its content
//=================================================================================================
struct Client
{
static constexpr uint32_t kInvalidClient = static_cast<uint32_t>(-1);
using ExchPtrInput = NetImgui::Internal::ExchangePtr<NetImgui::Internal::CmdInput>;
using ExchPtrBackground = NetImgui::Internal::ExchangePtr<NetImgui::Internal::CmdBackground>;
using ExchPtrImguiDraw = NetImgui::Internal::ExchangePtr<ImDrawData>;
using ExchPtrImguiDraw = NetImgui::Internal::ExchangePtr<NetImguiImDrawData>;
Client();
~Client();
Client(const Client&) = delete;
Expand All @@ -24,8 +42,8 @@ struct Client

void ReceiveTexture(NetImgui::Internal::CmdTexture*);
void ReceiveDrawFrame(NetImgui::Internal::CmdDrawFrame*);
ImDrawData* ConvertToImguiDrawData(const NetImgui::Internal::CmdDrawFrame* pCmdDrawFrame);
ImDrawData* GetImguiDrawData(void* pEmtpyTextureHAL); // Get current active Imgui draw data
NetImguiImDrawData* ConvertToImguiDrawData(const NetImgui::Internal::CmdDrawFrame* pCmdDrawFrame);
NetImguiImDrawData* GetImguiDrawData(void* pEmtpyTextureHAL); // Get current active Imgui draw data

void CaptureImguiInput();
NetImgui::Internal::CmdInput* TakePendingInput();
Expand All @@ -46,7 +64,7 @@ struct Client
char mConnectHost[64] = {}; //!< Connected Hostname of this remote client
int mConnectPort = 0; //!< Connected Port of this remote client

ImDrawData* mpImguiDrawData = nullptr; //!< Current Imgui Data that this client is the owner of
NetImguiImDrawData* mpImguiDrawData = nullptr; //!< Current Imgui Data that this client is the owner of
NetImgui::Internal::CmdDrawFrame* mpFrameDrawPrev = nullptr; //!< Last valid DrawDrame (used by com thread, to uncompress data)
std::vector<App::ServerTexture> mvTextures; //!< List of textures received and used by the client
ExchPtrImguiDraw mPendingImguiDrawDataIn; //!< Pending received Imgui DrawData, waiting to be taken ownership of
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ Related projects making use of **NetImgui**.
- ~~Commands to assign custom backgrounds~~
- ~~Add compression to data between Client and Server~~

### Version 1.7.5
(2022/01/31)
- **API Changes**
- None
- **Bug fixes**
- NetImgui Server memory leak fix

### Version 1.7.4
(2022/01/30)
- **API Changes**
Expand Down

0 comments on commit 8883df5

Please sign in to comment.