diff --git a/internal/graphics/image.go b/internal/graphics/image.go index 8e8d81ea4..87dc56dce 100644 --- a/internal/graphics/image.go +++ b/internal/graphics/image.go @@ -180,7 +180,7 @@ func (i *Image) ReplacePixels(p []uint8) error { } func (i *Image) IsInvalidated(context *opengl.Context) bool { - return context.IsContextLost(i.texture.native) + return !context.IsTexture(i.texture.native) } func (i *Image) createFramebufferIfNeeded(context *opengl.Context) (*framebuffer, error) { diff --git a/internal/opengl/context_desktop.go b/internal/opengl/context_desktop.go index 879e43c04..8f3e8dc6d 100644 --- a/internal/opengl/context_desktop.go +++ b/internal/opengl/context_desktop.go @@ -514,7 +514,3 @@ func (c *Context) Flush() { return nil }) } - -func (c *Context) IsContextLost(t Texture) bool { - return !c.IsTexture(t) -} diff --git a/internal/opengl/context_js.go b/internal/opengl/context_js.go index 6699937cb..b269da9b7 100644 --- a/internal/opengl/context_js.go +++ b/internal/opengl/context_js.go @@ -87,6 +87,7 @@ func init() { type context struct { gl *webgl.Context + loseContext *js.Object lastProgramID programID } @@ -116,6 +117,15 @@ func NewContext() (*Context, error) { } c := &Context{} c.gl = gl + // Getting an extension might fail after the context is lost, so + // it is required to get the extension here. + c.loseContext = gl.GetExtension("WEBGL_lose_context") + if c.loseContext != nil { + // This testing function name is temporary. + js.Global.Set("_ebiten_loseContextForTesting", func() { + c.loseContext.Call("loseContext") + }) + } return c, nil } @@ -408,7 +418,13 @@ func (c *Context) Flush() { gl.Flush() } -func (c *Context) IsContextLost(t Texture) bool { +func (c *Context) IsContextLost() bool { gl := c.gl return gl.IsContextLost() } + +func (c *Context) RestoreContext() { + if c.loseContext != nil { + c.loseContext.Call("restoreContext") + } +} diff --git a/internal/opengl/context_mobile.go b/internal/opengl/context_mobile.go index dfdde8fa2..cd73d98c2 100644 --- a/internal/opengl/context_mobile.go +++ b/internal/opengl/context_mobile.go @@ -430,7 +430,3 @@ func (c *Context) Flush() { gl := c.gl gl.Flush() } - -func (c *Context) IsContextLost(t Texture) bool { - return !c.IsTexture(t) -} diff --git a/internal/ui/ui_js.go b/internal/ui/ui_js.go index 2f36c8d41..bd19adc9a 100644 --- a/internal/ui/ui_js.go +++ b/internal/ui/ui_js.go @@ -27,17 +27,15 @@ import ( var canvas *js.Object type userInterface struct { - scale float64 - deviceScale float64 - sizeChanged bool - contextRestored bool - windowFocus bool + scale float64 + deviceScale float64 + sizeChanged bool + windowFocus bool } var currentUI = &userInterface{ - sizeChanged: true, - contextRestored: true, - windowFocus: true, + sizeChanged: true, + windowFocus: true, } // NOTE: This returns true even when the browser is not active. @@ -74,8 +72,8 @@ func (u *userInterface) update(g GraphicsContext) error { if !u.windowFocus { return nil } - if !u.contextRestored { - return nil + if glContext.IsContextLost() { + glContext.RestoreContext() } currentInput.updateGamepads() if u.sizeChanged { @@ -235,12 +233,11 @@ func initialize() error { canvas.Call("addEventListener", "webglcontextlost", func(e *js.Object) { e.Call("preventDefault") - currentUI.contextRestored = false }) canvas.Call("addEventListener", "webglcontextrestored", func(e *js.Object) { - // TODO: Call preventDefault? - currentUI.contextRestored = true + // Do nothing. }) + return nil }