Revert "Revert "shareable: Avoid unneeded extending images""

This reverts commit 96b9f09058.

Fixes #561
This commit is contained in:
Hajime Hoshi 2018-03-20 02:15:49 +09:00
parent 3e929de08a
commit aaa603dd08
2 changed files with 61 additions and 15 deletions

View File

@ -48,8 +48,8 @@ type Node struct {
y int
width int
height int
used bool
parent *Node
child0 *Node
child1 *Node
@ -268,3 +268,33 @@ func (p *Page) Extend() bool {
p.size = newSize
return true
}
func (n *Node) clone() *Node {
if n == nil {
return nil
}
cloned := &Node{
x: n.x,
y: n.y,
width: n.width,
height: n.height,
used: n.used,
child0: n.child0.clone(),
child1: n.child1.clone(),
}
if cloned.child0 != nil {
cloned.child0.parent = cloned
}
if cloned.child1 != nil {
cloned.child1.parent = cloned
}
return cloned
}
func (p *Page) Clone() *Page {
return &Page{
root: p.root.clone(),
size: p.size,
maxSize: p.maxSize,
}
}

View File

@ -35,24 +35,40 @@ type backend struct {
}
func (b *backend) TryAlloc(width, height int) (*packing.Node, bool) {
for {
if n := b.page.Alloc(width, height); n != nil {
return n, true
}
// If the region is allocated without any extention, it's fine.
if n := b.page.Alloc(width, height); n != nil {
return n, true
}
if !b.page.Extend() {
// Simulate the extending the page and calculate the appropriate page size.
page := b.page.Clone()
nExtended := 0
for {
if !page.Extend() {
// The page can't be extended any more. Return as failure.
return nil, false
}
nExtended++
if n := page.Alloc(width, height); n != nil {
break
}
s := b.page.Size()
newImg := restorable.NewImage(s, s, false)
w, h := b.restorable.Size()
newImg.DrawImage(b.restorable, 0, 0, w, h, nil, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
b.restorable.Dispose()
b.restorable = newImg
}
return nil, false
for i := 0; i < nExtended; i++ {
b.page.Extend()
}
s := b.page.Size()
newImg := restorable.NewImage(s, s, false)
w, h := b.restorable.Size()
newImg.DrawImage(b.restorable, 0, 0, w, h, nil, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
b.restorable.Dispose()
b.restorable = newImg
n := b.page.Alloc(width, height)
if n == nil {
panic("not reached")
}
return n, true
}
var (