internal/buffered: refactoring

This commit is contained in:
Hajime Hoshi 2022-06-25 01:42:40 +09:00
parent bf27f25e26
commit 0eb2f76422
2 changed files with 17 additions and 26 deletions

View File

@ -23,24 +23,20 @@ var (
// delayedCommands represents a queue for image operations that are ordered before the game starts // delayedCommands represents a queue for image operations that are ordered before the game starts
// (BeginFrame). Before the game starts, the package shareable doesn't determine the minimum/maximum texture // (BeginFrame). Before the game starts, the package shareable doesn't determine the minimum/maximum texture
// sizes (#879). // sizes (#879).
delayedCommands = []func() error{} delayedCommands = []func(){}
delayedCommandsM sync.Mutex delayedCommandsM sync.Mutex
delayedCommandsFlushed uint32 delayedCommandsFlushed uint32
) )
func flushDelayedCommands() error { func flushDelayedCommands() {
fs := getDelayedFuncsAndClear() fs := getDelayedFuncsAndClear()
for _, f := range fs { for _, f := range fs {
if err := f(); err != nil { f()
return err
}
} }
return nil
} }
func getDelayedFuncsAndClear() []func() error { func getDelayedFuncsAndClear() []func() {
if atomic.LoadUint32(&delayedCommandsFlushed) == 0 { if atomic.LoadUint32(&delayedCommandsFlushed) == 0 {
// Outline the slow-path to expect the fast-path is inlined. // Outline the slow-path to expect the fast-path is inlined.
return getDelayedFuncsAndClearSlow() return getDelayedFuncsAndClearSlow()
@ -48,14 +44,14 @@ func getDelayedFuncsAndClear() []func() error {
return nil return nil
} }
func getDelayedFuncsAndClearSlow() []func() error { func getDelayedFuncsAndClearSlow() []func() {
delayedCommandsM.Lock() delayedCommandsM.Lock()
defer delayedCommandsM.Unlock() defer delayedCommandsM.Unlock()
if delayedCommandsFlushed == 0 { if delayedCommandsFlushed == 0 {
defer atomic.StoreUint32(&delayedCommandsFlushed, 1) defer atomic.StoreUint32(&delayedCommandsFlushed, 1)
fs := make([]func() error, len(delayedCommands)) fs := make([]func(), len(delayedCommands))
copy(fs, delayedCommands) copy(fs, delayedCommands)
delayedCommands = nil delayedCommands = nil
return fs return fs
@ -71,13 +67,13 @@ func maybeCanAddDelayedCommand() bool {
return atomic.LoadUint32(&delayedCommandsFlushed) == 0 return atomic.LoadUint32(&delayedCommandsFlushed) == 0
} }
func tryAddDelayedCommand(f func() error) bool { func tryAddDelayedCommand(f func()) bool {
delayedCommandsM.Lock() delayedCommandsM.Lock()
defer delayedCommandsM.Unlock() defer delayedCommandsM.Unlock()
if delayedCommandsFlushed == 0 { if delayedCommandsFlushed == 0 {
delayedCommands = append(delayedCommands, func() error { delayedCommands = append(delayedCommands, func() {
return f() f()
}) })
return true return true
} }

View File

@ -38,7 +38,8 @@ func BeginFrame(graphicsDriver graphicsdriver.Graphics) error {
if err := atlas.BeginFrame(graphicsDriver); err != nil { if err := atlas.BeginFrame(graphicsDriver); err != nil {
return err return err
} }
return flushDelayedCommands() flushDelayedCommands()
return nil
} }
func EndFrame(graphicsDriver graphicsdriver.Graphics) error { func EndFrame(graphicsDriver graphicsdriver.Graphics) error {
@ -56,9 +57,8 @@ func NewImage(width, height int, imageType atlas.ImageType) *Image {
func (i *Image) initialize(imageType atlas.ImageType) { func (i *Image) initialize(imageType atlas.ImageType) {
if maybeCanAddDelayedCommand() { if maybeCanAddDelayedCommand() {
if tryAddDelayedCommand(func() error { if tryAddDelayedCommand(func() {
i.initialize(imageType) i.initialize(imageType)
return nil
}) { }) {
return return
} }
@ -87,9 +87,8 @@ func (i *Image) resolvePendingPixels(keepPendingPixels bool) {
func (i *Image) MarkDisposed() { func (i *Image) MarkDisposed() {
if maybeCanAddDelayedCommand() { if maybeCanAddDelayedCommand() {
if tryAddDelayedCommand(func() error { if tryAddDelayedCommand(func() {
i.MarkDisposed() i.MarkDisposed()
return nil
}) { }) {
return return
} }
@ -137,9 +136,8 @@ func (i *Image) ReplacePixels(pix []byte, x, y, width, height int) {
if maybeCanAddDelayedCommand() { if maybeCanAddDelayedCommand() {
copied := make([]byte, len(pix)) copied := make([]byte, len(pix))
copy(copied, pix) copy(copied, pix)
if tryAddDelayedCommand(func() error { if tryAddDelayedCommand(func() {
i.ReplacePixels(copied, x, y, width, height) i.ReplacePixels(copied, x, y, width, height)
return nil
}) { }) {
return return
} }
@ -192,10 +190,9 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
} }
if maybeCanAddDelayedCommand() { if maybeCanAddDelayedCommand() {
if tryAddDelayedCommand(func() error { if tryAddDelayedCommand(func() {
// Arguments are not copied. Copying is the caller's responsibility. // Arguments are not copied. Copying is the caller's responsibility.
i.DrawTriangles(srcs, vertices, indices, colorm, mode, filter, address, dstRegion, srcRegion, subimageOffsets, shader, uniforms, evenOdd) i.DrawTriangles(srcs, vertices, indices, colorm, mode, filter, address, dstRegion, srcRegion, subimageOffsets, shader, uniforms, evenOdd)
return nil
}) { }) {
return return
} }
@ -236,9 +233,8 @@ func NewShader(ir *shaderir.Program) *Shader {
func (s *Shader) initialize(ir *shaderir.Program) { func (s *Shader) initialize(ir *shaderir.Program) {
if maybeCanAddDelayedCommand() { if maybeCanAddDelayedCommand() {
if tryAddDelayedCommand(func() error { if tryAddDelayedCommand(func() {
s.initialize(ir) s.initialize(ir)
return nil
}) { }) {
return return
} }
@ -248,9 +244,8 @@ func (s *Shader) initialize(ir *shaderir.Program) {
func (s *Shader) MarkDisposed() { func (s *Shader) MarkDisposed() {
if maybeCanAddDelayedCommand() { if maybeCanAddDelayedCommand() {
if tryAddDelayedCommand(func() error { if tryAddDelayedCommand(func() {
s.MarkDisposed() s.MarkDisposed()
return nil
}) { }) {
return return
} }