mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge pull request #7757 from Robyt3/Graphics-LoadTexture-Move
Avoid copying texture memory when possible
This commit is contained in:
commit
ca9c4f532a
|
@ -290,10 +290,7 @@ void CGraphics_Threaded::FreeTextureIndex(CTextureHandle *pIndex)
|
||||||
|
|
||||||
int CGraphics_Threaded::UnloadTexture(CTextureHandle *pIndex)
|
int CGraphics_Threaded::UnloadTexture(CTextureHandle *pIndex)
|
||||||
{
|
{
|
||||||
if(pIndex->Id() == m_NullTexture.Id())
|
if(pIndex->IsNullTexture() || !pIndex->IsValid())
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(!pIndex->IsValid())
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
CCommandBuffer::SCommand_Texture_Destroy Cmd;
|
CCommandBuffer::SCommand_Texture_Destroy Cmd;
|
||||||
|
@ -416,7 +413,7 @@ bool CGraphics_Threaded::IsSpriteTextureFullyTransparent(CImageInfo &FromImageIn
|
||||||
return IsImageSubFullyTransparent(FromImageInfo, x, y, w, h);
|
return IsImageSubFullyTransparent(FromImageInfo, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData, int Flags, const char *pTexName)
|
static void LoadTextureAddWarning(size_t Width, size_t Height, int Flags, const char *pTexName, std::vector<SWarning> &vWarnings)
|
||||||
{
|
{
|
||||||
if((Flags & IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE) != 0 || (Flags & IGraphics::TEXLOAD_TO_3D_TEXTURE) != 0)
|
if((Flags & IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE) != 0 || (Flags & IGraphics::TEXLOAD_TO_3D_TEXTURE) != 0)
|
||||||
{
|
{
|
||||||
|
@ -424,30 +421,22 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_
|
||||||
{
|
{
|
||||||
SWarning NewWarning;
|
SWarning NewWarning;
|
||||||
char aText[128];
|
char aText[128];
|
||||||
aText[0] = '\0';
|
str_format(aText, sizeof(aText), "\"%s\"", pTexName ? pTexName : "(no name)");
|
||||||
if(pTexName)
|
|
||||||
{
|
|
||||||
str_format(aText, sizeof(aText), "\"%s\"", pTexName);
|
|
||||||
}
|
|
||||||
str_format(NewWarning.m_aWarningMsg, sizeof(NewWarning.m_aWarningMsg), Localize("The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs."), aText, 16, 16);
|
str_format(NewWarning.m_aWarningMsg, sizeof(NewWarning.m_aWarningMsg), Localize("The width of texture %s is not divisible by %d, or the height is not divisible by %d, which might cause visual bugs."), aText, 16, 16);
|
||||||
|
vWarnings.emplace_back(NewWarning);
|
||||||
m_vWarnings.emplace_back(NewWarning);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(Width == 0 || Height == 0)
|
static CCommandBuffer::SCommand_Texture_Create LoadTextureCreateCommand(int TextureId, size_t Width, size_t Height, int Flags)
|
||||||
return IGraphics::CTextureHandle();
|
{
|
||||||
|
|
||||||
IGraphics::CTextureHandle TextureHandle = FindFreeTextureIndex();
|
|
||||||
|
|
||||||
CCommandBuffer::SCommand_Texture_Create Cmd;
|
CCommandBuffer::SCommand_Texture_Create Cmd;
|
||||||
Cmd.m_Slot = TextureHandle.Id();
|
Cmd.m_Slot = TextureId;
|
||||||
Cmd.m_Width = Width;
|
Cmd.m_Width = Width;
|
||||||
Cmd.m_Height = Height;
|
Cmd.m_Height = Height;
|
||||||
Cmd.m_Format = CCommandBuffer::TEXFORMAT_RGBA;
|
Cmd.m_Format = CCommandBuffer::TEXFORMAT_RGBA;
|
||||||
Cmd.m_StoreFormat = CCommandBuffer::TEXFORMAT_RGBA;
|
Cmd.m_StoreFormat = CCommandBuffer::TEXFORMAT_RGBA;
|
||||||
|
|
||||||
// flags
|
|
||||||
Cmd.m_Flags = 0;
|
Cmd.m_Flags = 0;
|
||||||
if(Flags & IGraphics::TEXLOAD_NOMIPMAPS)
|
if(Flags & IGraphics::TEXLOAD_NOMIPMAPS)
|
||||||
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_NOMIPMAPS;
|
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_NOMIPMAPS;
|
||||||
|
@ -458,14 +447,51 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_
|
||||||
if((Flags & IGraphics::TEXLOAD_NO_2D_TEXTURE) != 0)
|
if((Flags & IGraphics::TEXLOAD_NO_2D_TEXTURE) != 0)
|
||||||
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_NO_2D_TEXTURE;
|
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_NO_2D_TEXTURE;
|
||||||
|
|
||||||
// copy texture data
|
return Cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData, int Flags, const char *pTexName)
|
||||||
|
{
|
||||||
|
LoadTextureAddWarning(Width, Height, Flags, pTexName, m_vWarnings);
|
||||||
|
|
||||||
|
if(Width == 0 || Height == 0)
|
||||||
|
return IGraphics::CTextureHandle();
|
||||||
|
|
||||||
|
IGraphics::CTextureHandle TextureHandle = FindFreeTextureIndex();
|
||||||
|
CCommandBuffer::SCommand_Texture_Create Cmd = LoadTextureCreateCommand(TextureHandle.Id(), Width, Height, Flags);
|
||||||
|
|
||||||
|
// Copy texture data and convert if necessary
|
||||||
const size_t MemSize = Width * Height * CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA);
|
const size_t MemSize = Width * Height * CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA);
|
||||||
void *pTmpData = malloc(MemSize);
|
void *pTmpData = malloc(MemSize);
|
||||||
if(!ConvertToRGBA((uint8_t *)pTmpData, (const uint8_t *)pData, Width, Height, Format))
|
if(!ConvertToRGBA(static_cast<uint8_t *>(pTmpData), static_cast<const uint8_t *>(pData), Width, Height, Format))
|
||||||
{
|
{
|
||||||
dbg_msg("graphics", "converted image %s to RGBA, consider making its file format RGBA", pTexName ? pTexName : "(no name)");
|
dbg_msg("graphics", "converted image '%s' to RGBA, consider making its file format RGBA", pTexName ? pTexName : "(no name)");
|
||||||
}
|
}
|
||||||
Cmd.m_pData = pTmpData;
|
Cmd.m_pData = pTmpData;
|
||||||
|
|
||||||
|
AddCmd(Cmd);
|
||||||
|
|
||||||
|
return TextureHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRawMove(size_t Width, size_t Height, CImageInfo::EImageFormat Format, void *pData, int Flags, const char *pTexName)
|
||||||
|
{
|
||||||
|
if(Format != CImageInfo::FORMAT_RGBA)
|
||||||
|
{
|
||||||
|
// Moving not possible, texture needs to be converted
|
||||||
|
return LoadTextureRaw(Width, Height, Format, pData, Flags, pTexName);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadTextureAddWarning(Width, Height, Flags, pTexName, m_vWarnings);
|
||||||
|
|
||||||
|
if(Width == 0 || Height == 0)
|
||||||
|
return IGraphics::CTextureHandle();
|
||||||
|
|
||||||
|
IGraphics::CTextureHandle TextureHandle = FindFreeTextureIndex();
|
||||||
|
CCommandBuffer::SCommand_Texture_Create Cmd = LoadTextureCreateCommand(TextureHandle.Id(), Width, Height, Flags);
|
||||||
|
|
||||||
|
Cmd.m_pData = pData;
|
||||||
|
|
||||||
AddCmd(Cmd);
|
AddCmd(Cmd);
|
||||||
|
|
||||||
return TextureHandle;
|
return TextureHandle;
|
||||||
|
@ -479,8 +505,7 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTexture(const char *pFilename,
|
||||||
CImageInfo Img;
|
CImageInfo Img;
|
||||||
if(LoadPNG(&Img, pFilename, StorageType))
|
if(LoadPNG(&Img, pFilename, StorageType))
|
||||||
{
|
{
|
||||||
CTextureHandle ID = LoadTextureRaw(Img.m_Width, Img.m_Height, Img.m_Format, Img.m_pData, Flags, pFilename);
|
CTextureHandle ID = LoadTextureRawMove(Img.m_Width, Img.m_Height, Img.m_Format, Img.m_pData, Flags, pFilename);
|
||||||
FreePNG(&Img);
|
|
||||||
if(ID.IsValid())
|
if(ID.IsValid())
|
||||||
{
|
{
|
||||||
if(g_Config.m_Debug)
|
if(g_Config.m_Debug)
|
||||||
|
|
|
@ -951,6 +951,7 @@ public:
|
||||||
void FreeTextureIndex(CTextureHandle *pIndex);
|
void FreeTextureIndex(CTextureHandle *pIndex);
|
||||||
int UnloadTexture(IGraphics::CTextureHandle *pIndex) override;
|
int UnloadTexture(IGraphics::CTextureHandle *pIndex) override;
|
||||||
IGraphics::CTextureHandle LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData, int Flags, const char *pTexName = nullptr) override;
|
IGraphics::CTextureHandle LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData, int Flags, const char *pTexName = nullptr) override;
|
||||||
|
IGraphics::CTextureHandle LoadTextureRawMove(size_t Width, size_t Height, CImageInfo::EImageFormat Format, void *pData, int Flags, const char *pTexName = nullptr) override;
|
||||||
int LoadTextureRawSub(IGraphics::CTextureHandle TextureID, int x, int y, size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData) override;
|
int LoadTextureRawSub(IGraphics::CTextureHandle TextureID, int x, int y, size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData) override;
|
||||||
IGraphics::CTextureHandle NullTexture() const override;
|
IGraphics::CTextureHandle NullTexture() const override;
|
||||||
|
|
||||||
|
|
|
@ -335,6 +335,7 @@ public:
|
||||||
|
|
||||||
virtual int UnloadTexture(CTextureHandle *pIndex) = 0;
|
virtual int UnloadTexture(CTextureHandle *pIndex) = 0;
|
||||||
virtual CTextureHandle LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData, int Flags, const char *pTexName = nullptr) = 0;
|
virtual CTextureHandle LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData, int Flags, const char *pTexName = nullptr) = 0;
|
||||||
|
virtual CTextureHandle LoadTextureRawMove(size_t Width, size_t Height, CImageInfo::EImageFormat Format, void *pData, int Flags, const char *pTexName = nullptr) = 0;
|
||||||
virtual int LoadTextureRawSub(CTextureHandle TextureID, int x, int y, size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData) = 0;
|
virtual int LoadTextureRawSub(CTextureHandle TextureID, int x, int y, size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData) = 0;
|
||||||
virtual CTextureHandle LoadTexture(const char *pFilename, int StorageType, int Flags = 0) = 0;
|
virtual CTextureHandle LoadTexture(const char *pFilename, int StorageType, int Flags = 0) = 0;
|
||||||
virtual CTextureHandle NullTexture() const = 0;
|
virtual CTextureHandle NullTexture() const = 0;
|
||||||
|
|
|
@ -75,8 +75,7 @@ void CCountryFlags::LoadCountryflagsIndexfile()
|
||||||
CCountryFlag CountryFlag;
|
CCountryFlag CountryFlag;
|
||||||
CountryFlag.m_CountryCode = CountryCode;
|
CountryFlag.m_CountryCode = CountryCode;
|
||||||
str_copy(CountryFlag.m_aCountryCodeString, aOrigin);
|
str_copy(CountryFlag.m_aCountryCodeString, aOrigin);
|
||||||
CountryFlag.m_Texture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0, aOrigin);
|
CountryFlag.m_Texture = Graphics()->LoadTextureRawMove(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0, aOrigin);
|
||||||
Graphics()->FreePNG(&Info);
|
|
||||||
|
|
||||||
if(g_Config.m_Debug)
|
if(g_Config.m_Debug)
|
||||||
{
|
{
|
||||||
|
|
|
@ -445,10 +445,7 @@ IGraphics::CTextureHandle CMapImages::UploadEntityLayerText(int TextureSize, int
|
||||||
UpdateEntityLayerText(pMem, PixelSize, Width, Height, TextureSize, MaxWidth, YOffset, 2, 255);
|
UpdateEntityLayerText(pMem, PixelSize, Width, Height, TextureSize, MaxWidth, YOffset, 2, 255);
|
||||||
|
|
||||||
const int TextureLoadFlag = (Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE) | IGraphics::TEXLOAD_NO_2D_TEXTURE;
|
const int TextureLoadFlag = (Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE) | IGraphics::TEXLOAD_NO_2D_TEXTURE;
|
||||||
IGraphics::CTextureHandle Texture = Graphics()->LoadTextureRaw(Width, Height, CImageInfo::FORMAT_RGBA, pMem, TextureLoadFlag);
|
return Graphics()->LoadTextureRawMove(Width, Height, CImageInfo::FORMAT_RGBA, pMem, TextureLoadFlag);
|
||||||
free(pMem);
|
|
||||||
|
|
||||||
return Texture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapImages::UpdateEntityLayerText(void *pTexBuffer, size_t PixelSize, size_t TexWidth, size_t TexHeight, int TextureSize, int MaxWidth, int YOffset, int NumbersPower, int MaxNumber)
|
void CMapImages::UpdateEntityLayerText(void *pTexBuffer, size_t PixelSize, size_t TexWidth, size_t TexHeight, int TextureSize, int MaxWidth, int YOffset, int NumbersPower, int MaxNumber)
|
||||||
|
|
|
@ -2197,8 +2197,7 @@ int CMenus::MenuImageScan(const char *pName, int IsDir, int DirType, void *pUser
|
||||||
pData[i * Step + 1] = v;
|
pData[i * Step + 1] = v;
|
||||||
pData[i * Step + 2] = v;
|
pData[i * Step + 2] = v;
|
||||||
}
|
}
|
||||||
MenuImage.m_GreyTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0);
|
MenuImage.m_GreyTexture = pSelf->Graphics()->LoadTextureRawMove(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0);
|
||||||
pSelf->Graphics()->FreePNG(&Info);
|
|
||||||
|
|
||||||
str_truncate(MenuImage.m_aName, sizeof(MenuImage.m_aName), pName, str_length(pName) - str_length(pExtension));
|
str_truncate(MenuImage.m_aName, sizeof(MenuImage.m_aName), pName, str_length(pName) - str_length(pExtension));
|
||||||
pSelf->m_vMenuImages.push_back(MenuImage);
|
pSelf->m_vMenuImages.push_back(MenuImage);
|
||||||
|
|
|
@ -1908,8 +1908,8 @@ void CMenus::LoadCommunityIconFinish(const char *pCommunityId, CImageInfo &&Info
|
||||||
pData[i * Step + 1] = v;
|
pData[i * Step + 1] = v;
|
||||||
pData[i * Step + 2] = v;
|
pData[i * Step + 2] = v;
|
||||||
}
|
}
|
||||||
CommunityIcon.m_GreyTexture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0);
|
CommunityIcon.m_GreyTexture = Graphics()->LoadTextureRawMove(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0);
|
||||||
Graphics()->FreePNG(&Info);
|
Info.m_pData = nullptr;
|
||||||
|
|
||||||
auto ExistingIcon = std::find_if(m_vCommunityIcons.begin(), m_vCommunityIcons.end(), [pCommunityId](const SCommunityIcon &Element) {
|
auto ExistingIcon = std::find_if(m_vCommunityIcons.begin(), m_vCommunityIcons.end(), [pCommunityId](const SCommunityIcon &Element) {
|
||||||
return str_comp(Element.m_aCommunityId, pCommunityId) == 0;
|
return str_comp(Element.m_aCommunityId, pCommunityId) == 0;
|
||||||
|
|
|
@ -5166,8 +5166,8 @@ void CEditor::RenderFileDialog()
|
||||||
if(Graphics()->LoadPNG(&m_FilePreviewImageInfo, aBuffer, m_vpFilteredFileList[m_FilesSelectedIndex]->m_StorageType))
|
if(Graphics()->LoadPNG(&m_FilePreviewImageInfo, aBuffer, m_vpFilteredFileList[m_FilesSelectedIndex]->m_StorageType))
|
||||||
{
|
{
|
||||||
Graphics()->UnloadTexture(&m_FilePreviewImage);
|
Graphics()->UnloadTexture(&m_FilePreviewImage);
|
||||||
m_FilePreviewImage = Graphics()->LoadTextureRaw(m_FilePreviewImageInfo.m_Width, m_FilePreviewImageInfo.m_Height, m_FilePreviewImageInfo.m_Format, m_FilePreviewImageInfo.m_pData, 0);
|
m_FilePreviewImage = Graphics()->LoadTextureRawMove(m_FilePreviewImageInfo.m_Width, m_FilePreviewImageInfo.m_Height, m_FilePreviewImageInfo.m_Format, m_FilePreviewImageInfo.m_pData, 0);
|
||||||
Graphics()->FreePNG(&m_FilePreviewImageInfo);
|
m_FilePreviewImageInfo.m_pData = nullptr;
|
||||||
m_FilePreviewState = PREVIEW_LOADED;
|
m_FilePreviewState = PREVIEW_LOADED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue