Functions to free up (SDL2) texture memory
This commit is contained in:
parent
c1b8bc910b
commit
df69b8e525
|
@ -79,6 +79,11 @@ func (t *Texture) Image() image.Image {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the texture. Doesn't do anything in the Canvas engine currently.
|
||||||
|
func (t *Texture) Free() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// LoadTexture recalls a cached texture image.
|
// LoadTexture recalls a cached texture image.
|
||||||
func (e *Engine) LoadTexture(name string) (render.Texturer, error) {
|
func (e *Engine) LoadTexture(name string) (render.Texturer, error) {
|
||||||
if tex, ok := e.textures[name]; ok {
|
if tex, ok := e.textures[name]; ok {
|
||||||
|
@ -94,5 +99,13 @@ func (e *Engine) Copy(t render.Texturer, src, dist render.Rect) {
|
||||||
|
|
||||||
// e.canvas.ctx2d.Call("drawImage", tex.image, dist.X, dist.Y)
|
// e.canvas.ctx2d.Call("drawImage", tex.image, dist.X, dist.Y)
|
||||||
e.canvas.ctx2d.Call("drawImage", tex.canvas, dist.X, dist.Y)
|
e.canvas.ctx2d.Call("drawImage", tex.canvas, dist.X, dist.Y)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FreeTextures flushes the texture cache.
|
||||||
|
func (e *Engine) FreeTextures() int {
|
||||||
|
var len = len(e.textures)
|
||||||
|
for name := range e.textures {
|
||||||
|
delete(e.textures, name)
|
||||||
|
}
|
||||||
|
return len
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,10 @@ type Engine interface {
|
||||||
LoadTexture(name string) (Texturer, error)
|
LoadTexture(name string) (Texturer, error)
|
||||||
Copy(t Texturer, src, dst Rect)
|
Copy(t Texturer, src, dst Rect)
|
||||||
|
|
||||||
|
// Teardown and free memory for all textures, returning the number
|
||||||
|
// of textures that were freed.
|
||||||
|
FreeTextures() int
|
||||||
|
|
||||||
// Delay for a moment using the render engine's delay method,
|
// Delay for a moment using the render engine's delay method,
|
||||||
// implemented by sdl.Delay(uint32)
|
// implemented by sdl.Delay(uint32)
|
||||||
Delay(uint32)
|
Delay(uint32)
|
||||||
|
@ -49,4 +53,5 @@ type Engine interface {
|
||||||
type Texturer interface {
|
type Texturer interface {
|
||||||
Size() Rect
|
Size() Rect
|
||||||
Image() image.Image
|
Image() image.Image
|
||||||
|
Free() error // teardown and free memory
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ func (r *Renderer) Copy(t render.Texturer, src, dst render.Rect) {
|
||||||
|
|
||||||
// Texture can hold on to SDL textures for caching and optimization.
|
// Texture can hold on to SDL textures for caching and optimization.
|
||||||
type Texture struct {
|
type Texture struct {
|
||||||
|
render *Renderer // backref to free them up thoroughly
|
||||||
tex *sdl.Texture
|
tex *sdl.Texture
|
||||||
image image.Image
|
image image.Image
|
||||||
width int32
|
width int32
|
||||||
|
@ -62,6 +63,7 @@ func (r *Renderer) StoreTexture(name string, img image.Image) (render.Texturer,
|
||||||
}
|
}
|
||||||
|
|
||||||
tex := &Texture{
|
tex := &Texture{
|
||||||
|
render: r,
|
||||||
width: surface.W,
|
width: surface.W,
|
||||||
height: surface.H,
|
height: surface.H,
|
||||||
tex: texture,
|
tex: texture,
|
||||||
|
@ -72,6 +74,32 @@ func (r *Renderer) StoreTexture(name string, img image.Image) (render.Texturer,
|
||||||
return tex, nil
|
return tex, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CountTextures is a custom function for the SDL2 Engine only that returns the
|
||||||
|
// size of the engine texture cache.
|
||||||
|
//
|
||||||
|
// Returns the number of (Go) Texture objects (which hold cached image.Image
|
||||||
|
// and can garbage collect nicely) and the number of those which also have
|
||||||
|
// SDL2 Texture objects (which need to be freed manually).
|
||||||
|
func (r *Renderer) CountTextures() (bitmaps int, sdl2textures int) {
|
||||||
|
var withTex int // ones with active SDL2 Texture objects
|
||||||
|
for _, tex := range r.textures {
|
||||||
|
if tex.tex != nil {
|
||||||
|
withTex++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len(r.textures), withTex
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTextures is a custom function to peek into the SDL2 texture cache names.
|
||||||
|
func (r *Renderer) ListTextures() []string {
|
||||||
|
var keys = []string{}
|
||||||
|
for key := range r.textures {
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
|
||||||
// Size returns the dimensions of the texture.
|
// Size returns the dimensions of the texture.
|
||||||
func (t *Texture) Size() render.Rect {
|
func (t *Texture) Size() render.Rect {
|
||||||
return render.NewRect(int(t.width), int(t.height))
|
return render.NewRect(int(t.width), int(t.height))
|
||||||
|
@ -82,10 +110,44 @@ func (t *Texture) Image() image.Image {
|
||||||
return t.image
|
return t.image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the SDL2 texture object.
|
||||||
|
func (t *Texture) Free() error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if t.tex != nil {
|
||||||
|
err = t.tex.Destroy()
|
||||||
|
t.tex = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free up the cached texture too to garbage collect the image.Image cache etc.
|
||||||
|
for name, tex := range t.render.textures {
|
||||||
|
if tex == t {
|
||||||
|
delete(t.render.textures, name)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// LoadTexture initializes a texture from a bitmap image.
|
// LoadTexture initializes a texture from a bitmap image.
|
||||||
func (r *Renderer) LoadTexture(name string) (render.Texturer, error) {
|
func (r *Renderer) LoadTexture(name string) (render.Texturer, error) {
|
||||||
if tex, ok := r.textures[name]; ok {
|
if tex, ok := r.textures[name]; ok {
|
||||||
|
// If the SDL2 texture had been freed, recreate it.
|
||||||
|
if tex.tex == nil {
|
||||||
|
return r.StoreTexture(name, tex.image)
|
||||||
|
}
|
||||||
return tex, nil
|
return tex, nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("LoadTexture(%s): not found in texture cache", name)
|
return nil, fmt.Errorf("LoadTexture(%s): not found in texture cache", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FreeTextures flushes the internal cache of SDL2 textures and frees their memory.
|
||||||
|
func (r *Renderer) FreeTextures() int {
|
||||||
|
var num = len(r.textures)
|
||||||
|
for name, tex := range r.textures {
|
||||||
|
delete(r.textures, name)
|
||||||
|
tex.tex.Destroy()
|
||||||
|
}
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user