mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 02:42:02 +01:00
image: Use SetFinalizer for images (#67)
This commit is contained in:
parent
e8c2e5f3d6
commit
27f1a865aa
35
image.go
35
image.go
@ -17,10 +17,12 @@ package ebiten
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Image represents an image.
|
// Image represents an image.
|
||||||
@ -44,11 +46,17 @@ func (i *Image) Size() (width, height int) {
|
|||||||
|
|
||||||
// Clear resets the pixels of the image into 0.
|
// Clear resets the pixels of the image into 0.
|
||||||
func (i *Image) Clear() (err error) {
|
func (i *Image) Clear() (err error) {
|
||||||
|
if i.isDisposed() {
|
||||||
|
return errors.New("image is already disposed")
|
||||||
|
}
|
||||||
return i.Fill(color.Transparent)
|
return i.Fill(color.Transparent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill fills the image with a solid color.
|
// Fill fills the image with a solid color.
|
||||||
func (i *Image) Fill(clr color.Color) (err error) {
|
func (i *Image) Fill(clr color.Color) (err error) {
|
||||||
|
if i.isDisposed() {
|
||||||
|
return errors.New("image is already disposed")
|
||||||
|
}
|
||||||
i.pixels = nil
|
i.pixels = nil
|
||||||
useGLContext(func(c *opengl.Context) {
|
useGLContext(func(c *opengl.Context) {
|
||||||
err = i.framebuffer.Fill(c, clr)
|
err = i.framebuffer.Fill(c, clr)
|
||||||
@ -71,6 +79,9 @@ func (i *Image) Fill(clr color.Color) (err error) {
|
|||||||
// Be careful that this method is potentially slow.
|
// Be careful that this method is potentially slow.
|
||||||
// It would be better if you could call this method fewer times.
|
// It would be better if you could call this method fewer times.
|
||||||
func (i *Image) DrawImage(image *Image, options *DrawImageOptions) (err error) {
|
func (i *Image) DrawImage(image *Image, options *DrawImageOptions) (err error) {
|
||||||
|
if i.isDisposed() {
|
||||||
|
return errors.New("image is already disposed")
|
||||||
|
}
|
||||||
if i == image {
|
if i == image {
|
||||||
return errors.New("Image.DrawImage: image should be different from the receiver")
|
return errors.New("Image.DrawImage: image should be different from the receiver")
|
||||||
}
|
}
|
||||||
@ -112,6 +123,9 @@ func (i *Image) ColorModel() color.Model {
|
|||||||
//
|
//
|
||||||
// This method loads pixels from VRAM to system memory if necessary.
|
// This method loads pixels from VRAM to system memory if necessary.
|
||||||
func (i *Image) At(x, y int) color.Color {
|
func (i *Image) At(x, y int) color.Color {
|
||||||
|
if i.isDisposed() {
|
||||||
|
return color.Transparent
|
||||||
|
}
|
||||||
if i.pixels == nil {
|
if i.pixels == nil {
|
||||||
useGLContext(func(c *opengl.Context) {
|
useGLContext(func(c *opengl.Context) {
|
||||||
var err error
|
var err error
|
||||||
@ -130,9 +144,11 @@ func (i *Image) At(x, y int) color.Color {
|
|||||||
|
|
||||||
// Dispose disposes the image data. After disposing, the image becomes invalid.
|
// Dispose disposes the image data. After disposing, the image becomes invalid.
|
||||||
// This is useful to save memory.
|
// This is useful to save memory.
|
||||||
func (i *Image) Dispose() {
|
//
|
||||||
|
// The behavior of any functions for a disposed image is undefined.
|
||||||
|
func (i *Image) Dispose() error {
|
||||||
if i.isDisposed() {
|
if i.isDisposed() {
|
||||||
panic("the image is already disposed")
|
return errors.New("image is already disposed")
|
||||||
}
|
}
|
||||||
useGLContext(func(c *opengl.Context) {
|
useGLContext(func(c *opengl.Context) {
|
||||||
i.framebuffer.Dispose(c)
|
i.framebuffer.Dispose(c)
|
||||||
@ -141,10 +157,11 @@ func (i *Image) Dispose() {
|
|||||||
i.texture = nil
|
i.texture = nil
|
||||||
})
|
})
|
||||||
i.pixels = nil
|
i.pixels = nil
|
||||||
|
runtime.SetFinalizer(i, nil)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDisposed returns a boolean indicating wheather the image is disposed.
|
func (i *Image) isDisposed() bool {
|
||||||
func (i *Image) IsDisposed() bool {
|
|
||||||
return i.texture == nil
|
return i.texture == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,8 +171,10 @@ func (i *Image) IsDisposed() bool {
|
|||||||
//
|
//
|
||||||
// This function may be slow (as for implementation, this calls glTexSubImage2D).
|
// This function may be slow (as for implementation, this calls glTexSubImage2D).
|
||||||
func (i *Image) ReplacePixels(p []uint8) error {
|
func (i *Image) ReplacePixels(p []uint8) error {
|
||||||
|
if i.isDisposed() {
|
||||||
|
return errors.New("image is already disposed")
|
||||||
|
}
|
||||||
// Don't set i.pixels here because i.pixels is used not every time.
|
// Don't set i.pixels here because i.pixels is used not every time.
|
||||||
|
|
||||||
i.pixels = nil
|
i.pixels = nil
|
||||||
w, h := i.Size()
|
w, h := i.Size()
|
||||||
l := 4 * w * h
|
l := 4 * w * h
|
||||||
@ -207,6 +226,7 @@ func NewImage(width, height int, filter Filter) (*Image, error) {
|
|||||||
if err := img.Clear(); err != nil {
|
if err := img.Clear(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
runtime.SetFinalizer(img, (*Image).Dispose)
|
||||||
return img, nil
|
return img, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,5 +255,6 @@ func NewImageFromImage(img image.Image, filter Filter) (*Image, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
runtime.SetFinalizer(eimg, (*Image).Dispose)
|
||||||
return eimg, nil
|
return eimg, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user