Fix memory leak of non-RGBA image data, clear all image info

The image data was not being freed when `IGraphics::LoadTextureRawMove` is used with images that are not in RGBA format as this falls back to using `IGraphics::LoadTextureRaw` which requires manually freeing the image data.

Also consistently clear all image info in `LoadTextureRawMove`. This makes it necessary to store the size of the preview image in the editor separately, as previously the width and height of the unloaded image info were being used to render the preview image.
This commit is contained in:
Robert Müller 2024-07-27 21:19:10 +02:00
parent 78cbb45d49
commit fb832b482c
4 changed files with 15 additions and 10 deletions

View file

@ -474,7 +474,9 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRawMove(CImageInfo &Ima
if(Image.m_Format != CImageInfo::FORMAT_RGBA)
{
// Moving not possible, texture needs to be converted
return LoadTextureRaw(Image, Flags, pTexName);
IGraphics::CTextureHandle TextureHandle = LoadTextureRaw(Image, Flags, pTexName);
Image.Free();
return TextureHandle;
}
LoadTextureAddWarning(Image.m_Width, Image.m_Height, Flags, pTexName, m_vWarnings);
@ -486,6 +488,7 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRawMove(CImageInfo &Ima
CCommandBuffer::SCommand_Texture_Create Cmd = LoadTextureCreateCommand(TextureHandle.Id(), Image.m_Width, Image.m_Height, Flags);
Cmd.m_pData = Image.m_pData;
Image.m_pData = nullptr;
Image.Free();
AddCmd(Cmd);
return TextureHandle;

View file

@ -2001,7 +2001,6 @@ void CMenus::LoadCommunityIconFinish(const char *pCommunityId, CImageInfo &Info,
pData[i * Step + 2] = v;
}
CommunityIcon.m_GreyTexture = Graphics()->LoadTextureRawMove(Info, 0, pCommunityId);
Info.m_pData = nullptr;
auto ExistingIcon = std::find_if(m_vCommunityIcons.begin(), m_vCommunityIcons.end(), [pCommunityId](const SCommunityIcon &Element) {
return str_comp(Element.m_aCommunityId, pCommunityId) == 0;

View file

@ -5140,11 +5140,13 @@ void CEditor::RenderFileDialog()
{
char aBuffer[IO_MAX_PATH_LENGTH];
str_format(aBuffer, sizeof(aBuffer), "%s/%s", m_pFileDialogPath, m_vpFilteredFileList[m_FilesSelectedIndex]->m_aFilename);
if(Graphics()->LoadPng(m_FilePreviewImageInfo, aBuffer, m_vpFilteredFileList[m_FilesSelectedIndex]->m_StorageType))
CImageInfo PreviewImageInfo;
if(Graphics()->LoadPng(PreviewImageInfo, aBuffer, m_vpFilteredFileList[m_FilesSelectedIndex]->m_StorageType))
{
Graphics()->UnloadTexture(&m_FilePreviewImage);
m_FilePreviewImage = Graphics()->LoadTextureRawMove(m_FilePreviewImageInfo, 0, aBuffer);
m_FilePreviewImageInfo.m_pData = nullptr;
m_FilePreviewImageWidth = PreviewImageInfo.m_Width;
m_FilePreviewImageHeight = PreviewImageInfo.m_Height;
m_FilePreviewImage = Graphics()->LoadTextureRawMove(PreviewImageInfo, 0, aBuffer);
m_FilePreviewState = PREVIEW_LOADED;
}
else
@ -5167,11 +5169,11 @@ void CEditor::RenderFileDialog()
Preview.Margin(10.0f, &Preview);
if(m_FilePreviewState == PREVIEW_LOADED)
{
int w = m_FilePreviewImageInfo.m_Width;
int h = m_FilePreviewImageInfo.m_Height;
if(m_FilePreviewImageInfo.m_Width > Preview.w)
int w = m_FilePreviewImageWidth;
int h = m_FilePreviewImageHeight;
if(m_FilePreviewImageWidth > Preview.w)
{
h = m_FilePreviewImageInfo.m_Height * Preview.w / m_FilePreviewImageInfo.m_Width;
h = m_FilePreviewImageHeight * Preview.w / m_FilePreviewImageWidth;
w = Preview.w;
}
if(h > Preview.h)

View file

@ -610,7 +610,8 @@ public:
IGraphics::CTextureHandle m_FilePreviewImage;
int m_FilePreviewSound;
EPreviewState m_FilePreviewState;
CImageInfo m_FilePreviewImageInfo;
int m_FilePreviewImageWidth;
int m_FilePreviewImageHeight;
bool m_FileDialogOpening;
int m_ToolbarPreviewSound;