restorable: Refactoring: Add (*Image).QuadVertices/PutVertex

This commit is contained in:
Hajime Hoshi 2019-02-14 23:44:02 +09:00
parent a06a2b65c1
commit 7c506bc5bc
4 changed files with 52 additions and 53 deletions

View File

@ -60,6 +60,8 @@ func (v *verticesBackend) slice(n int) []float32 {
} }
func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty float32, cr, cg, cb, ca float32) []float32 { func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty float32, cr, cg, cb, ca float32) []float32 {
// width and height are the source image's size.
// For performance reason, graphics.InternalImageSize is not applied to width/height here. // For performance reason, graphics.InternalImageSize is not applied to width/height here.
if !isInternalImageSize(width) { if !isInternalImageSize(width) {

View File

@ -191,7 +191,7 @@ func (i *Image) fill(r, g, b, a uint8) {
// There are not 'drawImageHistoryItem's for this image and emptyImage. // There are not 'drawImageHistoryItem's for this image and emptyImage.
// As emptyImage is a priority image, this is restored before other regular images are restored. // As emptyImage is a priority image, this is restored before other regular images are restored.
dw, dh := i.InternalSize() dw, dh := i.internalSize()
sw, sh := emptyImage.Size() sw, sh := emptyImage.Size()
vs := graphics.QuadVertices(dw, dh, 0, 0, sw, sh, vs := graphics.QuadVertices(dw, dh, 0, 0, sw, sh,
float32(dw)/float32(sw), 0, 0, float32(dh)/float32(sh), 0, 0, float32(dw)/float32(sw), 0, 0, float32(dh)/float32(sh), 0, 0,
@ -226,8 +226,8 @@ func (i *Image) Size() (int, int) {
return i.image.Size() return i.image.Size()
} }
// InternalSize returns the size of the internal texture. // internalSize returns the size of the internal texture.
func (i *Image) InternalSize() (int, int) { func (i *Image) internalSize() (int, int) {
if i.w2 == 0 || i.h2 == 0 { if i.w2 == 0 || i.h2 == 0 {
w, h := i.image.Size() w, h := i.image.Size()
i.w2 = graphics.InternalImageSize(w) i.w2 = graphics.InternalImageSize(w)
@ -236,6 +236,24 @@ func (i *Image) InternalSize() (int, int) {
return i.w2, i.h2 return i.w2, i.h2
} }
func (i *Image) QuadVertices(sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty float32, cr, cg, cb, ca float32) []float32 {
w, h := i.internalSize()
return graphics.QuadVertices(w, h, sx0, sy0, sx1, sy1, a, b, c, d, tx, ty, cr, cg, cb, ca)
}
func (i *Image) PutVertex(dest []float32, dx, dy, sx, sy float32, bx0, by0, bx1, by1 float32, cr, cg, cb, ca float32) {
w, h := i.internalSize()
su := sx / float32(w)
sv := sy / float32(h)
u0 := bx0 / float32(w)
v0 := by0 / float32(h)
u1 := bx1 / float32(w)
v1 := by1 / float32(h)
graphics.PutVertex(dest, w, h, dx, dy, su, sv, u0, v0, u1, v1, cr, cg, cb, ca)
}
// makeStale makes the image stale. // makeStale makes the image stale.
func (i *Image) makeStale() { func (i *Image) makeStale() {
i.basePixels = nil i.basePixels = nil

View File

@ -105,10 +105,8 @@ func TestRestoreWithoutDraw(t *testing.T) {
} }
} }
func quadVertices(dw, dh, sw, sh, x, y int) []float32 { func quadVertices(src *Image, sw, sh, x, y int) []float32 {
// dw/dh must be internal image sizes. return src.QuadVertices(0, 0, sw, sh,
return graphics.QuadVertices(dw, dh,
0, 0, sw, sh,
1, 0, 0, 1, float32(x), float32(y), 1, 0, 0, 1, float32(x), float32(y),
1, 1, 1, 1) 1, 1, 1, 1)
} }
@ -128,8 +126,7 @@ func TestRestoreChain(t *testing.T) {
clr := color.RGBA{0x00, 0x00, 0x00, 0xff} clr := color.RGBA{0x00, 0x00, 0x00, 0xff}
imgs[0].Fill(clr.R, clr.G, clr.B, clr.A) imgs[0].Fill(clr.R, clr.G, clr.B, clr.A)
for i := 0; i < num-1; i++ { for i := 0; i < num-1; i++ {
w, h := imgs[i].InternalSize() vs := quadVertices(imgs[i], 1, 1, 0, 0)
vs := quadVertices(w, h, 1, 1, 0, 0)
is := graphics.QuadIndices() is := graphics.QuadIndices()
imgs[i+1].DrawImage(imgs[i], vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) imgs[i+1].DrawImage(imgs[i], vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
} }
@ -170,12 +167,11 @@ func TestRestoreChain2(t *testing.T) {
clr8 := color.RGBA{0x00, 0x00, 0xff, 0xff} clr8 := color.RGBA{0x00, 0x00, 0xff, 0xff}
imgs[8].Fill(clr8.R, clr8.G, clr8.B, clr8.A) imgs[8].Fill(clr8.R, clr8.G, clr8.B, clr8.A)
vs := quadVertices(graphics.InternalImageSize(w), graphics.InternalImageSize(h), w, h, 0, 0)
is := graphics.QuadIndices() is := graphics.QuadIndices()
imgs[8].DrawImage(imgs[7], vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) imgs[8].DrawImage(imgs[7], quadVertices(imgs[7], w, h, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
imgs[9].DrawImage(imgs[8], vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) imgs[9].DrawImage(imgs[8], quadVertices(imgs[8], w, h, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
for i := 0; i < 7; i++ { for i := 0; i < 7; i++ {
imgs[i+1].DrawImage(imgs[i], vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) imgs[i+1].DrawImage(imgs[i], quadVertices(imgs[i], w, h, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
} }
ResolveStaleImages() ResolveStaleImages()
@ -212,12 +208,11 @@ func TestRestoreOverrideSource(t *testing.T) {
clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff} clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff}
clr1 := color.RGBA{0x00, 0x00, 0x01, 0xff} clr1 := color.RGBA{0x00, 0x00, 0x01, 0xff}
img1.Fill(clr0.R, clr0.G, clr0.B, clr0.A) img1.Fill(clr0.R, clr0.G, clr0.B, clr0.A)
vs := quadVertices(graphics.InternalImageSize(w), graphics.InternalImageSize(h), w, h, 0, 0)
is := graphics.QuadIndices() is := graphics.QuadIndices()
img2.DrawImage(img1, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img2.DrawImage(img1, quadVertices(img1, w, h, 0, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
img3.DrawImage(img2, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img3.DrawImage(img2, quadVertices(img2, w, h, 0, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
img0.Fill(clr1.R, clr1.G, clr1.B, clr1.A) img0.Fill(clr1.R, clr1.G, clr1.B, clr1.A)
img1.DrawImage(img0, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img1.DrawImage(img0, quadVertices(img0, w, h, 0, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
ResolveStaleImages() ResolveStaleImages()
if err := Restore(); err != nil { if err := Restore(); err != nil {
t.Fatal(err) t.Fatal(err)
@ -292,26 +287,24 @@ func TestRestoreComplexGraph(t *testing.T) {
img1.Dispose() img1.Dispose()
img0.Dispose() img0.Dispose()
}() }()
dw := graphics.InternalImageSize(w) vs := quadVertices(img0, w, h, 0, 0)
dh := graphics.InternalImageSize(h)
vs := quadVertices(dw, dh, w, h, 0, 0)
is := graphics.QuadIndices() is := graphics.QuadIndices()
img3.DrawImage(img0, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img3.DrawImage(img0, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
vs = quadVertices(dw, dh, w, h, 1, 0) vs = quadVertices(img1, w, h, 1, 0)
img3.DrawImage(img1, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img3.DrawImage(img1, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
vs = quadVertices(dw, dh, w, h, 1, 0) vs = quadVertices(img1, w, h, 1, 0)
img4.DrawImage(img1, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img4.DrawImage(img1, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
vs = quadVertices(dw, dh, w, h, 2, 0) vs = quadVertices(img2, w, h, 2, 0)
img4.DrawImage(img2, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img4.DrawImage(img2, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
vs = quadVertices(dw, dh, w, h, 0, 0) vs = quadVertices(img3, w, h, 0, 0)
img5.DrawImage(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img5.DrawImage(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
vs = quadVertices(dw, dh, w, h, 0, 0) vs = quadVertices(img3, w, h, 0, 0)
img6.DrawImage(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img6.DrawImage(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
vs = quadVertices(dw, dh, w, h, 1, 0) vs = quadVertices(img4, w, h, 1, 0)
img6.DrawImage(img4, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img6.DrawImage(img4, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
vs = quadVertices(dw, dh, w, h, 0, 0) vs = quadVertices(img2, w, h, 0, 0)
img7.DrawImage(img2, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img7.DrawImage(img2, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
vs = quadVertices(dw, dh, w, h, 2, 0) vs = quadVertices(img3, w, h, 2, 0)
img7.DrawImage(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img7.DrawImage(img3, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
ResolveStaleImages() ResolveStaleImages()
if err := Restore(); err != nil { if err := Restore(); err != nil {
@ -401,10 +394,9 @@ func TestRestoreRecursive(t *testing.T) {
img1.Dispose() img1.Dispose()
img0.Dispose() img0.Dispose()
}() }()
vs := quadVertices(graphics.InternalImageSize(w), graphics.InternalImageSize(h), w, h, 1, 0)
is := graphics.QuadIndices() is := graphics.QuadIndices()
img1.DrawImage(img0, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img1.DrawImage(img0, quadVertices(img0, w, h, 1, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
img0.DrawImage(img1, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) img0.DrawImage(img1, quadVertices(img1, w, h, 1, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero)
ResolveStaleImages() ResolveStaleImages()
if err := Restore(); err != nil { if err := Restore(); err != nil {
t.Fatal(err) t.Fatal(err)
@ -491,7 +483,7 @@ func TestDrawImageAndReplacePixels(t *testing.T) {
img1 := NewImage(2, 1) img1 := NewImage(2, 1)
defer img1.Dispose() defer img1.Dispose()
vs := quadVertices(graphics.InternalImageSize(1), graphics.InternalImageSize(1), 1, 1, 0, 0) vs := quadVertices(img0, 1, 1, 0, 0)
is := graphics.QuadIndices() is := graphics.QuadIndices()
img1.DrawImage(img0, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) img1.DrawImage(img0, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
img1.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, 0, 2, 1) img1.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, 0, 2, 1)
@ -524,10 +516,9 @@ func TestDispose(t *testing.T) {
img2 := newImageFromImage(base2) img2 := newImageFromImage(base2)
defer img2.Dispose() defer img2.Dispose()
vs := quadVertices(graphics.InternalImageSize(1), graphics.InternalImageSize(1), 1, 1, 0, 0)
is := graphics.QuadIndices() is := graphics.QuadIndices()
img1.DrawImage(img2, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) img1.DrawImage(img2, quadVertices(img2, 1, 1, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
img0.DrawImage(img1, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) img0.DrawImage(img1, quadVertices(img1, 1, 1, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
img1.Dispose() img1.Dispose()
ResolveStaleImages() ResolveStaleImages()
@ -618,7 +609,7 @@ func TestReplacePixelsOnly(t *testing.T) {
img0.ReplacePixels([]byte{1, 2, 3, 4}, i%w, i/w, 1, 1) img0.ReplacePixels([]byte{1, 2, 3, 4}, i%w, i/w, 1, 1)
} }
vs := quadVertices(graphics.InternalImageSize(w), graphics.InternalImageSize(h), 1, 1, 0, 0) vs := quadVertices(img0, 1, 1, 0, 0)
is := graphics.QuadIndices() is := graphics.QuadIndices()
img1.DrawImage(img0, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) img1.DrawImage(img0, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
img0.ReplacePixels([]byte{5, 6, 7, 8}, 0, 0, 1, 1) img0.ReplacePixels([]byte{5, 6, 7, 8}, 0, 0, 1, 1)
@ -663,7 +654,7 @@ func TestReadPixelsFromVolatileImage(t *testing.T) {
// Second, draw src to dst. If the implementation is correct, dst becomes stale. // Second, draw src to dst. If the implementation is correct, dst becomes stale.
src.Fill(0xff, 0xff, 0xff, 0xff) src.Fill(0xff, 0xff, 0xff, 0xff)
vs := quadVertices(graphics.InternalImageSize(w), graphics.InternalImageSize(h), 1, 1, 0, 0) vs := quadVertices(src, 1, 1, 0, 0)
is := graphics.QuadIndices() is := graphics.QuadIndices()
dst.DrawImage(src, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) dst.DrawImage(src, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)

View File

@ -129,8 +129,7 @@ func (i *Image) ensureNotShared() {
x, y, w, h := i.region() x, y, w, h := i.region()
newImg := restorable.NewImage(w, h) newImg := restorable.NewImage(w, h)
vw, vh := i.backend.restorable.InternalSize() vs := i.backend.restorable.QuadVertices(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()
newImg.DrawImage(i.backend.restorable, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) newImg.DrawImage(i.backend.restorable, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
@ -190,27 +189,16 @@ func (i *Image) QuadVertices(sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty float32,
i.allocate(true) i.allocate(true)
} }
ox, oy, _, _ := i.region() ox, oy, _, _ := i.region()
w, h := i.backend.restorable.InternalSize() return i.backend.restorable.QuadVertices(sx0+ox, sy0+oy, sx1+ox, sy1+oy, a, b, c, d, tx, ty, cr, cg, cb, ca)
return graphics.QuadVertices(w, h, sx0+ox, sy0+oy, sx1+ox, sy1+oy, a, b, c, d, tx, ty, cr, cg, cb, ca)
} }
func (i *Image) PutVertex(dest []float32, dx, dy, sx, sy float32, bx0, by0, bx1, by1 float32, func (i *Image) PutVertex(dest []float32, dx, dy, sx, sy float32, bx0, by0, bx1, by1 float32, cr, cg, cb, ca float32) {
cr, cg, cb, ca float32) {
if i.backend == nil { if i.backend == nil {
i.allocate(true) i.allocate(true)
} }
ox, oy, _, _ := i.region() ox, oy, _, _ := i.region()
oxf, oyf := float32(ox), float32(oy) oxf, oyf := float32(ox), float32(oy)
w, h := i.backend.restorable.InternalSize() i.backend.restorable.PutVertex(dest, dx, dy, sx+oxf, sy+oyf, bx0+oxf, by0+oyf, bx1+oxf, by1+oyf, cr, cg, cb, ca)
su := (sx + oxf) / float32(w)
sv := (sy + oyf) / float32(h)
u0 := (bx0 + oxf) / float32(w)
v0 := (by0 + oyf) / float32(h)
u1 := (bx1 + oxf) / float32(w)
v1 := (by1 + oyf) / float32(h)
graphics.PutVertex(dest, w, h, dx, dy, su, sv, u0, v0, u1, v1, cr, cg, cb, ca)
} }
const MaxCountForShare = 10 const MaxCountForShare = 10