mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +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() {
|
||||
continue
|
||||
}
|
||||
if err := img.image.Dispose(); err != nil {
|
||||
if err := img.restorable.Image().Dispose(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
56
imageimpl.go
56
imageimpl.go
@ -23,13 +23,11 @@ import (
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
||||
"github.com/hajimehoshi/ebiten/internal/restorable"
|
||||
)
|
||||
|
||||
type imageImpl struct {
|
||||
image *graphics.Image
|
||||
disposed bool
|
||||
width int
|
||||
height int
|
||||
@ -41,16 +39,15 @@ type imageImpl struct {
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
i := &imageImpl{
|
||||
image: img,
|
||||
width: width,
|
||||
height: height,
|
||||
filter: filter,
|
||||
restorable: restorable.NewImage(),
|
||||
restorable: img,
|
||||
volatile: volatile,
|
||||
}
|
||||
runtime.SetFinalizer(i, (*imageImpl).Dispose)
|
||||
@ -74,17 +71,15 @@ func newImageImplFromImage(source image.Image, filter Filter) (*imageImpl, error
|
||||
for j := 0; j < h; j++ {
|
||||
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 {
|
||||
// TODO: texture should be removed here?
|
||||
return nil, err
|
||||
}
|
||||
i := &imageImpl{
|
||||
image: img,
|
||||
width: w,
|
||||
height: h,
|
||||
filter: filter,
|
||||
restorable: restorable.NewImage(),
|
||||
restorable: img,
|
||||
}
|
||||
i.restorable.ReplacePixels(p)
|
||||
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) {
|
||||
img, err := graphics.NewScreenFramebufferImage(width, height)
|
||||
img, err := restorable.NewScreenFramebufferImage(width, height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
i := &imageImpl{
|
||||
image: img,
|
||||
width: width,
|
||||
height: height,
|
||||
restorable: restorable.NewImage(),
|
||||
restorable: img,
|
||||
volatile: true,
|
||||
screen: true,
|
||||
}
|
||||
@ -116,7 +110,7 @@ func (i *imageImpl) Fill(clr color.Color) error {
|
||||
}
|
||||
rgba := color.RGBAModel.Convert(clr).(color.RGBA)
|
||||
i.restorable.Fill(rgba)
|
||||
return i.image.Fill(rgba)
|
||||
return i.restorable.Image().Fill(rgba)
|
||||
}
|
||||
|
||||
func (i *imageImpl) clearIfVolatile() error {
|
||||
@ -129,7 +123,7 @@ func (i *imageImpl) clearIfVolatile() error {
|
||||
return nil
|
||||
}
|
||||
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 {
|
||||
@ -169,9 +163,9 @@ func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error {
|
||||
if image.impl.restorable.IsStale() {
|
||||
i.restorable.MakeStale()
|
||||
} 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 nil
|
||||
@ -187,7 +181,7 @@ func (i *imageImpl) At(x, y int, context *opengl.Context) color.Color {
|
||||
return color.Transparent
|
||||
}
|
||||
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 {
|
||||
panic(err)
|
||||
}
|
||||
@ -203,7 +197,7 @@ func (i *imageImpl) resolveStalePixels(context *opengl.Context) error {
|
||||
if i.volatile {
|
||||
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 nil
|
||||
@ -223,7 +217,7 @@ func (i *imageImpl) resetPixelsIfDependingOn(target *imageImpl, context *opengl.
|
||||
}
|
||||
// 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 !i.restorable.DependsOn(target.image) {
|
||||
if !i.restorable.DependsOn(target.restorable.Image()) {
|
||||
return nil
|
||||
}
|
||||
i.restorable.MakeStale()
|
||||
@ -243,26 +237,18 @@ func (i *imageImpl) restore(context *opengl.Context) error {
|
||||
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 {
|
||||
if err := i.restorable.RestoreAsScreen(i.width, i.height); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if i.volatile {
|
||||
var err error
|
||||
i.image, err = graphics.NewImage(i.width, i.height, glFilter(i.filter))
|
||||
if err != nil {
|
||||
if err := i.restorable.Recreate(i.width, i.height, glFilter(i.filter)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
i.image, err = i.restorable.CreateImage(context, i.width, i.height, glFilter(i.filter))
|
||||
if err != nil {
|
||||
if err := i.restorable.RestoreImage(context, i.width, i.height, glFilter(i.filter)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -275,11 +261,13 @@ func (i *imageImpl) Dispose() error {
|
||||
return errors.New("ebiten: image is already disposed")
|
||||
}
|
||||
if !i.screen {
|
||||
if err := i.image.Dispose(); err != nil {
|
||||
if err := i.restorable.Image().Dispose(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
i.image = nil
|
||||
if err := i.restorable.Dispose(); err != nil {
|
||||
return err
|
||||
}
|
||||
i.disposed = true
|
||||
i.restorable.Clear()
|
||||
runtime.SetFinalizer(i, nil)
|
||||
@ -296,7 +284,7 @@ func (i *imageImpl) ReplacePixels(p []uint8) error {
|
||||
if i.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 {
|
||||
@ -308,5 +296,5 @@ func (i *imageImpl) isDisposed() bool {
|
||||
func (i *imageImpl) isInvalidated(context *opengl.Context) bool {
|
||||
i.m.Lock()
|
||||
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.
|
||||
type Image struct {
|
||||
image *graphics.Image
|
||||
|
||||
// baseImage and baseColor are exclusive.
|
||||
basePixels []uint8
|
||||
baseColor color.RGBA
|
||||
@ -40,8 +42,35 @@ type Image struct {
|
||||
stale bool
|
||||
}
|
||||
|
||||
func NewImage() *Image {
|
||||
return &Image{}
|
||||
func NewImage(width, height int, filter opengl.Filter) (*Image, error) {
|
||||
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 {
|
||||
@ -79,6 +108,11 @@ func (p *Image) ReplacePixels(pixels []uint8) {
|
||||
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) {
|
||||
if p.stale {
|
||||
return
|
||||
@ -148,10 +182,10 @@ func (p *Image) HasDependency() bool {
|
||||
return p.drawImageHistory != nil
|
||||
}
|
||||
|
||||
// CreateImage 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) {
|
||||
// RestoreImage restores *graphics.Image from the pixels using its state.
|
||||
func (p *Image) RestoreImage(context *opengl.Context, width, height int, filter opengl.Filter) error {
|
||||
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))
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if p.baseColor != (color.RGBA{}) {
|
||||
if p.basePixels != nil {
|
||||
panic("not reach")
|
||||
}
|
||||
if err := gimg.Fill(p.baseColor); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, c := range p.drawImageHistory {
|
||||
@ -177,15 +211,44 @@ func (p *Image) CreateImage(context *opengl.Context, width, height int, filter o
|
||||
panic("not reach")
|
||||
}*/
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
p.baseColor = color.RGBA{}
|
||||
p.drawImageHistory = nil
|
||||
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