Skip to content

Commit

Permalink
Fix memory leak per turn - dispose of individual pixmaps immediately,…
Browse files Browse the repository at this point in the history
… dispose of atlases after new screen is available (#12865)
  • Loading branch information
yairm210 authored Jan 27, 2025
1 parent a7dca5c commit 56ab32e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
23 changes: 22 additions & 1 deletion core/src/com/unciv/ui/images/ImageGetter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ import com.unciv.ui.components.extensions.toGroup
import com.unciv.ui.components.extensions.toLabel
import com.unciv.ui.components.fonts.FontRulesetIcons
import com.unciv.ui.screens.basescreen.BaseScreen
import com.unciv.utils.Concurrency
import com.unciv.utils.debug
import kotlinx.coroutines.delay
import kotlin.math.atan2
import kotlin.math.max
import kotlin.math.min
Expand All @@ -56,6 +58,8 @@ object ImageGetter {
// We use texture atlases to minimize texture swapping - see https://yairm210.medium.com/the-libgdx-performance-guide-1d068a84e181
lateinit var atlas: TextureAtlas
private val atlases = HashMap<String, TextureAtlas>()
/** These are atlases that we generate on-the-fly per ruleset */
private val tempAtlases = ArrayList<TextureAtlas>()
var ruleset = Ruleset()

fun getStatWithBackground(statName: String): TextureRegionDrawable? = textureRegionDrawables[statName]
Expand Down Expand Up @@ -95,10 +99,24 @@ object ImageGetter {
BaseScreen.setSkin()
FontRulesetIcons.addRulesetImages(ruleset)

disposeTempAtlases()
setupStatImages()
setupResourcePortraits()
setupImprovementPortraits()
}

// We want this with a delay of a few seconds because *the current screen* might still be using this image
private fun disposeTempAtlases(){
val toDispose = tempAtlases.toList()
tempAtlases.clear()
Concurrency.run {
delay(3000)
Concurrency.runOnGLThread {
toDispose.forEach { it.dispose() }
}
}

}

private fun setupStatImages() {
// Performance improvement - "pack" the stat images together with the circle to the same texture
Expand Down Expand Up @@ -127,14 +145,17 @@ object ImageGetter {
val pixmapPacker = PixmapPacker(2048, 2048, Pixmap.Format.RGBA8888, 2, false).apply { packToTexture = true }
for ((name, actor) in nameToActorList) {
actor.apply { isTransform = true; setScale(1f, -1f); setPosition(0f, height) } // flip Y axis
pixmapPacker.pack(name, FontRulesetIcons.getPixmapFromActorBase(actor, size, size))
val pixmap = FontRulesetIcons.getPixmapFromActorBase(actor, size, size)
pixmapPacker.pack(name, pixmap)
pixmap.dispose()
}

val yieldAtlas = pixmapPacker.generateTextureAtlas(
TextureFilter.MipMapLinearLinear,
TextureFilter.MipMapLinearLinear,
true
)
tempAtlases.add(yieldAtlas)
for (region in yieldAtlas.regions) {
val drawable = TextureRegionDrawable(region)
textureRegionDrawables[region.name] = drawable
Expand Down
6 changes: 3 additions & 3 deletions core/src/com/unciv/ui/screens/worldscreen/WorldScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class WorldScreen(
val viewingCiv: Civilization,
restoreState: RestoreState? = null
) : BaseScreen() {
/** When set, causes the screen to update in the next [render][BaseScreen.render] event */
/** When set, causes the screen to update in the next [render][render] event */
var shouldUpdate = false

/** Indicates it's the player's ([viewingCiv]) turn */
Expand Down Expand Up @@ -445,8 +445,8 @@ class WorldScreen(
updateGameplayButtons()

val coveredNotificationsTop = stage.height - statusButtons.y
val coveredNotificationsBottom = bottomTileInfoTable.height +
(if (game.settings.showMinimap) minimapWrapper.height else 0f)
val coveredNotificationsBottom = (bottomTileInfoTable.height + bottomTileInfoTable.y)
// (if (game.settings.showMinimap) minimapWrapper.height else 0f)
notificationsScroll.update(viewingCiv.notifications, coveredNotificationsTop, coveredNotificationsBottom)

val posZoomFromRight = if (game.settings.showMinimap) minimapWrapper.width
Expand Down

0 comments on commit 56ab32e

Please sign in to comment.