mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-12 20:18:59 +01:00
graphics: Remove delayedImageTasks
This commit is contained in:
parent
32c2cb3ead
commit
fabed66b4a
@ -30,7 +30,7 @@ type graphicsContext struct {
|
|||||||
screen *Image
|
screen *Image
|
||||||
defaultRenderTarget *Image
|
defaultRenderTarget *Image
|
||||||
screenScale int
|
screenScale int
|
||||||
imageTasksDone bool
|
initialized bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *graphicsContext) SetSize(screenWidth, screenHeight, screenScale int) error {
|
func (c *graphicsContext) SetSize(screenWidth, screenHeight, screenScale int) error {
|
||||||
@ -55,16 +55,11 @@ func (c *graphicsContext) SetSize(screenWidth, screenHeight, screenScale int) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *graphicsContext) Update() error {
|
func (c *graphicsContext) Update() error {
|
||||||
if !c.imageTasksDone {
|
if !c.initialized {
|
||||||
if err := graphics.Initialize(ui.GLContext()); err != nil {
|
if err := graphics.Initialize(ui.GLContext()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// This execution is called here because we can say actual GL function calls
|
c.initialized = true
|
||||||
// should be done here (especailly on mobiles).
|
|
||||||
if err := theDelayedImageTasks.exec(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.imageTasksDone = true
|
|
||||||
}
|
}
|
||||||
if err := c.screen.Clear(); err != nil {
|
if err := c.screen.Clear(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -104,7 +99,7 @@ func (c *graphicsContext) flush() error {
|
|||||||
|
|
||||||
func (c *graphicsContext) Resume() error {
|
func (c *graphicsContext) Resume() error {
|
||||||
ui.GLContext().Resume()
|
ui.GLContext().Resume()
|
||||||
if !c.imageTasksDone {
|
if !c.initialized {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err := graphics.Initialize(ui.GLContext()); err != nil {
|
if err := graphics.Initialize(ui.GLContext()); err != nil {
|
||||||
|
195
image.go
195
image.go
@ -33,38 +33,6 @@ var (
|
|||||||
imageM sync.Mutex
|
imageM sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
type delayedImageTasks struct {
|
|
||||||
tasks []func() error
|
|
||||||
m sync.Mutex
|
|
||||||
execCalled bool
|
|
||||||
}
|
|
||||||
|
|
||||||
var theDelayedImageTasks = &delayedImageTasks{
|
|
||||||
tasks: []func() error{},
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *delayedImageTasks) add(f func() error) bool {
|
|
||||||
t.m.Lock()
|
|
||||||
defer t.m.Unlock()
|
|
||||||
if t.execCalled {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
t.tasks = append(t.tasks, f)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *delayedImageTasks) exec() error {
|
|
||||||
t.m.Lock()
|
|
||||||
defer t.m.Unlock()
|
|
||||||
t.execCalled = true
|
|
||||||
for _, f := range t.tasks {
|
|
||||||
if err := f(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type images struct {
|
type images struct {
|
||||||
images map[*imageImpl]struct{}
|
images map[*imageImpl]struct{}
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
@ -206,19 +174,13 @@ type imageImpl struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageImpl) Fill(clr color.Color) error {
|
func (i *imageImpl) Fill(clr color.Color) error {
|
||||||
f := func() error {
|
imageM.Lock()
|
||||||
imageM.Lock()
|
defer imageM.Unlock()
|
||||||
defer imageM.Unlock()
|
if i.isDisposed() {
|
||||||
if i.isDisposed() {
|
return errors.New("ebiten: image is already disposed")
|
||||||
return errors.New("ebiten: image is already disposed")
|
|
||||||
}
|
|
||||||
i.pixels = nil
|
|
||||||
return i.framebuffer.Fill(clr)
|
|
||||||
}
|
}
|
||||||
if theDelayedImageTasks.add(f) {
|
i.pixels = nil
|
||||||
return nil
|
return i.framebuffer.Fill(clr)
|
||||||
}
|
|
||||||
return f()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isWholeNumber(x float64) bool {
|
func isWholeNumber(x float64) bool {
|
||||||
@ -251,25 +213,19 @@ func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error {
|
|||||||
if i == image.impl {
|
if i == image.impl {
|
||||||
return errors.New("ebiten: Image.DrawImage: image should be different from the receiver")
|
return errors.New("ebiten: Image.DrawImage: image should be different from the receiver")
|
||||||
}
|
}
|
||||||
f := func() error {
|
imageM.Lock()
|
||||||
imageM.Lock()
|
defer imageM.Unlock()
|
||||||
defer imageM.Unlock()
|
if i.isDisposed() {
|
||||||
if i.isDisposed() {
|
return errors.New("ebiten: image is already disposed")
|
||||||
return errors.New("ebiten: image is already disposed")
|
|
||||||
}
|
|
||||||
i.pixels = nil
|
|
||||||
geom := &options.GeoM
|
|
||||||
colorm := &options.ColorM
|
|
||||||
mode := opengl.CompositeMode(options.CompositeMode)
|
|
||||||
if err := i.framebuffer.DrawTexture(image.impl.texture, vertices[:16*n], geom, colorm, mode); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
if theDelayedImageTasks.add(f) {
|
i.pixels = nil
|
||||||
return nil
|
geom := &options.GeoM
|
||||||
|
colorm := &options.ColorM
|
||||||
|
mode := opengl.CompositeMode(options.CompositeMode)
|
||||||
|
if err := i.framebuffer.DrawTexture(image.impl.texture, vertices[:16*n], geom, colorm, mode); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return f()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageImpl) At(x, y int) color.Color {
|
func (i *imageImpl) At(x, y int) color.Color {
|
||||||
@ -321,27 +277,20 @@ func (i *imageImpl) restorePixels(context *opengl.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageImpl) Dispose() error {
|
func (i *imageImpl) Dispose() error {
|
||||||
f := func() error {
|
imageM.Lock()
|
||||||
imageM.Lock()
|
defer imageM.Unlock()
|
||||||
defer imageM.Unlock()
|
if i.isDisposed() {
|
||||||
if i.isDisposed() {
|
return errors.New("ebiten: image is already disposed")
|
||||||
return errors.New("ebiten: image is already disposed")
|
|
||||||
}
|
|
||||||
if err := graphics.Dispose(i.texture, i.framebuffer); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
i.framebuffer = nil
|
|
||||||
i.texture = nil
|
|
||||||
i.disposed = true
|
|
||||||
i.pixels = nil
|
|
||||||
runtime.SetFinalizer(i, nil)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
if err := graphics.Dispose(i.texture, i.framebuffer); err != nil {
|
||||||
if theDelayedImageTasks.add(f) {
|
return err
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
return f()
|
i.framebuffer = nil
|
||||||
|
i.texture = nil
|
||||||
|
i.disposed = true
|
||||||
|
i.pixels = nil
|
||||||
|
runtime.SetFinalizer(i, nil)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageImpl) isDisposed() bool {
|
func (i *imageImpl) isDisposed() bool {
|
||||||
@ -352,20 +301,14 @@ func (i *imageImpl) ReplacePixels(p []uint8) error {
|
|||||||
if l := 4 * i.width * i.height; len(p) != l {
|
if l := 4 * i.width * i.height; len(p) != l {
|
||||||
return fmt.Errorf("ebiten: p's length must be %d", l)
|
return fmt.Errorf("ebiten: p's length must be %d", l)
|
||||||
}
|
}
|
||||||
f := func() error {
|
imageM.Lock()
|
||||||
imageM.Lock()
|
defer imageM.Unlock()
|
||||||
defer imageM.Unlock()
|
// TODO: Copy p?
|
||||||
// TODO: Copy p?
|
i.pixels = nil
|
||||||
i.pixels = nil
|
if i.isDisposed() {
|
||||||
if i.isDisposed() {
|
return errors.New("ebiten: image is already disposed")
|
||||||
return errors.New("ebiten: image is already disposed")
|
|
||||||
}
|
|
||||||
return i.framebuffer.ReplacePixels(i.texture, p)
|
|
||||||
}
|
}
|
||||||
if theDelayedImageTasks.add(f) {
|
return i.framebuffer.ReplacePixels(i.texture, p)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return f()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A DrawImageOptions represents options to render an image on an image.
|
// A DrawImageOptions represents options to render an image on an image.
|
||||||
@ -394,25 +337,16 @@ func NewImage(width, height int, filter Filter) (*Image, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
f := func() error {
|
imageM.Lock()
|
||||||
imageM.Lock()
|
defer imageM.Unlock()
|
||||||
defer imageM.Unlock()
|
texture, framebuffer, err := graphics.NewImage(width, height, glFilter(ui.GLContext(), filter))
|
||||||
texture, framebuffer, err := graphics.NewImage(width, height, glFilter(ui.GLContext(), filter))
|
if err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
return err
|
|
||||||
}
|
|
||||||
image.framebuffer = framebuffer
|
|
||||||
image.texture = texture
|
|
||||||
runtime.SetFinalizer(image, (*imageImpl).Dispose)
|
|
||||||
if err := image.framebuffer.Fill(color.Transparent); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
if theDelayedImageTasks.add(f) {
|
image.framebuffer = framebuffer
|
||||||
return eimg, nil
|
image.texture = texture
|
||||||
}
|
runtime.SetFinalizer(image, (*imageImpl).Dispose)
|
||||||
if err := f(); err != nil {
|
if err := image.framebuffer.Fill(color.Transparent); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return eimg, nil
|
return eimg, nil
|
||||||
@ -436,33 +370,24 @@ func NewImageFromImage(source image.Image, filter Filter) (*Image, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
f := func() error {
|
// Don't lock while manipulating an image.Image interface.
|
||||||
// Don't lock while manipulating an image.Image interface.
|
rgbaImg, ok := source.(*image.RGBA)
|
||||||
rgbaImg, ok := source.(*image.RGBA)
|
if !ok {
|
||||||
if !ok {
|
origImg := source
|
||||||
origImg := source
|
newImg := image.NewRGBA(origImg.Bounds())
|
||||||
newImg := image.NewRGBA(origImg.Bounds())
|
draw.Draw(newImg, newImg.Bounds(), origImg, origImg.Bounds().Min, draw.Src)
|
||||||
draw.Draw(newImg, newImg.Bounds(), origImg, origImg.Bounds().Min, draw.Src)
|
rgbaImg = newImg
|
||||||
rgbaImg = newImg
|
|
||||||
}
|
|
||||||
imageM.Lock()
|
|
||||||
defer imageM.Unlock()
|
|
||||||
texture, framebuffer, err := graphics.NewImageFromImage(rgbaImg, glFilter(ui.GLContext(), filter))
|
|
||||||
if err != nil {
|
|
||||||
// TODO: texture should be removed here?
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
img.framebuffer = framebuffer
|
|
||||||
img.texture = texture
|
|
||||||
runtime.SetFinalizer(img, (*imageImpl).Dispose)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
if theDelayedImageTasks.add(f) {
|
imageM.Lock()
|
||||||
return eimg, nil
|
defer imageM.Unlock()
|
||||||
}
|
texture, framebuffer, err := graphics.NewImageFromImage(rgbaImg, glFilter(ui.GLContext(), filter))
|
||||||
if err := f(); err != nil {
|
if err != nil {
|
||||||
|
// TODO: texture should be removed here?
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
img.framebuffer = framebuffer
|
||||||
|
img.texture = texture
|
||||||
|
runtime.SetFinalizer(img, (*imageImpl).Dispose)
|
||||||
return eimg, nil
|
return eimg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user