graphics: Refactoring: remove ExecOnUIThread

This commit is contained in:
Hajime Hoshi 2016-02-20 04:39:43 +09:00
parent 5cfefaf1a2
commit 63f2c3cb9f
6 changed files with 46 additions and 100 deletions

View File

@ -16,16 +16,8 @@ package ebiten
import ( import (
"github.com/hajimehoshi/ebiten/internal/graphics" "github.com/hajimehoshi/ebiten/internal/graphics"
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
"github.com/hajimehoshi/ebiten/internal/ui"
) )
func useGLContext(f func(*opengl.Context)) {
ui.ExecOnUIThread(func() {
f(glContext)
})
}
func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsContext, error) { func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsContext, error) {
c := &graphicsContext{} c := &graphicsContext{}
if err := c.setSize(screenWidth, screenHeight, screenScale); err != nil { if err := c.setSize(screenWidth, screenHeight, screenScale); err != nil {
@ -67,25 +59,22 @@ func (c *graphicsContext) setSize(screenWidth, screenHeight, screenScale int) er
c.screen.Dispose() c.screen.Dispose()
} }
var err error f, err := graphics.NewZeroFramebuffer(glContext, screenWidth*screenScale, screenHeight*screenScale)
useGLContext(func(g *opengl.Context) { if err != nil {
f, err := graphics.NewZeroFramebuffer(g, screenWidth*screenScale, screenHeight*screenScale) return err
if err != nil { }
return
}
texture, err := graphics.NewTexture(g, screenWidth, screenHeight, g.Nearest) texture, err := graphics.NewTexture(glContext, screenWidth, screenHeight, glContext.Nearest)
if err != nil { if err != nil {
return return err
} }
screenF, err := graphics.NewFramebufferFromTexture(g, texture) screenF, err := graphics.NewFramebufferFromTexture(glContext, texture)
if err != nil { if err != nil {
return return err
} }
screen := &Image{framebuffer: screenF, texture: texture} screen := &Image{framebuffer: screenF, texture: texture}
c.defaultRenderTarget = &Image{framebuffer: f, texture: nil} c.defaultRenderTarget = &Image{framebuffer: f, texture: nil}
c.screen = screen c.screen = screen
c.screenScale = screenScale c.screenScale = screenScale
}) return nil
return err
} }

View File

@ -22,7 +22,6 @@ import (
"runtime" "runtime"
"github.com/hajimehoshi/ebiten/internal/graphics" "github.com/hajimehoshi/ebiten/internal/graphics"
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
) )
// Image represents an image. // Image represents an image.
@ -58,10 +57,7 @@ func (i *Image) Fill(clr color.Color) (err error) {
return errors.New("image is already disposed") return errors.New("image is already disposed")
} }
i.pixels = nil i.pixels = nil
useGLContext(func(c *opengl.Context) { return i.framebuffer.Fill(glContext, clr)
err = i.framebuffer.Fill(c, clr)
})
return
} }
// DrawImage draws the given image on the receiver image. // DrawImage draws the given image on the receiver image.
@ -102,10 +98,7 @@ func (i *Image) DrawImage(image *Image, options *DrawImageOptions) (err error) {
} }
w, h := image.Size() w, h := image.Size()
quads := &textureQuads{parts: parts, width: w, height: h} quads := &textureQuads{parts: parts, width: w, height: h}
useGLContext(func(c *opengl.Context) { return i.framebuffer.DrawTexture(glContext, image.texture, quads, &options.GeoM, &options.ColorM)
err = i.framebuffer.DrawTexture(c, image.texture, quads, &options.GeoM, &options.ColorM)
})
return
} }
// Bounds returns the bounds of the image. // Bounds returns the bounds of the image.
@ -127,13 +120,11 @@ func (i *Image) At(x, y int) color.Color {
return color.Transparent return color.Transparent
} }
if i.pixels == nil { if i.pixels == nil {
useGLContext(func(c *opengl.Context) { var err error
var err error i.pixels, err = i.framebuffer.Pixels(glContext)
i.pixels, err = i.framebuffer.Pixels(c) if err != nil {
if err != nil { panic(err)
panic(err) }
}
})
} }
w, _ := i.Size() w, _ := i.Size()
w = graphics.NextPowerOf2Int(w) w = graphics.NextPowerOf2Int(w)
@ -150,12 +141,10 @@ func (i *Image) Dispose() error {
if i.isDisposed() { if i.isDisposed() {
return errors.New("image is already disposed") return errors.New("image is already disposed")
} }
useGLContext(func(c *opengl.Context) { i.framebuffer.Dispose(glContext)
i.framebuffer.Dispose(c) i.framebuffer = nil
i.framebuffer = nil i.texture.Dispose(glContext)
i.texture.Dispose(c) i.texture = nil
i.texture = nil
})
i.pixels = nil i.pixels = nil
runtime.SetFinalizer(i, nil) runtime.SetFinalizer(i, nil)
return nil return nil
@ -184,11 +173,7 @@ func (i *Image) ReplacePixels(p []uint8) error {
if len(p) != l { if len(p) != l {
return errors.New(fmt.Sprintf("p's length must be %d", l)) return errors.New(fmt.Sprintf("p's length must be %d", l))
} }
var err error return i.texture.ReplacePixels(glContext, p)
useGLContext(func(c *opengl.Context) {
err = i.texture.ReplacePixels(c, p)
})
return err
} }
// A DrawImageOptions represents options to render an image on an image. // A DrawImageOptions represents options to render an image on an image.
@ -208,28 +193,20 @@ type DrawImageOptions struct {
// even though nothing refers the image object and GC works. // even though nothing refers the image object and GC works.
// It is because there is no way to define finalizers for Go objects if you use GopherJS. // It is because there is no way to define finalizers for Go objects if you use GopherJS.
func NewImage(width, height int, filter Filter) (*Image, error) { func NewImage(width, height int, filter Filter) (*Image, error) {
var img *Image texture, err := graphics.NewTexture(glContext, width, height, glFilter(glContext, filter))
var err error
useGLContext(func(c *opengl.Context) {
var texture *graphics.Texture
var framebuffer *graphics.Framebuffer
texture, err = graphics.NewTexture(c, width, height, glFilter(c, filter))
if err != nil {
return
}
framebuffer, err = graphics.NewFramebufferFromTexture(c, texture)
if err != nil {
return
}
img = &Image{framebuffer: framebuffer, texture: texture}
})
if err != nil { if err != nil {
return nil, err return nil, err
} }
framebuffer, err := graphics.NewFramebufferFromTexture(glContext, texture)
if err != nil {
// TODO: texture should be removed here?
return nil, err
}
img := &Image{framebuffer: framebuffer, texture: texture}
runtime.SetFinalizer(img, (*Image).Dispose)
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
} }
@ -240,24 +217,16 @@ func NewImage(width, height int, filter Filter) (*Image, error) {
// even though nothing refers the image object and GC works. // even though nothing refers the image object and GC works.
// It is because there is no way to define finalizers for Go objects if you use GopherJS. // It is because there is no way to define finalizers for Go objects if you use GopherJS.
func NewImageFromImage(img image.Image, filter Filter) (*Image, error) { func NewImageFromImage(img image.Image, filter Filter) (*Image, error) {
var eimg *Image texture, err := graphics.NewTextureFromImage(glContext, img, glFilter(glContext, filter))
var err error
useGLContext(func(c *opengl.Context) {
var texture *graphics.Texture
var framebuffer *graphics.Framebuffer
texture, err = graphics.NewTextureFromImage(c, img, glFilter(c, filter))
if err != nil {
return
}
framebuffer, err = graphics.NewFramebufferFromTexture(c, texture)
if err != nil {
return
}
eimg = &Image{framebuffer: framebuffer, texture: texture}
})
if err != nil { if err != nil {
return nil, err return nil, err
} }
framebuffer, err := graphics.NewFramebufferFromTexture(glContext, texture)
if err != nil {
// TODO: texture should be removed here?
return nil, err
}
eimg := &Image{framebuffer: framebuffer, texture: texture}
runtime.SetFinalizer(eimg, (*Image).Dispose) runtime.SetFinalizer(eimg, (*Image).Dispose)
return eimg, nil return eimg, nil
} }

View File

@ -23,7 +23,5 @@ var glContext *opengl.Context
func init() { func init() {
ui.Init() ui.Init()
ui.ExecOnUIThread(func() { glContext = opengl.NewContext()
glContext = opengl.NewContext()
})
} }

View File

@ -60,10 +60,6 @@ func Init() {
currentUI = u currentUI = u
} }
func ExecOnUIThread(f func()) {
f()
}
func Start(width, height, scale int, title string) (actualScale int, err error) { func Start(width, height, scale int, title string) (actualScale int, err error) {
return currentUI.start(width, height, scale, title) return currentUI.start(width, height, scale, title)
} }

View File

@ -27,10 +27,6 @@ func Now() int64 {
return int64(js.Global.Get("performance").Call("now").Float() * float64(time.Millisecond)) return int64(js.Global.Get("performance").Call("now").Float() * float64(time.Millisecond))
} }
func ExecOnUIThread(f func()) {
f()
}
func Start(width, height, scale int, title string) (actualScale int, err error) { func Start(width, height, scale int, title string) (actualScale int, err error) {
return currentUI.start(width, height, scale, title) return currentUI.start(width, height, scale, title)
} }

4
run.go
View File

@ -54,9 +54,7 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
} }
defer ui.Terminate() defer ui.Terminate()
ui.ExecOnUIThread(func() { glContext.Check()
glContext.Check()
})
graphicsContext, err := newGraphicsContext(width, height, actualScale) graphicsContext, err := newGraphicsContext(width, height, actualScale)
if err != nil { if err != nil {
return err return err