Textures: extract ImTextureDataUpdateNewFrame() out of ImFontAtlasUpdateNewFrame(). (#8465)
This commit is contained in:
+45
-38
@@ -2817,48 +2817,12 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
|
|||||||
// Update texture status
|
// Update texture status
|
||||||
for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++)
|
for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++)
|
||||||
{
|
{
|
||||||
|
// Update and remove if requested
|
||||||
ImTextureData* tex = atlas->TexList[tex_n];
|
ImTextureData* tex = atlas->TexList[tex_n];
|
||||||
bool remove_from_list = false;
|
|
||||||
if (tex->Status == ImTextureStatus_OK)
|
|
||||||
{
|
|
||||||
tex->Updates.resize(0);
|
|
||||||
tex->UpdateRect.x = tex->UpdateRect.y = (unsigned short)~0;
|
|
||||||
tex->UpdateRect.w = tex->UpdateRect.h = 0;
|
|
||||||
}
|
|
||||||
if (tex->Status == ImTextureStatus_WantCreate && atlas->RendererHasTextures)
|
if (tex->Status == ImTextureStatus_WantCreate && atlas->RendererHasTextures)
|
||||||
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture's TexID/BackendUserData but did not update Status to OK.");
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture's TexID/BackendUserData but did not update Status to OK.");
|
||||||
|
|
||||||
// Request destroy
|
bool remove_from_list = ImTextureDataUpdateNewFrame(tex);
|
||||||
// - Keep bool to true in order to differentiate a planned destroy vs a destroy decided by the backend.
|
|
||||||
// - We don't destroy pixels right away, as backend may have an in-flight copy from RAM.
|
|
||||||
if (tex->WantDestroyNextFrame && tex->Status != ImTextureStatus_Destroyed && tex->Status != ImTextureStatus_WantDestroy)
|
|
||||||
{
|
|
||||||
IM_ASSERT(tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates);
|
|
||||||
tex->Status = ImTextureStatus_WantDestroy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a texture has never reached the backend, they don't need to know about it.
|
|
||||||
// (note: backends between 1.92.0 and 1.92.4 could set an already destroyed texture to ImTextureStatus_WantDestroy
|
|
||||||
// when invalidating graphics objects twice, which would previously remove it from the list and crash.)
|
|
||||||
if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL)
|
|
||||||
tex->Status = ImTextureStatus_Destroyed;
|
|
||||||
|
|
||||||
// Process texture being destroyed
|
|
||||||
if (tex->Status == ImTextureStatus_Destroyed)
|
|
||||||
{
|
|
||||||
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture Status to Destroyed but did not clear TexID/BackendUserData!");
|
|
||||||
if (tex->WantDestroyNextFrame)
|
|
||||||
remove_from_list = true; // Destroy was scheduled by us
|
|
||||||
else
|
|
||||||
tex->Status = ImTextureStatus_WantCreate; // Destroy was done was backend: recreate it (e.g. freed resources mid-run)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The backend may need defer destroying by a few frames, to handle texture used by previous in-flight rendering.
|
|
||||||
// We allow the texture staying in _WantDestroy state and increment a counter which the backend can use to take its decision.
|
|
||||||
if (tex->Status == ImTextureStatus_WantDestroy)
|
|
||||||
tex->UnusedFrames++;
|
|
||||||
|
|
||||||
// Destroy and remove
|
|
||||||
if (remove_from_list)
|
if (remove_from_list)
|
||||||
{
|
{
|
||||||
IM_ASSERT(atlas->TexData != tex);
|
IM_ASSERT(atlas->TexData != tex);
|
||||||
@@ -2870,6 +2834,49 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ImTextureDataUpdateNewFrame(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
bool remove_from_list = false;
|
||||||
|
if (tex->Status == ImTextureStatus_OK)
|
||||||
|
{
|
||||||
|
tex->Updates.resize(0);
|
||||||
|
tex->UpdateRect.x = tex->UpdateRect.y = (unsigned short)~0;
|
||||||
|
tex->UpdateRect.w = tex->UpdateRect.h = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request destroy
|
||||||
|
// - Keep bool to true in order to differentiate a planned destroy vs a destroy decided by the backend.
|
||||||
|
// - We don't destroy pixels right away, as backend may have an in-flight copy from RAM.
|
||||||
|
if (tex->WantDestroyNextFrame && tex->Status != ImTextureStatus_Destroyed && tex->Status != ImTextureStatus_WantDestroy)
|
||||||
|
{
|
||||||
|
IM_ASSERT(tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates);
|
||||||
|
tex->Status = ImTextureStatus_WantDestroy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a texture has never reached the backend, they don't need to know about it.
|
||||||
|
// (note: backends between 1.92.0 and 1.92.4 could set an already destroyed texture to ImTextureStatus_WantDestroy
|
||||||
|
// when invalidating graphics objects twice, which would previously remove it from the list and crash.)
|
||||||
|
if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL)
|
||||||
|
tex->Status = ImTextureStatus_Destroyed;
|
||||||
|
|
||||||
|
// Process texture being destroyed
|
||||||
|
if (tex->Status == ImTextureStatus_Destroyed)
|
||||||
|
{
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture Status to Destroyed but did not clear TexID/BackendUserData!");
|
||||||
|
if (tex->WantDestroyNextFrame)
|
||||||
|
remove_from_list = true; // Destroy was scheduled by us
|
||||||
|
else
|
||||||
|
tex->Status = ImTextureStatus_WantCreate; // Destroy was done was backend: recreate it (e.g. freed resources mid-run)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The backend may need defer destroying by a few frames, to handle texture used by previous in-flight rendering.
|
||||||
|
// We allow the texture staying in _WantDestroy state and increment a counter which the backend can use to take its decision.
|
||||||
|
if (tex->Status == ImTextureStatus_WantDestroy)
|
||||||
|
tex->UnusedFrames++;
|
||||||
|
|
||||||
|
return remove_from_list;
|
||||||
|
}
|
||||||
|
|
||||||
void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch, unsigned char* dst_pixels, ImTextureFormat dst_fmt, int dst_pitch, int w, int h)
|
void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch, unsigned char* dst_pixels, ImTextureFormat dst_fmt, int dst_pitch, int w, int h)
|
||||||
{
|
{
|
||||||
IM_ASSERT(src_pixels != NULL && dst_pixels != NULL);
|
IM_ASSERT(src_pixels != NULL && dst_pixels != NULL);
|
||||||
|
|||||||
@@ -1702,6 +1702,7 @@ enum ImGuiActivateFlags_
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Early work-in-progress API for ScrollToItem()
|
// Early work-in-progress API for ScrollToItem()
|
||||||
|
// FIXME: Missing flags to request making both edges visible when possible.
|
||||||
enum ImGuiScrollFlags_
|
enum ImGuiScrollFlags_
|
||||||
{
|
{
|
||||||
ImGuiScrollFlags_None = 0,
|
ImGuiScrollFlags_None = 0,
|
||||||
@@ -3979,6 +3980,7 @@ IMGUI_API void ImFontAtlasTextureBlockFill(ImTextureData* dst_tex,
|
|||||||
IMGUI_API void ImFontAtlasTextureBlockCopy(ImTextureData* src_tex, int src_x, int src_y, ImTextureData* dst_tex, int dst_x, int dst_y, int w, int h);
|
IMGUI_API void ImFontAtlasTextureBlockCopy(ImTextureData* src_tex, int src_x, int src_y, ImTextureData* dst_tex, int dst_x, int dst_y, int w, int h);
|
||||||
IMGUI_API void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex, int x, int y, int w, int h);
|
IMGUI_API void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex, int x, int y, int w, int h);
|
||||||
|
|
||||||
|
IMGUI_API bool ImTextureDataUpdateNewFrame(ImTextureData* tex);
|
||||||
IMGUI_API void ImTextureDataQueueUpload(ImTextureData* tex, int x, int y, int w, int h);
|
IMGUI_API void ImTextureDataQueueUpload(ImTextureData* tex, int x, int y, int w, int h);
|
||||||
IMGUI_API int ImTextureDataGetFormatBytesPerPixel(ImTextureFormat format);
|
IMGUI_API int ImTextureDataGetFormatBytesPerPixel(ImTextureFormat format);
|
||||||
IMGUI_API const char* ImTextureDataGetStatusName(ImTextureStatus status);
|
IMGUI_API const char* ImTextureDataGetStatusName(ImTextureStatus status);
|
||||||
|
|||||||
Reference in New Issue
Block a user