Fixed bad deallocation in Texture Manager and interface to create textures from raw data:

- Fixed rather embarrassing overlook in deallocation of data array passed from to CreateTexture from other function.
- Changed CreateTexture to use cleanup function passed with data (optional and only needed if data need to be released). Keeping data allocation and deallocation code together should make bugs like this easier to spot and avoid. Additionally this allows for more generic usage.
This commit is contained in:
Sebastian 2018-08-14 20:28:25 +01:00
parent 74c794b53e
commit d9220ad536
3 changed files with 9 additions and 11 deletions

View File

@ -72,7 +72,7 @@ void FImGuiModuleManager::LoadTextures()
int Width, Height, Bpp; int Width, Height, Bpp;
Fonts.GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp); Fonts.GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp);
TextureIndex FontsTexureIndex = TextureManager.CreateTexture(FName{ "ImGuiModule_FontAtlas" }, Width, Height, Bpp, Pixels, false); TextureIndex FontsTexureIndex = TextureManager.CreateTexture(FName{ "ImGuiModule_FontAtlas" }, Width, Height, Bpp, Pixels);
// Set font texture index in ImGui. // Set font texture index in ImGui.
Fonts.TexID = ImGuiInterops::ToImTextureID(FontsTexureIndex); Fonts.TexID = ImGuiInterops::ToImTextureID(FontsTexureIndex);

View File

@ -7,7 +7,7 @@
#include <algorithm> #include <algorithm>
TextureIndex FTextureManager::CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, bool bDeleteSrcData) TextureIndex FTextureManager::CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup)
{ {
checkf(FindTextureIndex(Name) == INDEX_NONE, TEXT("Trying to create texture using resource name '%s' that is already registered."), *Name.ToString()); checkf(FindTextureIndex(Name) == INDEX_NONE, TEXT("Trying to create texture using resource name '%s' that is already registered."), *Name.ToString());
@ -19,12 +19,9 @@ TextureIndex FTextureManager::CreateTexture(const FName& Name, int32 Width, int3
// Update texture data. // Update texture data.
FUpdateTextureRegion2D* TextureRegion = new FUpdateTextureRegion2D(0, 0, 0, 0, Width, Height); FUpdateTextureRegion2D* TextureRegion = new FUpdateTextureRegion2D(0, 0, 0, 0, Width, Height);
auto DataCleanup = [bDeleteSrcData](uint8* Data, const FUpdateTextureRegion2D* UpdateRegion) auto DataCleanup = [SrcDataCleanup](uint8* Data, const FUpdateTextureRegion2D* UpdateRegion)
{ {
if (bDeleteSrcData) SrcDataCleanup(Data);
{
delete Data;
}
delete UpdateRegion; delete UpdateRegion;
}; };
Texture->UpdateTextureRegions(0, 1u, TextureRegion, SrcBpp * Width, SrcBpp, SrcData, DataCleanup); Texture->UpdateTextureRegions(0, 1u, TextureRegion, SrcBpp * Width, SrcBpp, SrcData, DataCleanup);
@ -42,9 +39,10 @@ TextureIndex FTextureManager::CreatePlainTexture(const FName& Name, int32 Width,
const uint32 SizeInBytes = SizeInPixels * Bpp; const uint32 SizeInBytes = SizeInPixels * Bpp;
uint8* SrcData = new uint8[SizeInBytes]; uint8* SrcData = new uint8[SizeInBytes];
std::fill(reinterpret_cast<uint32*>(SrcData), reinterpret_cast<uint32*>(SrcData) + SizeInPixels, ColorPacked); std::fill(reinterpret_cast<uint32*>(SrcData), reinterpret_cast<uint32*>(SrcData) + SizeInPixels, ColorPacked);
auto SrcDataCleanup = [](uint8* Data) { delete[] Data; };
// Create new texture from raw data (we created the buffer, so mark it for delete). // Create new texture from raw data.
return CreateTexture(Name, Width, Height, Bpp, SrcData, true); return CreateTexture(Name, Width, Height, Bpp, SrcData, SrcDataCleanup);
} }
FTextureManager::FTextureEntry::FTextureEntry(const FName& InName, UTexture2D* InTexture) FTextureManager::FTextureEntry::FTextureEntry(const FName& InName, UTexture2D* InTexture)

View File

@ -57,9 +57,9 @@ public:
// @param Height - The texture height // @param Height - The texture height
// @param SrcBpp - The size in bytes of one pixel // @param SrcBpp - The size in bytes of one pixel
// @param SrcData - The source data // @param SrcData - The source data
// @param bDeleteSrcData - If true, we should delete source data after creating a texture // @param SrcDataCleanup - Optional function called to release source data after texture is created (only needed, if data need to be released)
// @returns The index of a texture that was created // @returns The index of a texture that was created
TextureIndex CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, bool bDeleteSrc = false); TextureIndex CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup = [](uint8*) {});
// Create a plain texture. Throws exception if there is already a texture with that name. // Create a plain texture. Throws exception if there is already a texture with that name.
// @param Name - The texture name // @param Name - The texture name