buffered: Refactoring: Flush delayed functions without the lock

This commit is contained in:
Hajime Hoshi 2020-02-16 19:24:26 +09:00
parent ff8689cfcd
commit 405ae99b32
2 changed files with 30 additions and 29 deletions

View File

@ -29,19 +29,23 @@ var (
) )
func flushDelayedCommands() error { func flushDelayedCommands() error {
delayedCommandsM.Lock() fs := getDelayedFuncsAndClear()
defer delayedCommandsM.Unlock() for _, f := range fs {
if err := f(); err != nil {
if !needsToDelayCommands {
return nil
}
for _, c := range delayedCommands {
if err := c(); err != nil {
return err return err
} }
} }
delayedCommands = delayedCommands[:0]
needsToDelayCommands = false
return nil return nil
}
func getDelayedFuncsAndClear() []func() error {
delayedCommandsM.Lock()
defer delayedCommandsM.Unlock()
fs := make([]func() error, len(delayedCommands))
copy(fs, delayedCommands)
delayedCommands = nil
needsToDelayCommands = false
return fs
} }

View File

@ -45,47 +45,47 @@ func EndFrame() error {
func NewImage(width, height int, volatile bool) *Image { func NewImage(width, height int, volatile bool) *Image {
i := &Image{} i := &Image{}
i.initialize(width, height, volatile)
return i
}
func (i *Image) initialize(width, height int, volatile bool) {
delayedCommandsM.Lock() delayedCommandsM.Lock()
defer delayedCommandsM.Unlock() defer delayedCommandsM.Unlock()
if needsToDelayCommands { if needsToDelayCommands {
delayedCommands = append(delayedCommands, func() error { delayedCommands = append(delayedCommands, func() error {
i.img = mipmap.New(width, height, volatile) i.initialize(width, height, volatile)
i.width = width
i.height = height
return nil return nil
}) })
return i return
} }
i.img = mipmap.New(width, height, volatile) i.img = mipmap.New(width, height, volatile)
i.width = width i.width = width
i.height = height i.height = height
return i
} }
func NewScreenFramebufferImage(width, height int) *Image { func NewScreenFramebufferImage(width, height int) *Image {
i := &Image{} i := &Image{}
i.initializeAsScreenFramebuffer(width, height)
return i
}
func (i *Image) initializeAsScreenFramebuffer(width, height int) {
delayedCommandsM.Lock() delayedCommandsM.Lock()
defer delayedCommandsM.Unlock() defer delayedCommandsM.Unlock()
if needsToDelayCommands { if needsToDelayCommands {
delayedCommands = append(delayedCommands, func() error { delayedCommands = append(delayedCommands, func() error {
i.img = mipmap.NewScreenFramebufferMipmap(width, height) i.initializeAsScreenFramebuffer(width, height)
i.width = width
i.height = height
return nil return nil
}) })
return
return i
} }
i.img = mipmap.NewScreenFramebufferMipmap(width, height) i.img = mipmap.NewScreenFramebufferMipmap(width, height)
i.width = width i.width = width
i.height = height i.height = height
return i
} }
func (i *Image) invalidatePendingPixels() { func (i *Image) invalidatePendingPixels() {
@ -111,8 +111,7 @@ func (i *Image) MarkDisposed() {
if needsToDelayCommands { if needsToDelayCommands {
delayedCommands = append(delayedCommands, func() error { delayedCommands = append(delayedCommands, func() error {
i.invalidatePendingPixels() i.MarkDisposed()
i.img.MarkDisposed()
return nil return nil
}) })
return return
@ -188,8 +187,7 @@ func (i *Image) Fill(clr color.RGBA) {
if needsToDelayCommands { if needsToDelayCommands {
delayedCommands = append(delayedCommands, func() error { delayedCommands = append(delayedCommands, func() error {
i.invalidatePendingPixels() i.Fill(clr)
i.img.Fill(clr)
return nil return nil
}) })
return return
@ -205,10 +203,9 @@ func (i *Image) ReplacePixels(pix []byte) {
if needsToDelayCommands { if needsToDelayCommands {
delayedCommands = append(delayedCommands, func() error { delayedCommands = append(delayedCommands, func() error {
i.invalidatePendingPixels()
copied := make([]byte, len(pix)) copied := make([]byte, len(pix))
copy(copied, pix) copy(copied, pix)
i.img.ReplacePixels(copied) i.ReplacePixels(copied)
return nil return nil
}) })
return return