mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
parent
a4123a479e
commit
5be567d58f
@ -23,6 +23,7 @@ import (
|
||||
_ "image/jpeg"
|
||||
"log"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/gopherjs/gopherwasm/js"
|
||||
|
||||
@ -41,8 +42,39 @@ var (
|
||||
count = 0
|
||||
gophersImage *ebiten.Image
|
||||
extraImages []*ebiten.Image
|
||||
lost = false
|
||||
)
|
||||
|
||||
func loseAndRestoreContext(context js.Value) {
|
||||
if lost {
|
||||
return
|
||||
}
|
||||
|
||||
// Edge might not support the extension. See
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context
|
||||
ext := context.Call("getExtension", "WEBGL_lose_context")
|
||||
if ext == js.Null() {
|
||||
fmt.Println("Fail to force context lost. Edge might not support the extension yet.")
|
||||
return
|
||||
}
|
||||
|
||||
ext.Call("loseContext")
|
||||
fmt.Println("Lost the context!")
|
||||
fmt.Println("The context is automatically restored after 3 seconds.")
|
||||
lost = true
|
||||
|
||||
// If and only if the context is lost by loseContext, you need to call restoreContext. Note that in usual
|
||||
// case of context lost, you cannot call restoreContext but the context should be restored automatically.
|
||||
//
|
||||
// After the context is lost, update will not be called. Instead, fire the goroutine to restore the context.
|
||||
go func() {
|
||||
time.Sleep(3 * time.Second)
|
||||
ext.Call("restoreContext")
|
||||
fmt.Println("Restored the context!")
|
||||
lost = false
|
||||
}()
|
||||
}
|
||||
|
||||
func update(screen *ebiten.Image) error {
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeySpace) && js.Global() != js.Null() {
|
||||
doc := js.Global().Get("document")
|
||||
@ -51,14 +83,8 @@ func update(screen *ebiten.Image) error {
|
||||
if context == js.Null() {
|
||||
context = canvas.Call("getContext", "experimental-webgl")
|
||||
}
|
||||
// Edge might not support the extension. See
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context
|
||||
if ext := context.Call("getExtension", "WEBGL_lose_context"); ext != js.Null() {
|
||||
ext.Call("loseContext")
|
||||
fmt.Println("Context Lost!")
|
||||
} else {
|
||||
fmt.Println("Fail to force context lost. Edge might not support the extension yet.")
|
||||
}
|
||||
|
||||
loseAndRestoreContext(context)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -75,7 +101,7 @@ func update(screen *ebiten.Image) error {
|
||||
op.GeoM.Translate(screenWidth/2, screenHeight/2)
|
||||
screen.DrawImage(gophersImage, op)
|
||||
|
||||
ebitenutil.DebugPrint(screen, "Press Space to force GL context lost!\n(Browser only)")
|
||||
ebitenutil.DebugPrint(screen, "Press Space to force to lose/restore the GL context!\n(Browser only)")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/internal/hooks"
|
||||
"github.com/hajimehoshi/ebiten/internal/shareable"
|
||||
"github.com/hajimehoshi/ebiten/internal/ui"
|
||||
"github.com/hajimehoshi/ebiten/internal/web"
|
||||
)
|
||||
|
||||
func newGraphicsContext(f func(*Image) error) *graphicsContext {
|
||||
@ -155,9 +154,6 @@ func (c *graphicsContext) Update(afterFrameUpdate func()) error {
|
||||
}
|
||||
|
||||
func (c *graphicsContext) needsRestoring() (bool, error) {
|
||||
if web.IsBrowser() {
|
||||
return c.invalidated, nil
|
||||
}
|
||||
return c.offscreen.mipmap.original().IsInvalidated()
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,6 @@ var (
|
||||
|
||||
type contextImpl struct {
|
||||
gl js.Value
|
||||
loseContext js.Value
|
||||
lastProgramID programID
|
||||
}
|
||||
|
||||
@ -116,10 +115,6 @@ func (c *context) ensureGL() {
|
||||
}
|
||||
|
||||
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.Call("getExtension", "WEBGL_lose_context")
|
||||
}
|
||||
|
||||
func (c *context) reset() error {
|
||||
@ -130,7 +125,11 @@ func (c *context) reset() error {
|
||||
c.lastViewportHeight = 0
|
||||
c.lastCompositeMode = graphics.CompositeModeUnknown
|
||||
|
||||
c.gl = js.Value{}
|
||||
c.ensureGL()
|
||||
if c.gl.Call("isContextLost").Bool() {
|
||||
return fmt.Errorf("opengl: the context is lost")
|
||||
}
|
||||
gl := c.gl
|
||||
gl.Call("enable", blend)
|
||||
c.blendFunc(graphics.CompositeModeSourceOver)
|
||||
@ -469,15 +468,3 @@ func (c *context) flush() {
|
||||
gl := c.gl
|
||||
gl.Call("flush")
|
||||
}
|
||||
|
||||
func (c *context) isContextLost() bool {
|
||||
c.ensureGL()
|
||||
gl := c.gl
|
||||
return gl.Call("isContextLost").Bool()
|
||||
}
|
||||
|
||||
func (c *context) restoreContext() {
|
||||
if c.loseContext != js.Null() {
|
||||
c.loseContext.Call("restoreContext")
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
// Copyright 2018 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build js
|
||||
|
||||
package opengl
|
||||
|
||||
func (d *Driver) IsContextLost() bool {
|
||||
return d.context.isContextLost()
|
||||
}
|
||||
|
||||
func (d *Driver) RestoreContext() {
|
||||
d.context.restoreContext()
|
||||
}
|
@ -25,7 +25,6 @@ import (
|
||||
"github.com/gopherjs/gopherwasm/js"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/devicescale"
|
||||
"github.com/hajimehoshi/ebiten/internal/graphicsdriver/opengl"
|
||||
"github.com/hajimehoshi/ebiten/internal/hooks"
|
||||
"github.com/hajimehoshi/ebiten/internal/input"
|
||||
)
|
||||
@ -43,6 +42,7 @@ type userInterface struct {
|
||||
sizeChanged bool
|
||||
windowFocus bool
|
||||
pageVisible bool
|
||||
contextLost bool
|
||||
|
||||
lastActualScale float64
|
||||
}
|
||||
@ -216,15 +216,6 @@ func (u *userInterface) update(g GraphicsContext) error {
|
||||
}
|
||||
hooks.ResumeAudio()
|
||||
|
||||
if opengl.Get().IsContextLost() {
|
||||
opengl.Get().RestoreContext()
|
||||
g.Invalidate()
|
||||
|
||||
// Need to return once to wait restored (#526)
|
||||
// TODO: Is it necessary to handle webglcontextrestored event?
|
||||
return nil
|
||||
}
|
||||
|
||||
input.Get().UpdateGamepads()
|
||||
u.updateGraphicsContext(g)
|
||||
if err := g.Update(func() {
|
||||
@ -241,6 +232,11 @@ func (u *userInterface) loop(g GraphicsContext) <-chan error {
|
||||
ch := make(chan error)
|
||||
var cf js.Callback
|
||||
f := func([]js.Value) {
|
||||
if u.contextLost {
|
||||
requestAnimationFrame.Invoke(cf)
|
||||
return
|
||||
}
|
||||
|
||||
if err := u.update(g); err != nil {
|
||||
ch <- err
|
||||
close(ch)
|
||||
@ -359,11 +355,12 @@ func init() {
|
||||
// Do nothing.
|
||||
}))
|
||||
|
||||
// Context
|
||||
canvas.Call("addEventListener", "webglcontextlost", js.NewEventCallback(js.PreventDefault, func(js.Value) {
|
||||
// Do nothing.
|
||||
currentUI.contextLost = true
|
||||
}))
|
||||
canvas.Call("addEventListener", "webglcontextrestored", js.NewCallback(func(e []js.Value) {
|
||||
// Do nothing.
|
||||
currentUI.contextLost = false
|
||||
}))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user