diff --git a/ReflectiveBoundTexture.go b/ReflectiveBoundTexture.go index a4750f3a..1c72841b 100644 --- a/ReflectiveBoundTexture.go +++ b/ReflectiveBoundTexture.go @@ -7,6 +7,7 @@ import ( "image/color" "sync" + "github.com/AllenDang/cimgui-go/backend" "github.com/AllenDang/cimgui-go/imgui" ) @@ -193,10 +194,16 @@ func (i *ReflectiveBoundTexture) unbind() { } // bind creates a new texture from the RGBA surface and assigns it to the ReflectiveBoundTexture. +// note it bypasses normal texture management up to cimgui-go to avoid double free from finalizers. func (i *ReflectiveBoundTexture) bind() { - NewTextureFromRgba(i.Surface, func(tex *Texture) { - i.tex = tex - }) + img := ImageToRgba(i.Surface) + i.tex = &Texture{ + &backend.Texture{ + ID: backend.TextureManager(Context.backend).CreateTextureRgba(img, img.Bounds().Dx(), img.Bounds().Dy()), + Width: img.Bounds().Dx(), + Height: img.Bounds().Dy(), + }, + } } // GetSurfaceWidth returns the width of the RGBA surface. diff --git a/examples/paint/canvas.go b/examples/paint/canvas.go index beb32401..4416a08d 100644 --- a/examples/paint/canvas.go +++ b/examples/paint/canvas.go @@ -4,6 +4,7 @@ import ( "fmt" "image" "image/color" + "sync" "github.com/AllenDang/cimgui-go/imgui" @@ -57,11 +58,13 @@ type Canvas struct { // inited is a boolean flag indicating whether the canvas has been initialized. inited bool + + appendMu sync.Mutex } -// GetDrawCommands returns a slice of drawCommand starting from the specified index. +// getDrawCommands returns a slice of drawCommand starting from the specified index. // It allows retrieval of draw commands that have been added since a given point in time. -func (c *Canvas) GetDrawCommands(sinceIndex int) []DrawCommand { +func (c *Canvas) getDrawCommands(sinceIndex int) []DrawCommand { return c.DrawCommands[sinceIndex:] } @@ -79,6 +82,8 @@ func (c *Canvas) PushImageToBackend(commit bool) error { // AppendDrawCommands adds a slice of drawCommand to the canvas's existing draw commands. // It appends the provided commands to the DrawCommands slice. func (c *Canvas) AppendDrawCommands(cmds *[]DrawCommand) { + c.appendMu.Lock() + defer c.appendMu.Unlock() c.DrawCommands = append(c.DrawCommands, *cmds...) } @@ -104,18 +109,29 @@ func (c *Canvas) Compute() { return } - // Return if there are no draw commands to process - if len(c.DrawCommands) < 1 { - return - } + var draws []DrawCommand + + if func() bool { + c.appendMu.Lock() + defer c.appendMu.Unlock() + + // Return if there are no draw commands to process + if len(c.DrawCommands) < 1 { + return true + } + + // Return if all draw commands have already been processed + if len(c.DrawCommands) <= c.LastComputedLen { + return true + } - // Return if all draw commands have already been processed - if len(c.DrawCommands) <= c.LastComputedLen { + // Get the new draw commands that need to be processed + draws = c.getDrawCommands(c.LastComputedLen) + return false + }() { return } - // Get the new draw commands that need to be processed - draws := c.GetDrawCommands(c.LastComputedLen) for _, r := range draws { switch r.Tool { case 0: