From e4690a57b82087125db2ba3d71b8bffffd164f62 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Sun, 4 Jan 2026 03:35:42 +0100 Subject: [PATCH] Plug leaks until Information Center, detected by the LeakSanitizer (#764) --- ISLE/isleapp.cpp | 1 + LEGO1/lego/legoomni/src/main/legomain.cpp | 5 +++++ LEGO1/lego/legoomni/src/video/legovideomanager.cpp | 14 ++++++++++++++ LEGO1/lego/sources/3dmanager/legoview1.cpp | 10 ++++++---- LEGO1/lego/sources/3dmanager/tglsurface.cpp | 4 ++++ LEGO1/mxdirectx/mxdirect3d.cpp | 2 ++ LEGO1/mxdirectx/mxdirectxinfo.cpp | 4 ++++ LEGO1/omni/include/mxmediapresenter.h | 8 ++++---- LEGO1/omni/src/audio/mxsoundpresenter.cpp | 8 ++++---- LEGO1/omni/src/common/mxmediapresenter.cpp | 14 ++++++++++++++ LEGO1/tgl/d3drm/view.cpp | 2 -- LEGO1/viewmanager/viewmanager.cpp | 6 +++--- miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp | 5 +++++ miniwin/src/d3drm/d3drmdevice.cpp | 6 +++++- miniwin/src/d3drm/d3drmframe.cpp | 3 --- miniwin/src/d3drm/d3drmmesh.cpp | 3 +++ miniwin/src/d3drm/d3drmviewport.cpp | 14 +++++++++++--- miniwin/src/internal/d3drmrenderer_sdl3gpu.h | 2 +- miniwin/src/internal/d3drmviewport_impl.h | 1 + miniwin/src/windows/windows.cpp | 3 +++ 20 files changed, 90 insertions(+), 25 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 3ce21e91..29f8334e 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -483,6 +483,7 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) if (device && !device->ConvertEventToRenderCoordinates(event)) { SDL_Log("Failed to convert event coordinates: %s", SDL_GetError()); } + device->Release(); #ifdef __EMSCRIPTEN__ Emscripten_ConvertEventToRenderCoordinates(event); diff --git a/LEGO1/lego/legoomni/src/main/legomain.cpp b/LEGO1/lego/legoomni/src/main/legomain.cpp index 6949638b..0f455d7a 100644 --- a/LEGO1/lego/legoomni/src/main/legomain.cpp +++ b/LEGO1/lego/legoomni/src/main/legomain.cpp @@ -155,6 +155,11 @@ void LegoOmni::Destroy() m_transitionManager = NULL; } + if (m_videoManager) { + delete m_videoManager; + m_videoManager = NULL; + } + m_action.ClearAtom(); DestroyScripts(); diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index b0e2a7bf..3aa6044f 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -54,6 +54,8 @@ LegoVideoManager::LegoVideoManager() m_unk0xe5 = FALSE; m_unk0x554 = FALSE; m_paused = FALSE; + m_camera = NULL; + m_appdata = NULL; } // FUNCTION: LEGO1 0x1007ab40 @@ -237,6 +239,11 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM // FUNCTION: BETA10 0x100d6816 void LegoVideoManager::Destroy() { + if (m_camera != NULL) { + m_camera->Release(); + m_camera = NULL; + } + if (m_cursorSurface != NULL) { m_cursorSurface->Release(); m_cursorSurface = NULL; @@ -264,6 +271,12 @@ void LegoVideoManager::Destroy() delete m_3dManager; MxVideoManager::Destroy(); + + if (m_direct3d != NULL) { + delete m_direct3d; + m_direct3d = NULL; + } + delete m_phonemeRefList; delete m_stopWatch; } @@ -677,6 +690,7 @@ int LegoVideoManager::EnableRMDevice() d3drmDev2->SetDither(m_dither); d3drmDev2->SetBufferCount(m_bufferCount); m_camera->Release(); + m_camera = nullptr; if (viewport->AddDestroyCallback(ViewportDestroyCallback, m_appdata) == D3DRM_OK) { ((TglImpl::ViewImpl*) m_3dManager->GetLego3DView()->GetView())->SetImplementationData(viewport); diff --git a/LEGO1/lego/sources/3dmanager/legoview1.cpp b/LEGO1/lego/sources/3dmanager/legoview1.cpp index cfc70a3b..cc6c58e0 100644 --- a/LEGO1/lego/sources/3dmanager/legoview1.cpp +++ b/LEGO1/lego/sources/3dmanager/legoview1.cpp @@ -57,19 +57,21 @@ BOOL LegoView::Create(const TglSurface::CreateStruct& rCreateStruct, Tgl::Render viewAngle = 90; } + assert(!m_pScene); m_pScene = pRenderer->CreateGroup(); assert(m_pScene); // TglSurface::Create() calls CreateView(), and we need the camera in // CreateView(), so create camera before calling TglSurface::Create() + assert(!m_pCamera); m_pCamera = pRenderer->CreateCamera(); assert(m_pCamera); if (!TglSurface::Create(rCreateStruct, pRenderer, m_pScene)) { delete m_pScene; - m_pScene = 0; + m_pScene = NULL; delete m_pCamera; - m_pCamera = 0; + m_pCamera = NULL; return FALSE; } @@ -96,10 +98,10 @@ Tgl::View* LegoView::CreateView(Tgl::Renderer* pRenderer, Tgl::Device* pDevice) void LegoView::Destroy() { delete m_pScene; - m_pScene = 0; + m_pScene = NULL; delete m_pCamera; - m_pCamera = 0; + m_pCamera = NULL; TglSurface::Destroy(); } diff --git a/LEGO1/lego/sources/3dmanager/tglsurface.cpp b/LEGO1/lego/sources/3dmanager/tglsurface.cpp index f9b2ab42..1b16addb 100644 --- a/LEGO1/lego/sources/3dmanager/tglsurface.cpp +++ b/LEGO1/lego/sources/3dmanager/tglsurface.cpp @@ -86,6 +86,9 @@ BOOL TglSurface::Create(const CreateStruct& rCreateStruct, Renderer* pRenderer, int textureColorCount = -1; Result result; + assert(!m_pRenderer); + assert(!m_pScene); + assert(!m_pDevice); m_pRenderer = pRenderer; m_pScene = pScene; m_pDevice = m_pRenderer->CreateDevice(createData); @@ -145,6 +148,7 @@ BOOL TglSurface::Create(const CreateStruct& rCreateStruct, Renderer* pRenderer, m_width = m_pDevice->GetWidth(); m_height = m_pDevice->GetHeight(); + assert(!m_pView); m_pView = CreateView(m_pRenderer, m_pDevice); if (!m_pView) { delete m_pDevice; diff --git a/LEGO1/mxdirectx/mxdirect3d.cpp b/LEGO1/mxdirectx/mxdirect3d.cpp index f09f0cf1..d3ca4579 100644 --- a/LEGO1/mxdirectx/mxdirect3d.cpp +++ b/LEGO1/mxdirectx/mxdirect3d.cpp @@ -139,6 +139,7 @@ BOOL MxDirect3D::D3DCreate() Error("Creation of IDirect3D failed", result); return FALSE; } + m_pDirect3d->Release(); return TRUE; } @@ -181,6 +182,7 @@ BOOL MxDirect3D::D3DSetMode() } LPDIRECTDRAWSURFACE backBuf = BackBuffer(); + assert(!m_pDirect3dDevice); HRESULT result = m_pDirect3d->CreateDevice(m_currentDeviceInfo->m_guid, backBuf, &m_pDirect3dDevice); if (result != DD_OK) { diff --git a/LEGO1/mxdirectx/mxdirectxinfo.cpp b/LEGO1/mxdirectx/mxdirectxinfo.cpp index 765d32f7..03305124 100644 --- a/LEGO1/mxdirectx/mxdirectxinfo.cpp +++ b/LEGO1/mxdirectx/mxdirectxinfo.cpp @@ -275,6 +275,10 @@ BOOL MxDeviceEnumerate::EnumDirectDrawCallback(LPGUID p_guid, LPSTR p_driverDesc } done: + if (miniwind3d) { + miniwind3d->Release(); + } + if (lpDirect3d2) { lpDirect3d2->Release(); } diff --git a/LEGO1/omni/include/mxmediapresenter.h b/LEGO1/omni/include/mxmediapresenter.h index 3cfee4bd..d3438197 100644 --- a/LEGO1/omni/include/mxmediapresenter.h +++ b/LEGO1/omni/include/mxmediapresenter.h @@ -57,10 +57,10 @@ class MxMediaPresenter : public MxPresenter { // MxMediaPresenter::`scalar deleting destructor' protected: - MxDSSubscriber* m_subscriber; // 0x40 - MxStreamChunkList* m_loopingChunks; // 0x44 - MxStreamChunkListCursor* m_loopingChunkCursor; // 0x48 - MxStreamChunk* m_currentChunk; // 0x4c + MxDSSubscriber* m_subscriber = NULL; // 0x40 + MxStreamChunkList* m_loopingChunks = NULL; // 0x44 + MxStreamChunkListCursor* m_loopingChunkCursor = NULL; // 0x48 + MxStreamChunk* m_currentChunk = NULL; // 0x4c void Init(); void Destroy(MxBool p_fromDestructor); diff --git a/LEGO1/omni/src/audio/mxsoundpresenter.cpp b/LEGO1/omni/src/audio/mxsoundpresenter.cpp index 3fa2cfaa..31166090 100644 --- a/LEGO1/omni/src/audio/mxsoundpresenter.cpp +++ b/LEGO1/omni/src/audio/mxsoundpresenter.cpp @@ -13,13 +13,13 @@ void MxSoundPresenter::Destroy(MxBool p_fromDestructor) MSoundManager()->UnregisterPresenter(*this); } - ENTER(m_criticalSection); - MxMediaPresenter::Init(); - m_criticalSection.Leave(); - if (!p_fromDestructor) { MxMediaPresenter::Destroy(FALSE); } + + ENTER(m_criticalSection); + MxMediaPresenter::Init(); + m_criticalSection.Leave(); } // FUNCTION: LEGO1 0x100b1aa0 diff --git a/LEGO1/omni/src/common/mxmediapresenter.cpp b/LEGO1/omni/src/common/mxmediapresenter.cpp index 11621f71..0dbb1d3b 100644 --- a/LEGO1/omni/src/common/mxmediapresenter.cpp +++ b/LEGO1/omni/src/common/mxmediapresenter.cpp @@ -16,6 +16,12 @@ DECOMP_SIZE_ASSERT(MxStreamChunkListCursor, 0x10); // FUNCTION: LEGO1 0x100b54e0 void MxMediaPresenter::Init() { + if (this->m_loopingChunks) { + delete m_loopingChunks; + } + if (this->m_loopingChunkCursor) { + delete this->m_loopingChunkCursor; + } this->m_subscriber = NULL; this->m_loopingChunks = NULL; this->m_loopingChunkCursor = NULL; @@ -38,6 +44,7 @@ void MxMediaPresenter::Destroy(MxBool p_fromDestructor) if (m_loopingChunkCursor) { delete m_loopingChunkCursor; + m_loopingChunkCursor = NULL; } if (m_loopingChunks) { @@ -49,6 +56,7 @@ void MxMediaPresenter::Destroy(MxBool p_fromDestructor) } delete m_loopingChunks; + m_loopingChunks = NULL; } Init(); @@ -106,6 +114,12 @@ MxResult MxMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAct if (MxPresenter::StartAction(p_controller, p_action) == SUCCESS) { if (m_action->GetFlags() & MxDSAction::c_looping) { + if (m_loopingChunks) { + delete m_loopingChunks; + } + if (m_loopingChunkCursor) { + delete m_loopingChunkCursor; + } m_loopingChunks = new MxStreamChunkList; m_loopingChunkCursor = new MxStreamChunkListCursor(m_loopingChunks); diff --git a/LEGO1/tgl/d3drm/view.cpp b/LEGO1/tgl/d3drm/view.cpp index 92e5e107..98531a3f 100644 --- a/LEGO1/tgl/d3drm/view.cpp +++ b/LEGO1/tgl/d3drm/view.cpp @@ -54,10 +54,8 @@ ViewportAppData::~ViewportAppData() } refCount = pChildFrames->Release(); - assert(refCount == 0); refCount = m_pLightFrame->Release(); - assert(refCount == 0); } // Forward declare to satisfy order check diff --git a/LEGO1/viewmanager/viewmanager.cpp b/LEGO1/viewmanager/viewmanager.cpp index c24a77ce..bc455ede 100644 --- a/LEGO1/viewmanager/viewmanager.cpp +++ b/LEGO1/viewmanager/viewmanager.cpp @@ -545,11 +545,11 @@ ViewROI* ViewManager::Pick(Tgl::View* p_view, int x, int y) } } } - - visual->Release(); - frameArray->Release(); } } + + visual->Release(); + frameArray->Release(); } picked->Release(); diff --git a/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp b/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp index 8039c147..050dded2 100644 --- a/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp +++ b/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp @@ -7,6 +7,7 @@ #include "miniwin.h" #include +#include #include #include @@ -349,6 +350,7 @@ Direct3DRMSDL3GPURenderer::Direct3DRMSDL3GPURenderer( Direct3DRMSDL3GPURenderer::~Direct3DRMSDL3GPURenderer() { + assert(m_refCount == 0); SDL_ReleaseGPUBuffer(m_device, m_uiMeshCache.vertexBuffer); SDL_ReleaseGPUBuffer(m_device, m_uiMeshCache.indexBuffer); SDL_ReleaseWindowFromGPUDevice(m_device, DDWindow); @@ -717,6 +719,9 @@ SDL_GPUTransferBuffer* Direct3DRMSDL3GPURenderer::GetUploadBuffer(size_t size) void Direct3DRMSDL3GPURenderer::StartRenderPass(float r, float g, float b, bool clear) { + if (m_cmdbuf != nullptr) { + SDL_CancelGPUCommandBuffer(m_cmdbuf); + } m_cmdbuf = SDL_AcquireGPUCommandBuffer(m_device); if (!m_cmdbuf) { SDL_LogError( diff --git a/miniwin/src/d3drm/d3drmdevice.cpp b/miniwin/src/d3drm/d3drmdevice.cpp index 2b062d50..3360f9ba 100644 --- a/miniwin/src/d3drm/d3drmdevice.cpp +++ b/miniwin/src/d3drm/d3drmdevice.cpp @@ -9,10 +9,12 @@ #include "miniwin/miniwindevice.h" #include +#include Direct3DRMDevice2Impl::Direct3DRMDevice2Impl(DWORD width, DWORD height, Direct3DRMRenderer* renderer) : m_virtualWidth(width), m_virtualHeight(height), m_renderer(renderer), m_viewports(new Direct3DRMViewportArrayImpl) { + m_renderer->AddRef(); Resize(); } @@ -25,7 +27,7 @@ Direct3DRMDevice2Impl::~Direct3DRMDevice2Impl() viewport->Release(); } m_viewports->Release(); - delete m_renderer; + m_renderer->Release(); } HRESULT Direct3DRMDevice2Impl::QueryInterface(const GUID& riid, void** ppvObject) @@ -161,7 +163,9 @@ void Direct3DRMDevice2Impl::Resize() for (int i = 0; i < m_viewports->GetSize(); i++) { IDirect3DRMViewport* viewport; m_viewports->GetElement(i, &viewport); + assert(viewport); static_cast(viewport)->UpdateProjectionMatrix(); + viewport->Release(); } } diff --git a/miniwin/src/d3drm/d3drmframe.cpp b/miniwin/src/d3drm/d3drmframe.cpp index 0fbc05df..a5a7f782 100644 --- a/miniwin/src/d3drm/d3drmframe.cpp +++ b/miniwin/src/d3drm/d3drmframe.cpp @@ -10,11 +10,8 @@ Direct3DRMFrameImpl::Direct3DRMFrameImpl(Direct3DRMFrameImpl* parent) { m_children = new Direct3DRMFrameArrayImpl; - m_children->AddRef(); m_lights = new Direct3DRMLightArrayImpl; - m_lights->AddRef(); m_visuals = new Direct3DRMVisualArrayImpl; - m_visuals->AddRef(); if (parent) { parent->AddChild(this); } diff --git a/miniwin/src/d3drm/d3drmmesh.cpp b/miniwin/src/d3drm/d3drmmesh.cpp index 4545036b..2765971c 100644 --- a/miniwin/src/d3drm/d3drmmesh.cpp +++ b/miniwin/src/d3drm/d3drmmesh.cpp @@ -176,6 +176,9 @@ HRESULT Direct3DRMMeshImpl::SetGroupTexture(D3DRMGROUPINDEX groupIndex, IDirect3 } texture->AddRef(); + if (group.texture) { + group.texture->Release(); + } group.texture = texture; group.version++; return DD_OK; diff --git a/miniwin/src/d3drm/d3drmviewport.cpp b/miniwin/src/d3drm/d3drmviewport.cpp index 165f0675..93b23175 100644 --- a/miniwin/src/d3drm/d3drmviewport.cpp +++ b/miniwin/src/d3drm/d3drmviewport.cpp @@ -19,6 +19,14 @@ Direct3DRMViewportImpl::Direct3DRMViewportImpl(DWORD width, DWORD height, Direct { } +Direct3DRMViewportImpl::~Direct3DRMViewportImpl() +{ + if (m_camera) { + m_camera->Release(); + m_camera = nullptr; + } +} + static void D3DRMMatrixMultiply(D3DRMMATRIX4D out, const D3DRMMATRIX4D a, const D3DRMMATRIX4D b) { for (int i = 0; i < 4; ++i) { @@ -374,12 +382,12 @@ HRESULT Direct3DRMViewportImpl::Clear() HRESULT Direct3DRMViewportImpl::SetCamera(IDirect3DRMFrame* camera) { - if (m_camera) { - m_camera->Release(); - } if (camera) { camera->AddRef(); } + if (m_camera) { + m_camera->Release(); + } m_camera = camera; return DD_OK; } diff --git a/miniwin/src/internal/d3drmrenderer_sdl3gpu.h b/miniwin/src/internal/d3drmrenderer_sdl3gpu.h index 1e528232..55f8233a 100644 --- a/miniwin/src/internal/d3drmrenderer_sdl3gpu.h +++ b/miniwin/src/internal/d3drmrenderer_sdl3gpu.h @@ -131,7 +131,7 @@ inline static void Direct3DRMSDL3GPU_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, voi if (!device) { return; } - delete device; + device->Release(); #endif D3DDEVICEDESC halDesc = {}; diff --git a/miniwin/src/internal/d3drmviewport_impl.h b/miniwin/src/internal/d3drmviewport_impl.h index b23652d0..98d66643 100644 --- a/miniwin/src/internal/d3drmviewport_impl.h +++ b/miniwin/src/internal/d3drmviewport_impl.h @@ -21,6 +21,7 @@ class Direct3DRMFrameImpl; struct Direct3DRMViewportImpl : public Direct3DRMObjectBaseImpl { Direct3DRMViewportImpl(DWORD width, DWORD height, Direct3DRMRenderer* renderer); + ~Direct3DRMViewportImpl() override; HRESULT Render(IDirect3DRMFrame* group) override; /** * @brief Blit the render back to our backbuffer diff --git a/miniwin/src/windows/windows.cpp b/miniwin/src/windows/windows.cpp index 0e8b53ed..8c0791f3 100644 --- a/miniwin/src/windows/windows.cpp +++ b/miniwin/src/windows/windows.cpp @@ -2,16 +2,19 @@ #include "miniwin/ddraw.h" #include +#include #include ULONG IUnknown::AddRef() { + assert(m_refCount > 0); m_refCount += 1; return m_refCount; } ULONG IUnknown::Release() { + assert(m_refCount > 0); m_refCount -= 1; if (m_refCount == 0) { delete this;