From 7c506bc5bca72811dd019a5bc1bee7e1384cf720 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Thu, 14 Feb 2019 23:44:02 +0900 Subject: [PATCH] restorable: Refactoring: Add (*Image).QuadVertices/PutVertex --- internal/graphics/vertices.go | 2 + internal/restorable/image.go | 24 ++++++++++-- internal/restorable/images_test.go | 59 +++++++++++++----------------- internal/shareable/shareable.go | 20 ++-------- 4 files changed, 52 insertions(+), 53 deletions(-) diff --git a/internal/graphics/vertices.go b/internal/graphics/vertices.go index a76260cdd..5973cc37e 100644 --- a/internal/graphics/vertices.go +++ b/internal/graphics/vertices.go @@ -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 { + // width and height are the source image's size. + // For performance reason, graphics.InternalImageSize is not applied to width/height here. if !isInternalImageSize(width) { diff --git a/internal/restorable/image.go b/internal/restorable/image.go index 2bab16cd2..7a11d1026 100644 --- a/internal/restorable/image.go +++ b/internal/restorable/image.go @@ -191,7 +191,7 @@ func (i *Image) fill(r, g, b, a uint8) { // 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. - dw, dh := i.InternalSize() + dw, dh := i.internalSize() sw, sh := emptyImage.Size() vs := graphics.QuadVertices(dw, dh, 0, 0, sw, sh, 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() } -// InternalSize returns the size of the internal texture. -func (i *Image) InternalSize() (int, int) { +// internalSize returns the size of the internal texture. +func (i *Image) internalSize() (int, int) { if i.w2 == 0 || i.h2 == 0 { w, h := i.image.Size() i.w2 = graphics.InternalImageSize(w) @@ -236,6 +236,24 @@ func (i *Image) InternalSize() (int, int) { 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. func (i *Image) makeStale() { i.basePixels = nil diff --git a/internal/restorable/images_test.go b/internal/restorable/images_test.go index 1cf4e6a40..08c0a2049 100644 --- a/internal/restorable/images_test.go +++ b/internal/restorable/images_test.go @@ -105,10 +105,8 @@ func TestRestoreWithoutDraw(t *testing.T) { } } -func quadVertices(dw, dh, sw, sh, x, y int) []float32 { - // dw/dh must be internal image sizes. - return graphics.QuadVertices(dw, dh, - 0, 0, sw, sh, +func quadVertices(src *Image, sw, sh, x, y int) []float32 { + return src.QuadVertices(0, 0, sw, sh, 1, 0, 0, 1, float32(x), float32(y), 1, 1, 1, 1) } @@ -128,8 +126,7 @@ func TestRestoreChain(t *testing.T) { clr := color.RGBA{0x00, 0x00, 0x00, 0xff} imgs[0].Fill(clr.R, clr.G, clr.B, clr.A) for i := 0; i < num-1; i++ { - w, h := imgs[i].InternalSize() - vs := quadVertices(w, h, 1, 1, 0, 0) + vs := quadVertices(imgs[i], 1, 1, 0, 0) is := graphics.QuadIndices() 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} 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() - imgs[8].DrawImage(imgs[7], vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) - imgs[9].DrawImage(imgs[8], 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], quadVertices(imgs[8], w, h, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) 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() @@ -212,12 +208,11 @@ func TestRestoreOverrideSource(t *testing.T) { clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff} clr1 := color.RGBA{0x00, 0x00, 0x01, 0xff} 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() - img2.DrawImage(img1, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) - img3.DrawImage(img2, 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, quadVertices(img2, w, h, 0, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) 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() if err := Restore(); err != nil { t.Fatal(err) @@ -292,26 +287,24 @@ func TestRestoreComplexGraph(t *testing.T) { img1.Dispose() img0.Dispose() }() - dw := graphics.InternalImageSize(w) - dh := graphics.InternalImageSize(h) - vs := quadVertices(dw, dh, w, h, 0, 0) + vs := quadVertices(img0, w, h, 0, 0) is := graphics.QuadIndices() 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) - 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) - 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) - 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) - 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) - 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) - 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) - 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) ResolveStaleImages() if err := Restore(); err != nil { @@ -401,10 +394,9 @@ func TestRestoreRecursive(t *testing.T) { img1.Dispose() img0.Dispose() }() - vs := quadVertices(graphics.InternalImageSize(w), graphics.InternalImageSize(h), w, h, 1, 0) is := graphics.QuadIndices() - img1.DrawImage(img0, vs, is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) - img0.DrawImage(img1, 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, quadVertices(img1, w, h, 1, 0), is, nil, graphics.CompositeModeSourceOver, graphics.FilterNearest, graphics.AddressClampToZero) ResolveStaleImages() if err := Restore(); err != nil { t.Fatal(err) @@ -491,7 +483,7 @@ func TestDrawImageAndReplacePixels(t *testing.T) { img1 := NewImage(2, 1) 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() 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) @@ -524,10 +516,9 @@ func TestDispose(t *testing.T) { img2 := newImageFromImage(base2) defer img2.Dispose() - vs := quadVertices(graphics.InternalImageSize(1), graphics.InternalImageSize(1), 1, 1, 0, 0) is := graphics.QuadIndices() - img1.DrawImage(img2, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) - img0.DrawImage(img1, 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, quadVertices(img1, 1, 1, 0, 0), is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) img1.Dispose() ResolveStaleImages() @@ -618,7 +609,7 @@ func TestReplacePixelsOnly(t *testing.T) { 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() img1.DrawImage(img0, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) 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. 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() dst.DrawImage(src, vs, is, nil, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero) diff --git a/internal/shareable/shareable.go b/internal/shareable/shareable.go index fa9946aeb..b6139c2b8 100644 --- a/internal/shareable/shareable.go +++ b/internal/shareable/shareable.go @@ -129,8 +129,7 @@ func (i *Image) ensureNotShared() { x, y, w, h := i.region() newImg := restorable.NewImage(w, h) - vw, vh := i.backend.restorable.InternalSize() - vs := graphics.QuadVertices(vw, vh, x, y, x+w, y+h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1) + vs := i.backend.restorable.QuadVertices(x, y, x+w, y+h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1) is := graphics.QuadIndices() 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) } ox, oy, _, _ := i.region() - w, h := i.backend.restorable.InternalSize() - return graphics.QuadVertices(w, h, sx0+ox, sy0+oy, sx1+ox, sy1+oy, a, b, c, d, tx, ty, cr, cg, cb, ca) + return i.backend.restorable.QuadVertices(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, - cr, cg, cb, ca float32) { +func (i *Image) PutVertex(dest []float32, dx, dy, sx, sy float32, bx0, by0, bx1, by1 float32, cr, cg, cb, ca float32) { if i.backend == nil { i.allocate(true) } ox, oy, _, _ := i.region() oxf, oyf := float32(ox), float32(oy) - w, h := i.backend.restorable.InternalSize() - - 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) + i.backend.restorable.PutVertex(dest, dx, dy, sx+oxf, sy+oyf, bx0+oxf, by0+oyf, bx1+oxf, by1+oyf, cr, cg, cb, ca) } const MaxCountForShare = 10