restorable: Disable restoring on desktops and mobile browsers (#380)

This commit is contained in:
Hajime Hoshi 2017-07-02 15:58:00 +09:00
parent e582a661c9
commit 364819f361
6 changed files with 110 additions and 11 deletions

View File

@ -81,14 +81,7 @@ func (c *graphicsContext) initializeIfNeeded() error {
}
c.initialized = true
}
r, err := c.needsRestoring()
if err != nil {
return err
}
if !r {
return nil
}
if err := c.restore(); err != nil {
if err := c.restoreIfNeeded(); err != nil {
return err
}
return nil
@ -137,7 +130,17 @@ func (c *graphicsContext) UpdateAndDraw(updateCount int) error {
return nil
}
func (c *graphicsContext) restore() error {
func (c *graphicsContext) restoreIfNeeded() error {
if !restorable.IsRestoringEnabled() {
return nil
}
r, err := c.needsRestoring()
if err != nil {
return err
}
if !r {
return nil
}
if err := graphics.Reset(); err != nil {
return err
}

View File

@ -0,0 +1,26 @@
// Copyright 2017 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 darwin freebsd linux windows
// +build !js
// +build !android
// +build !ios
package restorable
func init() {
// OpenGL (not ES) never causes context lost,
// so restorable feature is not needed.
restoringEnabled = false
}

View File

@ -0,0 +1,48 @@
// Copyright 2017 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 restorable
import (
"strings"
"github.com/gopherjs/gopherjs/js"
)
func isIOS() bool {
ua := js.Global.Get("navigator").Get("userAgent").String()
if !strings.Contains(ua, "iPhone") {
return false
}
return true
}
func isAndroidChrome() bool {
ua := js.Global.Get("navigator").Get("userAgent").String()
if !strings.Contains(ua, "Android") {
return false
}
if !strings.Contains(ua, "Chrome") {
return false
}
return true
}
func init() {
if isIOS() || isAndroidChrome() {
restoringEnabled = false
}
}

View File

@ -157,8 +157,7 @@ func (p *Image) ReplacePixels(pixels []uint8) {
func (p *Image) DrawImage(img *Image, vertices []float32, colorm *affine.ColorM, mode opengl.CompositeMode) {
theImages.resetPixelsIfDependingOn(p)
if img.stale || img.volatile {
// TODO: What will happen if there are images depending on p?
if img.stale || img.volatile || !IsRestoringEnabled() {
p.makeStale()
} else {
p.appendDrawImageHistory(img, vertices, colorm, mode)
@ -234,6 +233,9 @@ func (p *Image) readPixelsFromGPU(image *graphics.Image) error {
}
func (p *Image) resolveStalePixels() error {
if !IsRestoringEnabled() {
return nil
}
if p.volatile {
return nil
}
@ -339,5 +341,8 @@ func (p *Image) Dispose() {
}
func (p *Image) IsInvalidated() bool {
if !IsRestoringEnabled() {
return false
}
return p.image.IsInvalidated()
}

View File

@ -18,6 +18,19 @@ import (
"github.com/hajimehoshi/ebiten/internal/sync"
)
// restoringEnabled indicates if restoring happens or not.
var restoringEnabled = true // This value is overridden at enabled_*.go.
func IsRestoringEnabled() bool {
// This value is updated only at init or EnableRestoringForTesting.
// No need to lock here.
return restoringEnabled
}
func EnableRestoringForTesting() {
restoringEnabled = true
}
type images struct {
images map[*Image]struct{}
lastChecked *Image
@ -88,6 +101,9 @@ func (i *images) resetPixelsIfDependingOn(target *Image) {
func (i *images) restore() error {
i.m.Lock()
defer i.m.Unlock()
if !IsRestoringEnabled() {
panic("not reached")
}
// Framebuffers/textures cannot be disposed since framebuffers/textures that
// don't belong to the current context.

View File

@ -28,6 +28,7 @@ import (
)
func TestMain(m *testing.M) {
EnableRestoringForTesting()
code := 0
regularTermination := errors.New("regular termination")
f := func(screen *ebiten.Image) error {