mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-11 19:48:54 +01:00
restorable: Add an explicit way to detect context-lost
isTexture was used to detect context-lost and called every frame. This was not good for performance. This change adds a way to notify context-lost from the WebGL handlers directly, and the package restorable uses it instead of calling (*Image).isInvalaidated. Fixes #1175
This commit is contained in:
parent
117fd61d27
commit
2bdef2e8c4
@ -309,9 +309,8 @@ func (c *context) deleteTexture(t textureNative) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) isTexture(t textureNative) bool {
|
func (c *context) isTexture(t textureNative) bool {
|
||||||
c.ensureGL()
|
// isTexture should not be called to detect context-lost since this performance is not good (#1175).
|
||||||
gl := c.gl
|
panic("opengl: isTexture is not implemented")
|
||||||
return gl.Call("isTexture", js.Value(t)).Bool()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) newFramebuffer(t textureNative) (framebufferNative, error) {
|
func (c *context) newFramebuffer(t textureNative) (framebufferNative, error) {
|
||||||
|
@ -39,9 +39,10 @@ func EnableRestoringForTesting() {
|
|||||||
|
|
||||||
// images is a set of Image objects.
|
// images is a set of Image objects.
|
||||||
type images struct {
|
type images struct {
|
||||||
images map[*Image]struct{}
|
images map[*Image]struct{}
|
||||||
shaders map[*Shader]struct{}
|
shaders map[*Shader]struct{}
|
||||||
lastTarget *Image
|
lastTarget *Image
|
||||||
|
contextLost bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// theImages represents the images for the current process.
|
// theImages represents the images for the current process.
|
||||||
@ -73,21 +74,27 @@ func RestoreIfNeeded() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !forceRestoring {
|
if !forceRestoring {
|
||||||
r := false
|
var r bool
|
||||||
// As isInvalidated() is expensive, call this only for one image.
|
|
||||||
// This assumes that if there is one image that is invalidated, all images are invalidated.
|
if canDetectContextLostExplicitly {
|
||||||
for img := range theImages.images {
|
r = theImages.contextLost
|
||||||
// The screen image might not have a texture. Skip this.
|
} else {
|
||||||
if img.screen {
|
// As isInvalidated() is expensive, call this only for one image.
|
||||||
continue
|
// This assumes that if there is one image that is invalidated, all images are invalidated.
|
||||||
|
for img := range theImages.images {
|
||||||
|
// The screen image might not have a texture. Skip this.
|
||||||
|
if img.screen {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
r, err = img.isInvalidated()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
var err error
|
|
||||||
r, err = img.isInvalidated()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !r {
|
if !r {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -257,6 +264,9 @@ func (i *images) restore() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i.contextLost = false
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,3 +274,11 @@ func (i *images) restore() error {
|
|||||||
func InitializeGraphicsDriverState() error {
|
func InitializeGraphicsDriverState() error {
|
||||||
return graphicscommand.ResetGraphicsDriverState()
|
return graphicscommand.ResetGraphicsDriverState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnContextLost is called when the context lost is detected in an explicit way.
|
||||||
|
func OnContextLost() {
|
||||||
|
if !canDetectContextLostExplicitly {
|
||||||
|
panic("restorable: OnContextLost cannot be called in this environment")
|
||||||
|
}
|
||||||
|
theImages.contextLost = true
|
||||||
|
}
|
||||||
|
@ -16,7 +16,11 @@
|
|||||||
|
|
||||||
package restorable
|
package restorable
|
||||||
|
|
||||||
|
// needsDisposingWhenRestoring reports whether disposing resources is necessary or not when restoring.
|
||||||
|
//
|
||||||
// On browsers, disposing resources is not required since the objects are already managed by JavaScript GC and they
|
// On browsers, disposing resources is not required since the objects are already managed by JavaScript GC and they
|
||||||
// are already invalidated. Rather, disposing them when restoring causes warnings on the console.
|
// are already invalidated. Rather, disposing them when restoring causes warnings on the console.
|
||||||
|
|
||||||
const needsDisposingWhenRestoring = false
|
const needsDisposingWhenRestoring = false
|
||||||
|
|
||||||
|
// canDetectContextLostExplicitly reports whether the context lost can be detected by handlers in an explicit way.
|
||||||
|
const canDetectContextLostExplicitly = true
|
||||||
|
@ -17,3 +17,5 @@
|
|||||||
package restorable
|
package restorable
|
||||||
|
|
||||||
const needsDisposingWhenRestoring = true
|
const needsDisposingWhenRestoring = true
|
||||||
|
|
||||||
|
const canDetectContextLostExplicitly = false
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/internal/graphicsdriver/opengl"
|
"github.com/hajimehoshi/ebiten/internal/graphicsdriver/opengl"
|
||||||
"github.com/hajimehoshi/ebiten/internal/hooks"
|
"github.com/hajimehoshi/ebiten/internal/hooks"
|
||||||
"github.com/hajimehoshi/ebiten/internal/jsutil"
|
"github.com/hajimehoshi/ebiten/internal/jsutil"
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/restorable"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserInterface struct {
|
type UserInterface struct {
|
||||||
@ -400,6 +401,7 @@ func init() {
|
|||||||
e := args[0]
|
e := args[0]
|
||||||
e.Call("preventDefault")
|
e.Call("preventDefault")
|
||||||
theUI.contextLost = true
|
theUI.contextLost = true
|
||||||
|
restorable.OnContextLost()
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
canvas.Call("addEventListener", "webglcontextrestored", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
canvas.Call("addEventListener", "webglcontextrestored", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
|
Loading…
Reference in New Issue
Block a user