internal/atlas: bug fix: use the global lock for shaders

Closes #2129
This commit is contained in:
Hajime Hoshi 2022-06-08 10:00:26 +09:00
parent 83ac234142
commit 3b6a080519
2 changed files with 76 additions and 0 deletions

View File

@ -26,6 +26,9 @@ type Shader struct {
}
func NewShader(ir *shaderir.Program) *Shader {
backendsM.Lock()
defer backendsM.Unlock()
s := &Shader{
shader: restorable.NewShader(ir),
}
@ -39,6 +42,9 @@ func NewShader(ir *shaderir.Program) *Shader {
// A function from finalizer must not be blocked, but disposing operation can be blocked.
// Defer this operation until it becomes safe. (#913)
func (s *Shader) MarkDisposed() {
backendsM.Lock()
defer backendsM.Unlock()
deferredM.Lock()
deferred = append(deferred, func() {
s.dispose()

View File

@ -0,0 +1,70 @@
// Copyright 2022 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.
//go:build ignore
// +build ignore
package main
import (
"errors"
"github.com/hajimehoshi/ebiten/v2"
)
var regularTermination = errors.New("regular termination")
type Game struct {
count int
}
func (g *Game) Update() error {
const shaderData = `
package main
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
return vec4(1)
}
`
g.count++
if g.count == 16 {
return regularTermination
}
if g.count < 8 {
go func() {
s, err := ebiten.NewShader([]byte(shaderData))
if err != nil {
panic(err)
}
s.Dispose()
}()
return nil
}
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
}
func (g *Game) Layout(width, height int) (int, int) {
return width, height
}
func main() {
if err := ebiten.RunGame(&Game{}); err != nil && err != regularTermination {
panic(err)
}
}