shareable: Implement extending shareable texture again

Related to #509
This commit is contained in:
Hajime Hoshi 2018-03-11 01:30:24 +09:00
parent c37dd9d961
commit b474946619

View File

@ -32,6 +32,20 @@ type backend struct {
page *packing.Page page *packing.Page
} }
func (b *backend) Extend() bool {
if !b.page.Extend() {
return false
}
s := b.page.Size()
newImg := restorable.NewImage(s, s, false)
newImg.DrawImage(b.restorable, 0, 0, s, s, nil, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
b.restorable.Dispose()
b.restorable = newImg
return true
}
var ( var (
// backendsM is a mutex for critical sections of the backend and packing.Node objects. // backendsM is a mutex for critical sections of the backend and packing.Node objects.
backendsM sync.Mutex backendsM sync.Mutex
@ -177,7 +191,10 @@ func (s *Image) IsInvalidated() (bool, error) {
} }
func NewImage(width, height int) *Image { func NewImage(width, height int) *Image {
const maxSize = 2048 const (
initSize = 1024
maxSize = 4096
)
backendsM.Lock() backendsM.Lock()
defer backendsM.Unlock() defer backendsM.Unlock()
@ -191,26 +208,39 @@ func NewImage(width, height int) *Image {
} }
} }
for _, s := range theBackends { for _, b := range theBackends {
if n := s.page.Alloc(width, height); n != nil { for {
return &Image{ if n := b.page.Alloc(width, height); n != nil {
backend: s, return &Image{
node: n, backend: b,
node: n,
}
}
if !b.Extend() {
break
} }
} }
} }
s := &backend{ size := initSize
restorable: restorable.NewImage(maxSize, maxSize, false), for width > size || height > size {
page: packing.NewPage(maxSize, maxSize), // TODO: Utilize 'Extend' page. if size == maxSize {
panic("not reached")
}
size *= 2
} }
theBackends = append(theBackends, s)
n := s.page.Alloc(width, height) b := &backend{
restorable: restorable.NewImage(size, size, false),
page: packing.NewPage(size, maxSize),
}
theBackends = append(theBackends, b)
n := b.page.Alloc(width, height)
if n == nil { if n == nil {
panic("not reached") panic("not reached")
} }
i := &Image{ i := &Image{
backend: s, backend: b,
node: n, node: n,
} }
runtime.SetFinalizer(i, (*Image).Dispose) runtime.SetFinalizer(i, (*Image).Dispose)