Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: ebiten: image arena #3206

Open
11 tasks
hajimehoshi opened this issue Mar 4, 2025 · 1 comment
Open
11 tasks

proposal: ebiten: image arena #3206

hajimehoshi opened this issue Mar 4, 2025 · 1 comment

Comments

@hajimehoshi
Copy link
Owner

hajimehoshi commented Mar 4, 2025

Operating System

  • Windows
  • macOS
  • Linux
  • FreeBSD
  • OpenBSD
  • Android
  • iOS
  • Nintendo Switch
  • PlayStation 5
  • Xbox
  • Web Browsers

What feature would you like to be added?

Like a memory arena, we want a special texture atlas whose lifetime can be explicitly controlled.

Now there is no choice to choose which texture atlas is used for an image. When relatively big image is used, an automatic texture atlas is bloated and never shrunk. This can consume unnecessarily big GPU memory.

The current unmanged image is useful to get control of lifetimes for one image, but this doesn't have the Ebitengine's automatic texture atlas allocation.

See also #3100

Why is this needed?

No response

@hajimehoshi hajimehoshi changed the title ebiten: image arena proposal: ebiten: image arena Mar 4, 2025
@hajimehoshi hajimehoshi added this to the v2.9.0 milestone Mar 4, 2025
@hajimehoshi
Copy link
Owner Author

hajimehoshi commented Mar 8, 2025

An arena is basically the same as the internal texture atlas.

package ebiten

// Atlas is a direct representation of GPU memory for images.
// Atlas can hold one or more *ebiten.Image, deallocate them, and evict them from GPU memory explicitly.
//
// A regular image is created on an internal automatic texture atlas, so you don't have to care this in usual cases.
// Atlas is useful for an environment where GPU memory is restricted and you want to control memory more explicitly.
type Atlas struct {
}

type NewAtlasOptions struct {
    // InitialWidth must be power of 2.
    InitialWidth int

    // InitialHeight must be power of 2.
    InitialHeight int

    // FixedSize indicates whether the texture atlas is extended if it needs more region to allocate a new image.
    //
    // The default (zero) value is false, which indicates that the texture atlas is automatically extended.
    FixedSize bool
}

// NewAtlas creats a new texture atlas.
func NewAtlas(options *NewAtlasOptions) *Atlas

// Deallocate deallocates the texture atlas and all the images tha belong to the atlas.
func (a *Atlas) Deallocate()

type NewImageOptions struct {
    // ...

    // Atlas specifies the initial texture atlas explicitly.
    //
    // Even after this image is deallocated, the image is still available.
    // In this case, if the specified atlas is still alive, the image is allocated on the atlas again.
    // Otherwiser, tring to use this image panics.
    //
    // If the belonging atlas is deallocated, the image is also deallocated and evicted from GPU memory.
    //
    // If the atlas size is fixed and allocating an image fails, NewImage panics.
    //
    // If the rendering source and the rendering target belong to the same Atlas, the operation panics.
    // 
    // The default (zero) valus is nil, which indicates that an internal automatic atlas is used.
    Atlas *Atlas
}

TODO: What if Unmanaged and Atlas are specified at the same time??

An actual usage will be like this:

// When a new game scene starts, create a new atlas for the scene.
atlas := ebiten.NewAtlas(nil)

// Create images with the atlas.
img1 := ebiten.NewImageFromImageWithOptions(pngImg1, &ebiten.NewImageOptions{
    Atlas: atlas
})
img2 := ebiten.NewImageFromImageWithOptions(pngImg2, &ebiten.NewImageOptions{
    Atlas: atlas
})

// Use the images during the game scene.

// When the game scene ends, deallocate the arena. The images are no longer available.
atlas.Deallocate()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant