mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-13 20:42:07 +01:00
Revert "packing: Add Extend"
This reverts commit 1dd32066d2
.
Reason: #542
This commit is contained in:
parent
e977019d2f
commit
9c72671232
@ -16,20 +16,16 @@
|
|||||||
package packing
|
package packing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/sync"
|
"github.com/hajimehoshi/ebiten/internal/sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
initSize = 1024
|
MaxSize = 2048
|
||||||
MaxSize = 4096
|
minSize = 1
|
||||||
minSize = 1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
root *Node
|
root *Node
|
||||||
size int
|
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,30 +138,15 @@ func (p *Page) alloc(n *Node, width, height int) *Node {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Page) ensureSize() {
|
|
||||||
if p.size == 0 {
|
|
||||||
p.size = initSize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Page) Size() int {
|
|
||||||
p.m.Lock()
|
|
||||||
p.ensureSize()
|
|
||||||
s := p.size
|
|
||||||
p.m.Unlock()
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Page) Alloc(width, height int) *Node {
|
func (p *Page) Alloc(width, height int) *Node {
|
||||||
p.m.Lock()
|
p.m.Lock()
|
||||||
if width <= 0 || height <= 0 {
|
if width <= 0 || height <= 0 {
|
||||||
panic("bsp: width and height must > 0")
|
panic("bsp: width and height must > 0")
|
||||||
}
|
}
|
||||||
p.ensureSize()
|
|
||||||
if p.root == nil {
|
if p.root == nil {
|
||||||
p.root = &Node{
|
p.root = &Node{
|
||||||
width: p.size,
|
width: MaxSize,
|
||||||
height: p.size,
|
height: MaxSize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if width < minSize {
|
if width < minSize {
|
||||||
@ -202,93 +183,3 @@ func (p *Page) free(node *Node) {
|
|||||||
p.free(node.parent)
|
p.free(node.parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func walk(n *Node, f func(n *Node) error) error {
|
|
||||||
if err := f(n); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if n.child0 != nil {
|
|
||||||
if err := walk(n.child0, f); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if n.child1 != nil {
|
|
||||||
if err := walk(n.child1, f); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Page) Extend() bool {
|
|
||||||
p.m.Lock()
|
|
||||||
defer p.m.Unlock()
|
|
||||||
|
|
||||||
p.ensureSize()
|
|
||||||
if p.size >= MaxSize {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
newSize := p.size * 2
|
|
||||||
edgeNodes := []*Node{}
|
|
||||||
abort := errors.New("abort")
|
|
||||||
canExtendNodes := true
|
|
||||||
_ = walk(p.root, func(n *Node) error {
|
|
||||||
if n.x+n.width < p.size && n.y+n.height < p.size {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if n.used {
|
|
||||||
canExtendNodes = false
|
|
||||||
return abort
|
|
||||||
}
|
|
||||||
edgeNodes = append(edgeNodes, n)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if canExtendNodes {
|
|
||||||
for _, n := range edgeNodes {
|
|
||||||
if n.x+n.width == p.size {
|
|
||||||
n.width += newSize - p.size
|
|
||||||
}
|
|
||||||
if n.y+n.height == p.size {
|
|
||||||
n.height += newSize - p.size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
leftUpper := p.root
|
|
||||||
leftLower := &Node{
|
|
||||||
x: 0,
|
|
||||||
y: p.size,
|
|
||||||
width: p.size,
|
|
||||||
height: newSize - p.size,
|
|
||||||
}
|
|
||||||
left := &Node{
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
width: p.size,
|
|
||||||
height: p.size,
|
|
||||||
child0: leftUpper,
|
|
||||||
child1: leftLower,
|
|
||||||
}
|
|
||||||
leftUpper.parent = left
|
|
||||||
leftLower.parent = left
|
|
||||||
|
|
||||||
right := &Node{
|
|
||||||
x: p.size,
|
|
||||||
y: 0,
|
|
||||||
width: newSize - p.size,
|
|
||||||
height: newSize,
|
|
||||||
}
|
|
||||||
p.root = &Node{
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
width: newSize,
|
|
||||||
height: newSize,
|
|
||||||
child0: left,
|
|
||||||
child1: right,
|
|
||||||
}
|
|
||||||
left.parent = p.root
|
|
||||||
right.parent = p.root
|
|
||||||
}
|
|
||||||
|
|
||||||
p.size = newSize
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
@ -52,7 +52,7 @@ func TestPage(t *testing.T) {
|
|||||||
{0, 0, 0},
|
{0, 0, 0},
|
||||||
{0, 0, 2},
|
{0, 0, 2},
|
||||||
{0, 0, 4},
|
{0, 0, 4},
|
||||||
{1024, 1024, -1},
|
{MaxSize, MaxSize, -1},
|
||||||
},
|
},
|
||||||
Out: []*Rect{
|
Out: []*Rect{
|
||||||
{0, 0, 100, 100},
|
{0, 0, 100, 100},
|
||||||
@ -67,108 +67,108 @@ func TestPage(t *testing.T) {
|
|||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
{0, 0, 1024, 1024},
|
{0, 0, MaxSize, MaxSize},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
In: []Op{
|
In: []Op{
|
||||||
{100, 200, -1},
|
{200, 400, -1},
|
||||||
{1024, 1024, -1},
|
{MaxSize, MaxSize, -1},
|
||||||
{100, 200, -1},
|
{200, 400, -1},
|
||||||
{50, 50, -1},
|
|
||||||
{200, 200, -1},
|
|
||||||
{1024, 1024, -1},
|
|
||||||
{500, 500, -1},
|
|
||||||
{600, 600, -1},
|
|
||||||
{100, 100, -1},
|
{100, 100, -1},
|
||||||
|
{400, 400, -1},
|
||||||
|
{MaxSize, MaxSize, -1},
|
||||||
|
{1000, 1000, -1},
|
||||||
|
{1200, 1200, -1},
|
||||||
|
{200, 200, -1},
|
||||||
{0, 0, 2},
|
{0, 0, 2},
|
||||||
{100, 200, -1},
|
{200, 400, -1},
|
||||||
},
|
},
|
||||||
Out: []*Rect{
|
Out: []*Rect{
|
||||||
{0, 0, 100, 200},
|
{0, 0, 200, 400},
|
||||||
nil,
|
nil,
|
||||||
{0, 200, 100, 200},
|
{0, 400, 200, 400},
|
||||||
{0, 400, 50, 50},
|
{0, 800, 100, 100},
|
||||||
{100, 0, 200, 200},
|
{200, 0, 400, 400},
|
||||||
nil,
|
nil,
|
||||||
{100, 200, 500, 500},
|
{200, 400, 1000, 1000},
|
||||||
nil,
|
nil,
|
||||||
{0, 450, 100, 100},
|
{0, 900, 200, 200},
|
||||||
nil,
|
nil,
|
||||||
{0, 200, 100, 200},
|
{0, 400, 200, 400},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
In: []Op{
|
In: []Op{
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
|
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
|
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
|
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
|
|
||||||
{256, 256, -1},
|
{512, 512, -1},
|
||||||
},
|
},
|
||||||
Out: []*Rect{
|
Out: []*Rect{
|
||||||
{0, 0, 256, 256},
|
{0, 0, 512, 512},
|
||||||
{0, 256, 256, 256},
|
{0, 512, 512, 512},
|
||||||
{0, 512, 256, 256},
|
{0, 1024, 512, 512},
|
||||||
{0, 768, 256, 256},
|
{0, 1536, 512, 512},
|
||||||
|
|
||||||
{256, 0, 256, 256},
|
{512, 0, 512, 512},
|
||||||
{512, 0, 256, 256},
|
{1024, 0, 512, 512},
|
||||||
{768, 0, 256, 256},
|
{1536, 0, 512, 512},
|
||||||
{256, 256, 256, 256},
|
{512, 512, 512, 512},
|
||||||
|
|
||||||
{256, 512, 256, 256},
|
{512, 1024, 512, 512},
|
||||||
{256, 768, 256, 256},
|
{512, 1536, 512, 512},
|
||||||
{512, 256, 256, 256},
|
{1024, 512, 512, 512},
|
||||||
{768, 256, 256, 256},
|
{1536, 512, 512, 512},
|
||||||
|
|
||||||
{512, 512, 256, 256},
|
{1024, 1024, 512, 512},
|
||||||
{512, 768, 256, 256},
|
{1024, 1536, 512, 512},
|
||||||
{768, 512, 256, 256},
|
{1536, 1024, 512, 512},
|
||||||
{768, 768, 256, 256},
|
{1536, 1536, 512, 512},
|
||||||
|
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
In: []Op{
|
In: []Op{
|
||||||
{300, 300, -1},
|
{600, 600, -1},
|
||||||
{300, 300, -1},
|
{600, 600, -1},
|
||||||
{300, 300, -1},
|
{600, 600, -1},
|
||||||
{300, 300, -1},
|
{600, 600, -1},
|
||||||
{300, 300, -1},
|
{600, 600, -1},
|
||||||
{300, 300, -1},
|
{600, 600, -1},
|
||||||
{300, 300, -1},
|
{600, 600, -1},
|
||||||
{300, 300, -1},
|
{600, 600, -1},
|
||||||
{300, 300, -1},
|
{600, 600, -1},
|
||||||
{300, 300, -1},
|
{600, 600, -1},
|
||||||
},
|
},
|
||||||
Out: []*Rect{
|
Out: []*Rect{
|
||||||
{0, 0, 300, 300},
|
{0, 0, 600, 600},
|
||||||
{0, 300, 300, 300},
|
{0, 600, 600, 600},
|
||||||
{0, 600, 300, 300},
|
{0, 1200, 600, 600},
|
||||||
{300, 0, 300, 300},
|
{600, 0, 600, 600},
|
||||||
{600, 0, 300, 300},
|
{1200, 0, 600, 600},
|
||||||
{300, 300, 300, 300},
|
{600, 600, 600, 600},
|
||||||
{300, 600, 300, 300},
|
{600, 1200, 600, 600},
|
||||||
{600, 300, 300, 300},
|
{1200, 600, 600, 600},
|
||||||
{600, 600, 300, 300},
|
{1200, 1200, 600, 600},
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -206,47 +206,3 @@ func TestPage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtend(t *testing.T) {
|
|
||||||
p := &Page{}
|
|
||||||
s := p.Size()
|
|
||||||
p.Alloc(s/2, s/2)
|
|
||||||
// Now Extend extends the page by exntending the existing edge nodes.
|
|
||||||
p.Extend()
|
|
||||||
if p.Alloc(s*3/2, s*2) == nil {
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
if p.Alloc(s/2, s*3/2) == nil {
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
if p.Alloc(1, 1) != nil {
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExtendAddingNewNodes(t *testing.T) {
|
|
||||||
p := &Page{}
|
|
||||||
s := p.Size()
|
|
||||||
p.Alloc(s/2, s/2)
|
|
||||||
n1 := p.Alloc(s/2, s/2)
|
|
||||||
n2 := p.Alloc(s/2, s/2)
|
|
||||||
p.Alloc(s/2, s/2)
|
|
||||||
p.Free(n1)
|
|
||||||
p.Free(n2)
|
|
||||||
// There is an allocation at lower left.
|
|
||||||
// In this case, Extend doesn't extend the existing edge nodes, but
|
|
||||||
// instead adds new nodes.
|
|
||||||
p.Extend()
|
|
||||||
if p.Alloc(s*3/2, s*2) != nil {
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
if p.Alloc(s, s*2) == nil {
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
if p.Alloc(s, s) == nil {
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
if p.Alloc(s, s) != nil {
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
39
shared.go
39
shared.go
@ -15,8 +15,6 @@
|
|||||||
package ebiten
|
package ebiten
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/packing"
|
"github.com/hajimehoshi/ebiten/internal/packing"
|
||||||
"github.com/hajimehoshi/ebiten/internal/restorable"
|
"github.com/hajimehoshi/ebiten/internal/restorable"
|
||||||
"github.com/hajimehoshi/ebiten/internal/sync"
|
"github.com/hajimehoshi/ebiten/internal/sync"
|
||||||
@ -73,41 +71,22 @@ func newSharedImagePart(width, height int) *sharedImagePart {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for _, s := range theSharedImages {
|
for _, s := range theSharedImages {
|
||||||
for {
|
if n := s.page.Alloc(width, height); n != nil {
|
||||||
if n := s.page.Alloc(width, height); n != nil {
|
return &sharedImagePart{
|
||||||
return &sharedImagePart{
|
sharedImage: s,
|
||||||
sharedImage: s,
|
node: n,
|
||||||
node: n,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !s.page.Extend() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
newSharedImage := restorable.NewImage(s.page.Size(), s.page.Size(), false)
|
|
||||||
newSharedImage.DrawImage(s.restorable, 0, 0, s.page.Size(), s.page.Size(), nil, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
|
||||||
s.restorable.Dispose()
|
|
||||||
|
|
||||||
s.restorable = newSharedImage
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s := &sharedImage{
|
||||||
s := &sharedImage{}
|
restorable: restorable.NewImage(packing.MaxSize, packing.MaxSize, false),
|
||||||
var n *packing.Node
|
|
||||||
for {
|
|
||||||
n = s.page.Alloc(width, height)
|
|
||||||
if n != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if !s.page.Extend() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
theSharedImages = append(theSharedImages, s)
|
||||||
|
|
||||||
|
n := s.page.Alloc(width, height)
|
||||||
if n == nil {
|
if n == nil {
|
||||||
panic("not reached")
|
panic("not reached")
|
||||||
}
|
}
|
||||||
s.restorable = restorable.NewImage(s.page.Size(), s.page.Size(), false)
|
|
||||||
theSharedImages = append(theSharedImages, s)
|
|
||||||
|
|
||||||
return &sharedImagePart{
|
return &sharedImagePart{
|
||||||
sharedImage: s,
|
sharedImage: s,
|
||||||
node: n,
|
node: n,
|
||||||
|
Loading…
Reference in New Issue
Block a user