mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
internal/atlas: Reuse byte array for ReplacePixels
This reduces memory allocation at ReplacePixels. Updates #1681
This commit is contained in:
parent
371bbfc0f2
commit
38ce46328a
@ -38,6 +38,53 @@ var (
|
||||
maxSize = 0
|
||||
)
|
||||
|
||||
type temporaryPixels struct {
|
||||
pixels []byte
|
||||
pos int
|
||||
totalUse int
|
||||
unusedTime int
|
||||
}
|
||||
|
||||
var theTemporaryPixels temporaryPixels
|
||||
|
||||
func (t *temporaryPixels) alloc(size int) []byte {
|
||||
if len(t.pixels) < t.pos+size {
|
||||
newL := len(t.pixels)
|
||||
if newL == 0 {
|
||||
newL = 16
|
||||
}
|
||||
for newL < t.pos+size {
|
||||
newL *= 2
|
||||
}
|
||||
t.pixels = make([]byte, newL)
|
||||
t.pos = 0
|
||||
}
|
||||
pix := t.pixels[t.pos : t.pos+size]
|
||||
t.pos += size
|
||||
t.totalUse += size
|
||||
return pix
|
||||
}
|
||||
|
||||
func (t *temporaryPixels) resetAtFrameEnd() {
|
||||
const maxUnusedTime = 60
|
||||
|
||||
if t.totalUse == 0 {
|
||||
if t.unusedTime < maxUnusedTime {
|
||||
t.unusedTime++
|
||||
}
|
||||
} else {
|
||||
t.unusedTime = 0
|
||||
}
|
||||
|
||||
// Let the pixels GCed if this is not used for a while.
|
||||
if t.unusedTime == maxUnusedTime && len(t.pixels) > 0 {
|
||||
t.pixels = nil
|
||||
}
|
||||
|
||||
t.pos = 0
|
||||
t.totalUse = 0
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
@ -487,7 +534,7 @@ func (i *Image) replacePixels(pix []byte) {
|
||||
}
|
||||
|
||||
// Add a padding around the image.
|
||||
pixb := make([]byte, 4*w*h)
|
||||
pixb := theTemporaryPixels.alloc(4 * w * h)
|
||||
for j := 0; j < oh; j++ {
|
||||
copy(pixb[4*((j+paddingSize)*w+paddingSize):], pix[4*j*ow:4*(j+1)*ow])
|
||||
}
|
||||
@ -700,6 +747,8 @@ func NewScreenFramebufferImage(width, height int) *Image {
|
||||
func EndFrame() error {
|
||||
backendsM.Lock()
|
||||
|
||||
theTemporaryPixels.resetAtFrameEnd()
|
||||
|
||||
return restorable.ResolveStaleImages()
|
||||
}
|
||||
|
||||
|
@ -304,7 +304,11 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
||||
|
||||
if x == 0 && y == 0 && width == w && height == h {
|
||||
if pixels != nil {
|
||||
i.basePixels.AddOrReplace(pixels, 0, 0, w, h)
|
||||
// pixels can point to a shared region.
|
||||
// This function is responsible to copy this.
|
||||
copiedPixels := make([]byte, len(pixels))
|
||||
copy(copiedPixels, pixels)
|
||||
i.basePixels.AddOrReplace(copiedPixels, 0, 0, w, h)
|
||||
} else {
|
||||
i.basePixels.Remove(0, 0, w, h)
|
||||
}
|
||||
@ -324,7 +328,11 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
||||
}
|
||||
|
||||
if pixels != nil {
|
||||
i.basePixels.AddOrReplace(pixels, x, y, width, height)
|
||||
// pixels can point to a shared region.
|
||||
// This function is responsible to copy this.
|
||||
copiedPixels := make([]byte, len(pixels))
|
||||
copy(copiedPixels, pixels)
|
||||
i.basePixels.AddOrReplace(copiedPixels, x, y, width, height)
|
||||
} else {
|
||||
i.basePixels.Remove(x, y, width, height)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user