restorable: Bug fix: ReplacePixels might call DrawImage, which violates some assumptions

This commit is contained in:
Hajime Hoshi 2019-01-10 23:22:59 +09:00
parent 6d714a16cf
commit 4a587f495d
2 changed files with 38 additions and 19 deletions

View File

@ -76,7 +76,23 @@ func NewImage(width, height int, volatile bool) *Image {
image: graphicscommand.NewImage(width, height),
volatile: volatile,
}
i.ReplacePixels(nil, 0, 0, width, height)
// There are not 'drawImageHistoryItem's for this image and dummyImage.
// This means dummyImage might not be restored yet when this image is restored.
// However, that's ok since this image will be stale or have its updated pixel data soon,
// and this image can be restored without dummyImage.
//
// dummyImage should be restored later anyway.
sw, sh := dummyImage.Size()
dw := graphics.NextPowerOf2Int(width)
dh := graphics.NextPowerOf2Int(height)
vs := graphics.QuadVertices(dw, dh, 0, 0, sw, sh,
float32(width)/float32(sw), 0, 0, float32(height)/float32(sh),
0, 0,
1, 1, 1, 1)
is := graphics.QuadIndices()
i.image.DrawImage(dummyImage.image, vs, is, nil, graphics.CompositeModeClear, graphics.FilterNearest, graphics.AddressClampToZero)
theImages.add(i)
return i
}
@ -156,25 +172,10 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
// For this purpuse, images should remember which part of that is used for DrawImage.
theImages.makeStaleIfDependingOn(i)
if pixels != nil {
i.image.ReplacePixels(pixels, x, y, width, height)
} else {
// There are not 'drawImageHistoryItem's for this image and dummyImage.
// This means dummyImage might not be restored yet when this image is restored.
// However, that's ok since this image will be stale or have its updated pixel data soon,
// and this image can be restored without dummyImage.
//
// dummyImage should be restored later anyway.
sw, sh := dummyImage.Size()
dw := graphics.NextPowerOf2Int(w)
dh := graphics.NextPowerOf2Int(h)
vs := graphics.QuadVertices(dw, dh, 0, 0, sw, sh,
float32(width)/float32(sw), 0, 0, float32(height)/float32(sh),
float32(x), float32(y),
1, 1, 1, 1)
is := graphics.QuadIndices()
i.image.DrawImage(dummyImage.image, vs, is, nil, graphics.CompositeModeClear, graphics.FilterNearest, graphics.AddressClampToZero)
if pixels == nil {
pixels = make([]byte, 4*width*height)
}
i.image.ReplacePixels(pixels, x, y, width, height)
if x == 0 && y == 0 && width == w && height == h {
if pixels != nil {

View File

@ -206,6 +206,7 @@ func Disabled_TestReshared(t *testing.T) {
func TestExtend(t *testing.T) {
const w0, h0 = 100, 100
img0 := NewImage(w0, h0)
defer img0.Dispose()
p0 := make([]byte, 4*w0*h0)
for i := 0; i < w0*h0; i++ {
p0[4*i] = byte(i)
@ -217,6 +218,7 @@ func TestExtend(t *testing.T) {
const w1, h1 = 1025, 100
img1 := NewImage(w1, h1)
defer img1.Dispose()
p1 := make([]byte, 4*w1*h1)
for i := 0; i < w1*h1; i++ {
p1[4*i] = byte(i)
@ -256,7 +258,9 @@ func TestExtend(t *testing.T) {
func TestReplacePixelsAfterDrawImage(t *testing.T) {
const w, h = 256, 256
src := NewImage(w, h)
defer src.Dispose()
dst := NewImage(w, h)
defer dst.Dispose()
pix := make([]byte, 4*w*h)
for i := 0; i < w*h; i++ {
@ -283,3 +287,17 @@ func TestReplacePixelsAfterDrawImage(t *testing.T) {
}
}
}
func TestVariousReplacePixelsMustNotCrash(t *testing.T) {
const w, h = 256, 256
img0 := NewImage(w, h)
defer img0.Dispose()
img1 := NewImage(w, h)
defer img1.Dispose()
img0.ReplacePixels(nil)
img0.ReplacePixels(make([]byte, 4*w*h))
img0.ReplacePixels(nil)
img0.ReplacePixels(make([]byte, 4*w*h))
img1.Dispose()
img0.Dispose()
}