mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-14 15:07:26 +01:00
ebiten: improve bulitinShader by reducing locks
old.txt: 04c9a802a7
new.txt: this commit
```
% benchstat old.txt new.txt
goos: darwin
goarch: arm64
pkg: github.com/hajimehoshi/ebiten/v2
cpu: Apple M3 Pro
│ old.txt │ new.txt │
│ sec/op │ sec/op vs base │
BuiltinShader-12 4.226n ± 2% 1.352n ± 2% -68.00% (p=0.000 n=10)
```
This commit is contained in:
parent
04c9a802a7
commit
2437ad8248
27
shader.go
27
shader.go
@ -17,6 +17,7 @@ package ebiten
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/builtinshader"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||
@ -86,21 +87,30 @@ func (s *Shader) appendUniforms(dst []uint32, uniforms map[string]any) []uint32
|
||||
}
|
||||
|
||||
var (
|
||||
builtinShaders [builtinshader.FilterCount][builtinshader.AddressCount][2]*Shader
|
||||
builtinShadersForRead atomic.Pointer[[builtinshader.FilterCount][builtinshader.AddressCount][2]*Shader]
|
||||
builtinShadersM sync.Mutex
|
||||
)
|
||||
|
||||
func builtinShader(filter builtinshader.Filter, address builtinshader.Address, useColorM bool) *Shader {
|
||||
builtinShadersM.Lock()
|
||||
defer builtinShadersM.Unlock()
|
||||
|
||||
var c int
|
||||
if useColorM {
|
||||
c = 1
|
||||
}
|
||||
if s := builtinShaders[filter][address][c]; s != nil {
|
||||
if read := builtinShadersForRead.Load(); read != nil {
|
||||
if s := (*read)[filter][address][c]; s != nil {
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
builtinShadersM.Lock()
|
||||
defer builtinShadersM.Unlock()
|
||||
|
||||
// Double check in case another goroutine already created a shader.
|
||||
if read := builtinShadersForRead.Load(); read != nil {
|
||||
if s := (*read)[filter][address][c]; s != nil {
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
var shader *Shader
|
||||
if address == builtinshader.AddressUnsafe && !useColorM {
|
||||
@ -135,6 +145,11 @@ func builtinShader(filter builtinshader.Filter, address builtinshader.Address, u
|
||||
shader = s
|
||||
}
|
||||
|
||||
builtinShaders[filter][address][c] = shader
|
||||
var shaders [builtinshader.FilterCount][builtinshader.AddressCount][2]*Shader
|
||||
if ptr := builtinShadersForRead.Load(); ptr != nil {
|
||||
shaders = *ptr
|
||||
}
|
||||
shaders[filter][address][c] = shader
|
||||
builtinShadersForRead.Store(&shaders)
|
||||
return shader
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user