restorable: Add MakeVolatile

This commit is contained in:
Hajime Hoshi 2019-02-12 15:05:05 +09:00
parent f613cd1407
commit 5147bbde9d
3 changed files with 35 additions and 30 deletions

View File

@ -75,16 +75,19 @@ func init() {
// The returned image is cleared. // The returned image is cleared.
// //
// Note that Dispose is not called automatically. // Note that Dispose is not called automatically.
func NewImage(width, height int, volatile bool) *Image { func NewImage(width, height int) *Image {
i := &Image{ i := &Image{
image: graphicscommand.NewImage(width, height), image: graphicscommand.NewImage(width, height),
volatile: volatile,
} }
i.clear() i.clear()
theImages.add(i) theImages.add(i)
return i return i
} }
func (i *Image) MakeVolatile() {
i.volatile = true
}
// NewScreenFramebufferImage creates a special image that framebuffer is one for the screen. // NewScreenFramebufferImage creates a special image that framebuffer is one for the screen.
// //
// The returned image is cleared. // The returned image is cleared.

View File

@ -81,7 +81,7 @@ func fill(img *Image, r, g, b, a uint8) {
} }
func TestRestore(t *testing.T) { func TestRestore(t *testing.T) {
img0 := NewImage(1, 1, false) img0 := NewImage(1, 1)
defer img0.Dispose() defer img0.Dispose()
clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff} clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff}
@ -98,7 +98,7 @@ func TestRestore(t *testing.T) {
} }
func TestRestoreWithoutDraw(t *testing.T) { func TestRestoreWithoutDraw(t *testing.T) {
img0 := NewImage(1024, 1024, false) img0 := NewImage(1024, 1024)
defer img0.Dispose() defer img0.Dispose()
// If there is no drawing command on img0, img0 is cleared when restored. // If there is no drawing command on img0, img0 is cleared when restored.
@ -121,7 +121,7 @@ func TestRestoreChain(t *testing.T) {
const num = 10 const num = 10
imgs := []*Image{} imgs := []*Image{}
for i := 0; i < num; i++ { for i := 0; i < num; i++ {
img := NewImage(1, 1, false) img := NewImage(1, 1)
imgs = append(imgs, img) imgs = append(imgs, img)
} }
defer func() { defer func() {
@ -158,7 +158,7 @@ func TestRestoreChain2(t *testing.T) {
) )
imgs := []*Image{} imgs := []*Image{}
for i := 0; i < num; i++ { for i := 0; i < num; i++ {
img := NewImage(w, h, false) img := NewImage(w, h)
imgs = append(imgs, img) imgs = append(imgs, img)
} }
defer func() { defer func() {
@ -203,10 +203,10 @@ func TestRestoreOverrideSource(t *testing.T) {
w = 1 w = 1
h = 1 h = 1
) )
img0 := NewImage(w, h, false) img0 := NewImage(w, h)
img1 := NewImage(w, h, false) img1 := NewImage(w, h)
img2 := NewImage(w, h, false) img2 := NewImage(w, h)
img3 := NewImage(w, h, false) img3 := NewImage(w, h)
defer func() { defer func() {
img3.Dispose() img3.Dispose()
img2.Dispose() img2.Dispose()
@ -281,11 +281,11 @@ func TestRestoreComplexGraph(t *testing.T) {
img0 := newImageFromImage(base) img0 := newImageFromImage(base)
img1 := newImageFromImage(base) img1 := newImageFromImage(base)
img2 := newImageFromImage(base) img2 := newImageFromImage(base)
img3 := NewImage(w, h, false) img3 := NewImage(w, h)
img4 := NewImage(w, h, false) img4 := NewImage(w, h)
img5 := NewImage(w, h, false) img5 := NewImage(w, h)
img6 := NewImage(w, h, false) img6 := NewImage(w, h)
img7 := NewImage(w, h, false) img7 := NewImage(w, h)
defer func() { defer func() {
img7.Dispose() img7.Dispose()
img6.Dispose() img6.Dispose()
@ -381,7 +381,7 @@ func TestRestoreComplexGraph(t *testing.T) {
func newImageFromImage(rgba *image.RGBA) *Image { func newImageFromImage(rgba *image.RGBA) *Image {
s := rgba.Bounds().Size() s := rgba.Bounds().Size()
img := NewImage(s.X, s.Y, false) img := NewImage(s.X, s.Y)
img.ReplacePixels(rgba.Pix, 0, 0, s.X, s.Y) img.ReplacePixels(rgba.Pix, 0, 0, s.X, s.Y)
return img return img
} }
@ -398,7 +398,7 @@ func TestRestoreRecursive(t *testing.T) {
base.Pix[3] = 0xff base.Pix[3] = 0xff
img0 := newImageFromImage(base) img0 := newImageFromImage(base)
img1 := NewImage(w, h, false) img1 := NewImage(w, h)
defer func() { defer func() {
img1.Dispose() img1.Dispose()
img0.Dispose() img0.Dispose()
@ -447,7 +447,7 @@ func TestReplacePixels(t *testing.T) {
h = 31 h = 31
) )
img := NewImage(17, 31, false) img := NewImage(17, 31)
defer img.Dispose() defer img.Dispose()
pix := make([]byte, 4*4*4) pix := make([]byte, 4*4*4)
@ -490,7 +490,7 @@ func TestDrawImageAndReplacePixels(t *testing.T) {
base.Pix[3] = 0xff base.Pix[3] = 0xff
img0 := newImageFromImage(base) img0 := newImageFromImage(base)
defer img0.Dispose() defer img0.Dispose()
img1 := NewImage(2, 1, false) img1 := NewImage(2, 1)
defer img1.Dispose() defer img1.Dispose()
vs := graphics.QuadVertices(1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1) vs := graphics.QuadVertices(1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
@ -550,7 +550,7 @@ func TestClear(t *testing.T) {
pix[i] = 0xff pix[i] = 0xff
} }
img := NewImage(4, 4, false) img := NewImage(4, 4)
img.ReplacePixels(pix, 0, 0, 4, 4) img.ReplacePixels(pix, 0, 0, 4, 4)
// This doesn't make the image stale. Its base pixels are available. // This doesn't make the image stale. Its base pixels are available.
img.ReplacePixels(nil, 1, 1, 2, 2) img.ReplacePixels(nil, 1, 1, 2, 2)
@ -611,9 +611,9 @@ func TestClear(t *testing.T) {
func TestReplacePixelsOnly(t *testing.T) { func TestReplacePixelsOnly(t *testing.T) {
const w, h = 128, 128 const w, h = 128, 128
img0 := NewImage(w, h, false) img0 := NewImage(w, h)
defer img0.Dispose() defer img0.Dispose()
img1 := NewImage(1, 1, false) img1 := NewImage(1, 1)
defer img1.Dispose() defer img1.Dispose()
for i := 0; i < w*h; i += 5 { for i := 0; i < w*h; i += 5 {
@ -656,8 +656,9 @@ func TestReplacePixelsOnly(t *testing.T) {
// Issue #793 // Issue #793
func TestReadPixelsFromVolatileImage(t *testing.T) { func TestReadPixelsFromVolatileImage(t *testing.T) {
const w, h = 16, 16 const w, h = 16, 16
dst := NewImage(w, h, true) dst := NewImage(w, h)
src := NewImage(w, h, false) dst.MakeVolatile()
src := NewImage(w, h)
// First, make sure that dst has pixels // First, make sure that dst has pixels
dst.ReplacePixels(make([]byte, 4*w*h), 0, 0, w, h) dst.ReplacePixels(make([]byte, 4*w*h), 0, 0, w, h)

View File

@ -62,7 +62,7 @@ func (b *backend) TryAlloc(width, height int) (*packing.Node, bool) {
b.page.Extend() b.page.Extend()
} }
s := b.page.Size() s := b.page.Size()
newImg := restorable.NewImage(s, s, false) newImg := restorable.NewImage(s, s)
oldImg := b.restorable oldImg := b.restorable
// Do not use DrawImage here. ReplacePixels will be called on a part of newImg later, and it looked like // Do not use DrawImage here. ReplacePixels will be called on a part of newImg later, and it looked like
// ReplacePixels on a part of image deletes other region that are rendered by DrawImage (#593, #758). // ReplacePixels on a part of image deletes other region that are rendered by DrawImage (#593, #758).
@ -128,7 +128,7 @@ func (i *Image) ensureNotShared() {
} }
x, y, w, h := i.region() x, y, w, h := i.region()
newImg := restorable.NewImage(w, h, false) newImg := restorable.NewImage(w, h)
vw, vh := i.backend.restorable.Size() vw, vh := i.backend.restorable.Size()
vs := graphics.QuadVertices(vw, vh, x, y, x+w, y+h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1) vs := graphics.QuadVertices(vw, vh, x, y, x+w, y+h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
is := graphics.QuadIndices() is := graphics.QuadIndices()
@ -443,7 +443,7 @@ func (i *Image) allocate(shareable bool) {
if !shareable || !i.shareable() { if !shareable || !i.shareable() {
i.backend = &backend{ i.backend = &backend{
restorable: restorable.NewImage(i.width, i.height, false), restorable: restorable.NewImage(i.width, i.height),
} }
runtime.SetFinalizer(i, (*Image).Dispose) runtime.SetFinalizer(i, (*Image).Dispose)
return return
@ -466,7 +466,7 @@ func (i *Image) allocate(shareable bool) {
} }
b := &backend{ b := &backend{
restorable: restorable.NewImage(size, size, false), restorable: restorable.NewImage(size, size),
page: packing.NewPage(size, maxSize), page: packing.NewPage(size, maxSize),
} }
theBackends = append(theBackends, b) theBackends = append(theBackends, b)
@ -485,7 +485,8 @@ func NewVolatileImage(width, height int) *Image {
backendsM.Lock() backendsM.Lock()
defer backendsM.Unlock() defer backendsM.Unlock()
r := restorable.NewImage(width, height, true) r := restorable.NewImage(width, height)
r.MakeVolatile()
i := &Image{ i := &Image{
width: width, width: width,
height: height, height: height,