mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
graphics: Remove imageImpl.image member
This commit is contained in:
parent
438afdac5b
commit
fb3724a40e
2
image.go
2
image.go
@ -95,7 +95,7 @@ func (i *images) restore(context *opengl.Context) error {
|
|||||||
if img.isDisposed() {
|
if img.isDisposed() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := img.image.Dispose(); err != nil {
|
if err := img.restorable.Image().Dispose(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
56
imageimpl.go
56
imageimpl.go
@ -23,13 +23,11 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
||||||
"github.com/hajimehoshi/ebiten/internal/restorable"
|
"github.com/hajimehoshi/ebiten/internal/restorable"
|
||||||
)
|
)
|
||||||
|
|
||||||
type imageImpl struct {
|
type imageImpl struct {
|
||||||
image *graphics.Image
|
|
||||||
disposed bool
|
disposed bool
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
@ -41,16 +39,15 @@ type imageImpl struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newImageImpl(width, height int, filter Filter, volatile bool) (*imageImpl, error) {
|
func newImageImpl(width, height int, filter Filter, volatile bool) (*imageImpl, error) {
|
||||||
img, err := graphics.NewImage(width, height, glFilter(filter))
|
img, err := restorable.NewImage(width, height, glFilter(filter))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
i := &imageImpl{
|
i := &imageImpl{
|
||||||
image: img,
|
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
restorable: restorable.NewImage(),
|
restorable: img,
|
||||||
volatile: volatile,
|
volatile: volatile,
|
||||||
}
|
}
|
||||||
runtime.SetFinalizer(i, (*imageImpl).Dispose)
|
runtime.SetFinalizer(i, (*imageImpl).Dispose)
|
||||||
@ -74,17 +71,15 @@ func newImageImplFromImage(source image.Image, filter Filter) (*imageImpl, error
|
|||||||
for j := 0; j < h; j++ {
|
for j := 0; j < h; j++ {
|
||||||
copy(p[j*w*4:(j+1)*w*4], rgbaImg.Pix[j*rgbaImg.Stride:])
|
copy(p[j*w*4:(j+1)*w*4], rgbaImg.Pix[j*rgbaImg.Stride:])
|
||||||
}
|
}
|
||||||
img, err := graphics.NewImageFromImage(rgbaImg, glFilter(filter))
|
img, err := restorable.NewImageFromImage(rgbaImg, glFilter(filter))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: texture should be removed here?
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
i := &imageImpl{
|
i := &imageImpl{
|
||||||
image: img,
|
|
||||||
width: w,
|
width: w,
|
||||||
height: h,
|
height: h,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
restorable: restorable.NewImage(),
|
restorable: img,
|
||||||
}
|
}
|
||||||
i.restorable.ReplacePixels(p)
|
i.restorable.ReplacePixels(p)
|
||||||
runtime.SetFinalizer(i, (*imageImpl).Dispose)
|
runtime.SetFinalizer(i, (*imageImpl).Dispose)
|
||||||
@ -92,15 +87,14 @@ func newImageImplFromImage(source image.Image, filter Filter) (*imageImpl, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newScreenImageImpl(width, height int) (*imageImpl, error) {
|
func newScreenImageImpl(width, height int) (*imageImpl, error) {
|
||||||
img, err := graphics.NewScreenFramebufferImage(width, height)
|
img, err := restorable.NewScreenFramebufferImage(width, height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
i := &imageImpl{
|
i := &imageImpl{
|
||||||
image: img,
|
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
restorable: restorable.NewImage(),
|
restorable: img,
|
||||||
volatile: true,
|
volatile: true,
|
||||||
screen: true,
|
screen: true,
|
||||||
}
|
}
|
||||||
@ -116,7 +110,7 @@ func (i *imageImpl) Fill(clr color.Color) error {
|
|||||||
}
|
}
|
||||||
rgba := color.RGBAModel.Convert(clr).(color.RGBA)
|
rgba := color.RGBAModel.Convert(clr).(color.RGBA)
|
||||||
i.restorable.Fill(rgba)
|
i.restorable.Fill(rgba)
|
||||||
return i.image.Fill(rgba)
|
return i.restorable.Image().Fill(rgba)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageImpl) clearIfVolatile() error {
|
func (i *imageImpl) clearIfVolatile() error {
|
||||||
@ -129,7 +123,7 @@ func (i *imageImpl) clearIfVolatile() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
i.restorable.Clear()
|
i.restorable.Clear()
|
||||||
return i.image.Fill(color.RGBA{})
|
return i.restorable.Image().Fill(color.RGBA{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error {
|
func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error {
|
||||||
@ -169,9 +163,9 @@ func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error {
|
|||||||
if image.impl.restorable.IsStale() {
|
if image.impl.restorable.IsStale() {
|
||||||
i.restorable.MakeStale()
|
i.restorable.MakeStale()
|
||||||
} else {
|
} else {
|
||||||
i.restorable.AppendDrawImageHistory(image.impl.image, vertices, &geom, &colorm, mode)
|
i.restorable.AppendDrawImageHistory(image.impl.restorable.Image(), vertices, &geom, &colorm, mode)
|
||||||
}
|
}
|
||||||
if err := i.image.DrawImage(image.impl.image, vertices, &geom, &colorm, mode); err != nil {
|
if err := i.restorable.Image().DrawImage(image.impl.restorable.Image(), vertices, &geom, &colorm, mode); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -187,7 +181,7 @@ func (i *imageImpl) At(x, y int, context *opengl.Context) color.Color {
|
|||||||
return color.Transparent
|
return color.Transparent
|
||||||
}
|
}
|
||||||
idx := 4*x + 4*y*i.width
|
idx := 4*x + 4*y*i.width
|
||||||
clr, err := i.restorable.At(idx, i.image, context)
|
clr, err := i.restorable.At(idx, i.restorable.Image(), context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -203,7 +197,7 @@ func (i *imageImpl) resolveStalePixels(context *opengl.Context) error {
|
|||||||
if i.volatile {
|
if i.volatile {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err := i.restorable.ReadPixelsFromVRAMIfStale(i.image, context); err != nil {
|
if err := i.restorable.ReadPixelsFromVRAMIfStale(i.restorable.Image(), context); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -223,7 +217,7 @@ func (i *imageImpl) resetPixelsIfDependingOn(target *imageImpl, context *opengl.
|
|||||||
}
|
}
|
||||||
// target is an image that is about to be tried mutating.
|
// target is an image that is about to be tried mutating.
|
||||||
// If pixels object is related to that image, the pixels must be reset.
|
// If pixels object is related to that image, the pixels must be reset.
|
||||||
if !i.restorable.DependsOn(target.image) {
|
if !i.restorable.DependsOn(target.restorable.Image()) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
i.restorable.MakeStale()
|
i.restorable.MakeStale()
|
||||||
@ -243,26 +237,18 @@ func (i *imageImpl) restore(context *opengl.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if i.screen {
|
if i.screen {
|
||||||
// The screen image should also be recreated because framebuffer might
|
if err := i.restorable.RestoreAsScreen(i.width, i.height); err != nil {
|
||||||
// be changed.
|
|
||||||
var err error
|
|
||||||
i.image, err = graphics.NewScreenFramebufferImage(i.width, i.height)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if i.volatile {
|
if i.volatile {
|
||||||
var err error
|
if err := i.restorable.Recreate(i.width, i.height, glFilter(i.filter)); err != nil {
|
||||||
i.image, err = graphics.NewImage(i.width, i.height, glFilter(i.filter))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var err error
|
if err := i.restorable.RestoreImage(context, i.width, i.height, glFilter(i.filter)); err != nil {
|
||||||
i.image, err = i.restorable.CreateImage(context, i.width, i.height, glFilter(i.filter))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -275,11 +261,13 @@ func (i *imageImpl) Dispose() error {
|
|||||||
return errors.New("ebiten: image is already disposed")
|
return errors.New("ebiten: image is already disposed")
|
||||||
}
|
}
|
||||||
if !i.screen {
|
if !i.screen {
|
||||||
if err := i.image.Dispose(); err != nil {
|
if err := i.restorable.Image().Dispose(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i.image = nil
|
if err := i.restorable.Dispose(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
i.disposed = true
|
i.disposed = true
|
||||||
i.restorable.Clear()
|
i.restorable.Clear()
|
||||||
runtime.SetFinalizer(i, nil)
|
runtime.SetFinalizer(i, nil)
|
||||||
@ -296,7 +284,7 @@ func (i *imageImpl) ReplacePixels(p []uint8) error {
|
|||||||
if i.disposed {
|
if i.disposed {
|
||||||
return errors.New("ebiten: image is already disposed")
|
return errors.New("ebiten: image is already disposed")
|
||||||
}
|
}
|
||||||
return i.image.ReplacePixels(p)
|
return i.restorable.Image().ReplacePixels(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageImpl) isDisposed() bool {
|
func (i *imageImpl) isDisposed() bool {
|
||||||
@ -308,5 +296,5 @@ func (i *imageImpl) isDisposed() bool {
|
|||||||
func (i *imageImpl) isInvalidated(context *opengl.Context) bool {
|
func (i *imageImpl) isInvalidated(context *opengl.Context) bool {
|
||||||
i.m.Lock()
|
i.m.Lock()
|
||||||
defer i.m.Unlock()
|
defer i.m.Unlock()
|
||||||
return i.image.IsInvalidated(context)
|
return i.restorable.Image().IsInvalidated(context)
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,8 @@ type drawImageHistoryItem struct {
|
|||||||
|
|
||||||
// Image represents an image of an image for restoring when GL context is lost.
|
// Image represents an image of an image for restoring when GL context is lost.
|
||||||
type Image struct {
|
type Image struct {
|
||||||
|
image *graphics.Image
|
||||||
|
|
||||||
// baseImage and baseColor are exclusive.
|
// baseImage and baseColor are exclusive.
|
||||||
basePixels []uint8
|
basePixels []uint8
|
||||||
baseColor color.RGBA
|
baseColor color.RGBA
|
||||||
@ -40,8 +42,35 @@ type Image struct {
|
|||||||
stale bool
|
stale bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImage() *Image {
|
func NewImage(width, height int, filter opengl.Filter) (*Image, error) {
|
||||||
return &Image{}
|
img, err := graphics.NewImage(width, height, filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Image{
|
||||||
|
image: img,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewImageFromImage(source *image.RGBA, filter opengl.Filter) (*Image, error) {
|
||||||
|
img, err := graphics.NewImageFromImage(source, filter)
|
||||||
|
if err != nil {
|
||||||
|
// TODO: texture should be removed here?
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Image{
|
||||||
|
image: img,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewScreenFramebufferImage(width, height int) (*Image, error) {
|
||||||
|
img, err := graphics.NewScreenFramebufferImage(width, height)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Image{
|
||||||
|
image: img,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Image) IsStale() bool {
|
func (p *Image) IsStale() bool {
|
||||||
@ -79,6 +108,11 @@ func (p *Image) ReplacePixels(pixels []uint8) {
|
|||||||
p.stale = false
|
p.stale = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Image) Image() *graphics.Image {
|
||||||
|
// TODO: This function is temporary. Remove this.
|
||||||
|
return p.image
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Image) AppendDrawImageHistory(image *graphics.Image, vertices []int16, geom graphics.Matrix, colorm graphics.Matrix, mode opengl.CompositeMode) {
|
func (p *Image) AppendDrawImageHistory(image *graphics.Image, vertices []int16, geom graphics.Matrix, colorm graphics.Matrix, mode opengl.CompositeMode) {
|
||||||
if p.stale {
|
if p.stale {
|
||||||
return
|
return
|
||||||
@ -148,10 +182,10 @@ func (p *Image) HasDependency() bool {
|
|||||||
return p.drawImageHistory != nil
|
return p.drawImageHistory != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateImage restores *graphics.Image from the pixels using its state.
|
// RestoreImage restores *graphics.Image from the pixels using its state.
|
||||||
func (p *Image) CreateImage(context *opengl.Context, width, height int, filter opengl.Filter) (*graphics.Image, error) {
|
func (p *Image) RestoreImage(context *opengl.Context, width, height int, filter opengl.Filter) error {
|
||||||
if p.stale {
|
if p.stale {
|
||||||
return nil, errors.New("pixels: pixels must not be stale when restoring")
|
return errors.New("restorable: pixels must not be stale when restoring")
|
||||||
}
|
}
|
||||||
img := image.NewRGBA(image.Rect(0, 0, width, height))
|
img := image.NewRGBA(image.Rect(0, 0, width, height))
|
||||||
if p.basePixels != nil {
|
if p.basePixels != nil {
|
||||||
@ -161,14 +195,14 @@ func (p *Image) CreateImage(context *opengl.Context, width, height int, filter o
|
|||||||
}
|
}
|
||||||
gimg, err := graphics.NewImageFromImage(img, filter)
|
gimg, err := graphics.NewImageFromImage(img, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if p.baseColor != (color.RGBA{}) {
|
if p.baseColor != (color.RGBA{}) {
|
||||||
if p.basePixels != nil {
|
if p.basePixels != nil {
|
||||||
panic("not reach")
|
panic("not reach")
|
||||||
}
|
}
|
||||||
if err := gimg.Fill(p.baseColor); err != nil {
|
if err := gimg.Fill(p.baseColor); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, c := range p.drawImageHistory {
|
for _, c := range p.drawImageHistory {
|
||||||
@ -177,15 +211,44 @@ func (p *Image) CreateImage(context *opengl.Context, width, height int, filter o
|
|||||||
panic("not reach")
|
panic("not reach")
|
||||||
}*/
|
}*/
|
||||||
if err := gimg.DrawImage(c.image, c.vertices, c.geom, c.colorm, c.mode); err != nil {
|
if err := gimg.DrawImage(c.image, c.vertices, c.geom, c.colorm, c.mode); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
p.image = gimg
|
||||||
|
|
||||||
p.basePixels, err = gimg.Pixels(context)
|
p.basePixels, err = gimg.Pixels(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
p.baseColor = color.RGBA{}
|
p.baseColor = color.RGBA{}
|
||||||
p.drawImageHistory = nil
|
p.drawImageHistory = nil
|
||||||
p.stale = false
|
p.stale = false
|
||||||
return gimg, nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Image) RestoreAsScreen(width, height int) error {
|
||||||
|
// The screen image should also be recreated because framebuffer might
|
||||||
|
// be changed.
|
||||||
|
var err error
|
||||||
|
p.image, err = graphics.NewScreenFramebufferImage(width, height)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// TODO: Reset other values?
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Image) Recreate(width, height int, filter opengl.Filter) error {
|
||||||
|
var err error
|
||||||
|
p.image, err = graphics.NewImage(width, height, filter)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// TODO: Reset other values?
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Image) Dispose() error {
|
||||||
|
p.image = nil
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user