internal/atlas: do not access global variable references at deallocate

As deallocate is invoked from the finalizer, it is problematic to access
a global variable referring the object itself. Especially,
runtime.AddCleanup doesn't work well with the current deallocate
implmenentation.

This change removes the access to the global variables from deallocate.
The global variables are reset every frame so it is self not to
remove a deallocated image explicitly. Also, this change fixes
the logic to iterate the global variables' images to check if the
image is already deallocated or not.

Updates #3204
This commit is contained in:
Hajime Hoshi
2025-09-22 00:02:08 +09:00
parent 765193a40e
commit 4daa59b2cd

View File

@@ -59,6 +59,11 @@ const baseCountToPutOnSourceBackend = 10
func putImagesOnSourceBackend() {
// The counter usedAsDestinationCount is updated at most once per frame (#2676).
imagesUsedAsDestination.forEach(func(i *Image) {
// i.backend can be nil after deallocate is called.
if i.backend == nil {
i.usedAsDestinationCount = 0
return
}
// This counter is not updated when the backend is created in this frame.
if !i.backendCreatedInThisFrame && i.usedAsDestinationCount < math.MaxInt {
i.usedAsDestinationCount++
@@ -68,6 +73,11 @@ func putImagesOnSourceBackend() {
imagesUsedAsDestination.clear()
imagesToPutOnSourceBackend.forEach(func(i *Image) {
// i.backend can be nil after deallocate is called.
if i.backend == nil {
i.usedAsSourceCount = 0
return
}
if i.usedAsSourceCount < math.MaxInt {
i.usedAsSourceCount++
}
@@ -573,9 +583,8 @@ func (i *Image) deallocate() {
i.node = nil
}()
i.resetUsedAsSourceCount()
i.usedAsSourceCount = 0
i.usedAsDestinationCount = 0
imagesUsedAsDestination.remove(i)
if i.backend == nil {
// Not allocated yet.