mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
parent
a4123a479e
commit
5be567d58f
@ -23,6 +23,7 @@ import (
|
|||||||
_ "image/jpeg"
|
_ "image/jpeg"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gopherjs/gopherwasm/js"
|
"github.com/gopherjs/gopherwasm/js"
|
||||||
|
|
||||||
@ -41,8 +42,39 @@ var (
|
|||||||
count = 0
|
count = 0
|
||||||
gophersImage *ebiten.Image
|
gophersImage *ebiten.Image
|
||||||
extraImages []*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 {
|
func update(screen *ebiten.Image) error {
|
||||||
if inpututil.IsKeyJustPressed(ebiten.KeySpace) && js.Global() != js.Null() {
|
if inpututil.IsKeyJustPressed(ebiten.KeySpace) && js.Global() != js.Null() {
|
||||||
doc := js.Global().Get("document")
|
doc := js.Global().Get("document")
|
||||||
@ -51,14 +83,8 @@ func update(screen *ebiten.Image) error {
|
|||||||
if context == js.Null() {
|
if context == js.Null() {
|
||||||
context = canvas.Call("getContext", "experimental-webgl")
|
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
|
loseAndRestoreContext(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.")
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +101,7 @@ func update(screen *ebiten.Image) error {
|
|||||||
op.GeoM.Translate(screenWidth/2, screenHeight/2)
|
op.GeoM.Translate(screenWidth/2, screenHeight/2)
|
||||||
screen.DrawImage(gophersImage, op)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/internal/hooks"
|
"github.com/hajimehoshi/ebiten/internal/hooks"
|
||||||
"github.com/hajimehoshi/ebiten/internal/shareable"
|
"github.com/hajimehoshi/ebiten/internal/shareable"
|
||||||
"github.com/hajimehoshi/ebiten/internal/ui"
|
"github.com/hajimehoshi/ebiten/internal/ui"
|
||||||
"github.com/hajimehoshi/ebiten/internal/web"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newGraphicsContext(f func(*Image) error) *graphicsContext {
|
func newGraphicsContext(f func(*Image) error) *graphicsContext {
|
||||||
@ -155,9 +154,6 @@ func (c *graphicsContext) Update(afterFrameUpdate func()) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *graphicsContext) needsRestoring() (bool, error) {
|
func (c *graphicsContext) needsRestoring() (bool, error) {
|
||||||
if web.IsBrowser() {
|
|
||||||
return c.invalidated, nil
|
|
||||||
}
|
|
||||||
return c.offscreen.mipmap.original().IsInvalidated()
|
return c.offscreen.mipmap.original().IsInvalidated()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,6 @@ var (
|
|||||||
|
|
||||||
type contextImpl struct {
|
type contextImpl struct {
|
||||||
gl js.Value
|
gl js.Value
|
||||||
loseContext js.Value
|
|
||||||
lastProgramID programID
|
lastProgramID programID
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,10 +115,6 @@ func (c *context) ensureGL() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.gl = gl
|
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 {
|
func (c *context) reset() error {
|
||||||
@ -130,7 +125,11 @@ func (c *context) reset() error {
|
|||||||
c.lastViewportHeight = 0
|
c.lastViewportHeight = 0
|
||||||
c.lastCompositeMode = graphics.CompositeModeUnknown
|
c.lastCompositeMode = graphics.CompositeModeUnknown
|
||||||
|
|
||||||
|
c.gl = js.Value{}
|
||||||
c.ensureGL()
|
c.ensureGL()
|
||||||
|
if c.gl.Call("isContextLost").Bool() {
|
||||||
|
return fmt.Errorf("opengl: the context is lost")
|
||||||
|
}
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("enable", blend)
|
gl.Call("enable", blend)
|
||||||
c.blendFunc(graphics.CompositeModeSourceOver)
|
c.blendFunc(graphics.CompositeModeSourceOver)
|
||||||
@ -469,15 +468,3 @@ func (c *context) flush() {
|
|||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("flush")
|
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/gopherjs/gopherwasm/js"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/devicescale"
|
"github.com/hajimehoshi/ebiten/internal/devicescale"
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphicsdriver/opengl"
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/hooks"
|
"github.com/hajimehoshi/ebiten/internal/hooks"
|
||||||
"github.com/hajimehoshi/ebiten/internal/input"
|
"github.com/hajimehoshi/ebiten/internal/input"
|
||||||
)
|
)
|
||||||
@ -43,6 +42,7 @@ type userInterface struct {
|
|||||||
sizeChanged bool
|
sizeChanged bool
|
||||||
windowFocus bool
|
windowFocus bool
|
||||||
pageVisible bool
|
pageVisible bool
|
||||||
|
contextLost bool
|
||||||
|
|
||||||
lastActualScale float64
|
lastActualScale float64
|
||||||
}
|
}
|
||||||
@ -216,15 +216,6 @@ func (u *userInterface) update(g GraphicsContext) error {
|
|||||||
}
|
}
|
||||||
hooks.ResumeAudio()
|
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()
|
input.Get().UpdateGamepads()
|
||||||
u.updateGraphicsContext(g)
|
u.updateGraphicsContext(g)
|
||||||
if err := g.Update(func() {
|
if err := g.Update(func() {
|
||||||
@ -241,6 +232,11 @@ func (u *userInterface) loop(g GraphicsContext) <-chan error {
|
|||||||
ch := make(chan error)
|
ch := make(chan error)
|
||||||
var cf js.Callback
|
var cf js.Callback
|
||||||
f := func([]js.Value) {
|
f := func([]js.Value) {
|
||||||
|
if u.contextLost {
|
||||||
|
requestAnimationFrame.Invoke(cf)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if err := u.update(g); err != nil {
|
if err := u.update(g); err != nil {
|
||||||
ch <- err
|
ch <- err
|
||||||
close(ch)
|
close(ch)
|
||||||
@ -359,11 +355,12 @@ func init() {
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// Context
|
||||||
canvas.Call("addEventListener", "webglcontextlost", js.NewEventCallback(js.PreventDefault, func(js.Value) {
|
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) {
|
canvas.Call("addEventListener", "webglcontextrestored", js.NewCallback(func(e []js.Value) {
|
||||||
// Do nothing.
|
currentUI.contextLost = false
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user