diff --git a/image.go b/image.go index c742cc857..7513ab203 100644 --- a/image.go +++ b/image.go @@ -231,13 +231,13 @@ func NewImageFromImage(source image.Image, filter Filter) (*Image, error) { } func newImageWithScreenFramebuffer(width, height int) (*Image, error) { - i, err := graphics.NewScreenFramebufferImage(width, height) + img, err := newScreenImageImpl(width, height) if err != nil { return nil, err } - img, err := newImageImpl(i, FilterNearest) + eimg, err := theImagesForRestoring.add(img) if err != nil { return nil, err } - return &Image{img}, nil + return eimg, nil } diff --git a/imageimpl.go b/imageimpl.go index 698a8f9b2..4338fb0b2 100644 --- a/imageimpl.go +++ b/imageimpl.go @@ -37,6 +37,7 @@ type imageImpl struct { filter Filter pixels []uint8 noSave bool + screen bool m sync.Mutex } @@ -84,6 +85,19 @@ func newImageImplFromImage(source image.Image, filter Filter) (*imageImpl, error return i, nil } +func newScreenImageImpl(width, height int) (*imageImpl, error) { + i, err := graphics.NewScreenFramebufferImage(width, height) + if err != nil { + return nil, err + } + img, err := newImageImpl(i, FilterNearest) + if err != nil { + return nil, err + } + img.screen = true + return img, nil +} + func (i *imageImpl) Fill(clr color.Color) error { i.m.Lock() defer i.m.Unlock() @@ -159,6 +173,9 @@ func (i *imageImpl) At(x, y int) color.Color { func (i *imageImpl) savePixels(context *opengl.Context) error { i.m.Lock() defer i.m.Unlock() + if i.screen { + return nil + } if i.noSave { return nil } @@ -182,6 +199,16 @@ func (i *imageImpl) restorePixels() error { if i.disposed { return nil } + if i.screen { + // The screen image should also be recreated because framebuffer might + // be changed. + var err error + i.image, err = graphics.NewScreenFramebufferImage(i.width, i.height) + if err != nil { + return err + } + return nil + } if i.pixels != nil { img := image.NewRGBA(image.Rect(0, 0, i.width, i.height)) for j := 0; j < i.height; j++ { @@ -208,8 +235,10 @@ func (i *imageImpl) Dispose() error { if i.disposed { return errors.New("ebiten: image is already disposed") } - if err := i.image.Dispose(); err != nil { - return err + if !i.screen { + if err := i.image.Dispose(); err != nil { + return err + } } i.image = nil i.disposed = true diff --git a/internal/graphics/command.go b/internal/graphics/command.go index 65913ae31..dae275ed7 100644 --- a/internal/graphics/command.go +++ b/internal/graphics/command.go @@ -167,7 +167,7 @@ type disposeCommand struct { } func (c *disposeCommand) Exec(context *opengl.Context) error { - if c.target.framebuffer != nil && c.target.framebuffer.native != context.ScreenFramebuffer() { + if c.target.framebuffer != nil { context.DeleteFramebuffer(c.target.framebuffer.native) } if c.target.texture != nil {