internal/restorable: refactoring: unify NewScreenFramebufferImage and NewImage

This commit is contained in:
Hajime Hoshi 2022-06-06 09:29:30 +09:00
parent 31fd736ca5
commit 73c893e977
4 changed files with 63 additions and 72 deletions

View File

@ -283,8 +283,11 @@ func (i *Image) ensureIsolated() {
sy0 /= float32(sh)
sx1 /= float32(sw)
sy1 /= float32(sh)
newImg := restorable.NewImage(w, h)
newImg.SetVolatile(i.volatile)
typ := restorable.ImageTypeRegular
if i.volatile {
typ = restorable.ImageTypeVolatile
}
newImg := restorable.NewImage(w, h, typ)
vs := []float32{
dx0, dy0, sx0, sy0, 1, 1, 1, 1,
dx1, dy0, sx1, sy0, 1, 1, 1, 1,
@ -757,16 +760,19 @@ func (i *Image) allocate(putOnAtlas bool) {
if i.screen {
// A screen image doesn't have a padding.
i.backend = &backend{
restorable: restorable.NewScreenFramebufferImage(i.width, i.height),
restorable: restorable.NewImage(i.width, i.height, restorable.ImageTypeScreenFramebuffer),
}
return
}
if !putOnAtlas || !i.canBePutOnAtlas() {
i.backend = &backend{
restorable: restorable.NewImage(i.width+2*paddingSize, i.height+2*paddingSize),
typ := restorable.ImageTypeRegular
if i.volatile {
typ = restorable.ImageTypeVolatile
}
i.backend = &backend{
restorable: restorable.NewImage(i.width+2*paddingSize, i.height+2*paddingSize, typ),
}
i.backend.restorable.SetVolatile(i.volatile)
return
}
@ -785,11 +791,14 @@ func (i *Image) allocate(putOnAtlas bool) {
size *= 2
}
typ := restorable.ImageTypeRegular
if i.volatile {
typ = restorable.ImageTypeVolatile
}
b := &backend{
restorable: restorable.NewImage(size, size),
restorable: restorable.NewImage(size, size, typ),
page: packing.NewPage(size, maxSize),
}
b.restorable.SetVolatile(i.volatile)
theBackends = append(theBackends, b)
n := b.page.Alloc(i.width+2*paddingSize, i.height+2*paddingSize)

View File

@ -149,15 +149,16 @@ func ensureEmptyImage() *Image {
// The returned image is cleared.
//
// Note that Dispose is not called automatically.
func NewImage(width, height int) *Image {
func NewImage(width, height int, imageType ImageType) *Image {
if !graphicsDriverInitialized {
panic("restorable: graphics driver must be ready at NewImage but not")
}
i := &Image{
image: graphicscommand.NewImage(width, height, false),
width: width,
height: height,
image: graphicscommand.NewImage(width, height, imageType == ImageTypeScreenFramebuffer),
width: width,
height: height,
imageType: imageType,
}
clearImage(i.image)
theImages.add(i)
@ -201,8 +202,7 @@ func (i *Image) Extend(width, height int) *Image {
panic(fmt.Sprintf("restorable: the original size (%d, %d) cannot be extended to (%d, %d)", i.width, i.height, width, height))
}
newImg := NewImage(width, height)
newImg.SetVolatile(i.imageType == ImageTypeVolatile)
newImg := NewImage(width, height, i.imageType)
// Use DrawTriangles instead of ReplacePixels because the image i might be stale and not have its pixels
// information.
@ -230,23 +230,6 @@ func (i *Image) Extend(width, height int) *Image {
return newImg
}
// NewScreenFramebufferImage creates a special image that framebuffer is one for the screen.
//
// The returned image is cleared.
//
// Note that Dispose is not called automatically.
func NewScreenFramebufferImage(width, height int) *Image {
i := &Image{
image: graphicscommand.NewImage(width, height, true),
width: width,
height: height,
imageType: ImageTypeScreenFramebuffer,
}
clearImage(i.image)
theImages.add(i)
return i
}
// quadVertices returns vertices to render a quad. These values are passed to graphicscommand.Image.
func quadVertices(src *Image, dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1, cr, cg, cb, ca float32) []float32 {
sw, sh := src.InternalSize()

View File

@ -57,7 +57,7 @@ func sameColors(c1, c2 color.RGBA, delta int) bool {
}
func TestRestore(t *testing.T) {
img0 := restorable.NewImage(1, 1)
img0 := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
defer img0.Dispose()
clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff}
@ -76,7 +76,7 @@ func TestRestore(t *testing.T) {
}
func TestRestoreWithoutDraw(t *testing.T) {
img0 := restorable.NewImage(1024, 1024)
img0 := restorable.NewImage(1024, 1024, restorable.ImageTypeRegular)
defer img0.Dispose()
// If there is no drawing command on img0, img0 is cleared when restored.
@ -126,7 +126,7 @@ func TestRestoreChain(t *testing.T) {
const num = 10
imgs := []*restorable.Image{}
for i := 0; i < num; i++ {
img := restorable.NewImage(1, 1)
img := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
imgs = append(imgs, img)
}
defer func() {
@ -170,7 +170,7 @@ func TestRestoreChain2(t *testing.T) {
)
imgs := []*restorable.Image{}
for i := 0; i < num; i++ {
img := restorable.NewImage(w, h)
img := restorable.NewImage(w, h, restorable.ImageTypeRegular)
imgs = append(imgs, img)
}
defer func() {
@ -222,10 +222,10 @@ func TestRestoreOverrideSource(t *testing.T) {
w = 1
h = 1
)
img0 := restorable.NewImage(w, h)
img1 := restorable.NewImage(w, h)
img2 := restorable.NewImage(w, h)
img3 := restorable.NewImage(w, h)
img0 := restorable.NewImage(w, h, restorable.ImageTypeRegular)
img1 := restorable.NewImage(w, h, restorable.ImageTypeRegular)
img2 := restorable.NewImage(w, h, restorable.ImageTypeRegular)
img3 := restorable.NewImage(w, h, restorable.ImageTypeRegular)
defer func() {
img3.Dispose()
img2.Dispose()
@ -307,11 +307,11 @@ func TestRestoreComplexGraph(t *testing.T) {
img0 := newImageFromImage(base)
img1 := newImageFromImage(base)
img2 := newImageFromImage(base)
img3 := restorable.NewImage(w, h)
img4 := restorable.NewImage(w, h)
img5 := restorable.NewImage(w, h)
img6 := restorable.NewImage(w, h)
img7 := restorable.NewImage(w, h)
img3 := restorable.NewImage(w, h, restorable.ImageTypeRegular)
img4 := restorable.NewImage(w, h, restorable.ImageTypeRegular)
img5 := restorable.NewImage(w, h, restorable.ImageTypeRegular)
img6 := restorable.NewImage(w, h, restorable.ImageTypeRegular)
img7 := restorable.NewImage(w, h, restorable.ImageTypeRegular)
defer func() {
img7.Dispose()
img6.Dispose()
@ -416,7 +416,7 @@ func TestRestoreComplexGraph(t *testing.T) {
func newImageFromImage(rgba *image.RGBA) *restorable.Image {
s := rgba.Bounds().Size()
img := restorable.NewImage(s.X, s.Y)
img := restorable.NewImage(s.X, s.Y, restorable.ImageTypeRegular)
img.ReplacePixels(rgba.Pix, nil, 0, 0, s.X, s.Y)
return img
}
@ -433,7 +433,7 @@ func TestRestoreRecursive(t *testing.T) {
base.Pix[3] = 0xff
img0 := newImageFromImage(base)
img1 := restorable.NewImage(w, h)
img1 := restorable.NewImage(w, h, restorable.ImageTypeRegular)
defer func() {
img1.Dispose()
img0.Dispose()
@ -484,7 +484,7 @@ func TestRestoreRecursive(t *testing.T) {
}
func TestReplacePixels(t *testing.T) {
img := restorable.NewImage(17, 31)
img := restorable.NewImage(17, 31, restorable.ImageTypeRegular)
defer img.Dispose()
pix := make([]byte, 4*4*4)
@ -535,7 +535,7 @@ func TestDrawTrianglesAndReplacePixels(t *testing.T) {
base.Pix[3] = 0xff
img0 := newImageFromImage(base)
defer img0.Dispose()
img1 := restorable.NewImage(2, 1)
img1 := restorable.NewImage(2, 1, restorable.ImageTypeRegular)
defer img1.Dispose()
vs := quadVertices(img0, 1, 1, 0, 0)
@ -616,7 +616,7 @@ func TestReplacePixelsPart(t *testing.T) {
pix[i] = 0xff
}
img := restorable.NewImage(4, 4)
img := restorable.NewImage(4, 4, restorable.ImageTypeRegular)
// This doesn't make the image stale. Its base pixels are available.
img.ReplacePixels(pix, nil, 1, 1, 2, 2)
@ -687,9 +687,9 @@ func TestReplacePixelsPart(t *testing.T) {
func TestReplacePixelsOnly(t *testing.T) {
const w, h = 128, 128
img0 := restorable.NewImage(w, h)
img0 := restorable.NewImage(w, h, restorable.ImageTypeRegular)
defer img0.Dispose()
img1 := restorable.NewImage(1, 1)
img1 := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
defer img1.Dispose()
for i := 0; i < w*h; i += 5 {
@ -743,9 +743,8 @@ func TestReplacePixelsOnly(t *testing.T) {
// Issue #793
func TestReadPixelsFromVolatileImage(t *testing.T) {
const w, h = 16, 16
dst := restorable.NewImage(w, h)
dst.SetVolatile(true)
src := restorable.NewImage(w, h)
dst := restorable.NewImage(w, h, restorable.ImageTypeVolatile)
src := restorable.NewImage(w, h, restorable.ImageTypeRegular)
// First, make sure that dst has pixels
dst.ReplacePixels(make([]byte, 4*w*h), nil, 0, 0, w, h)
@ -780,8 +779,8 @@ func TestReadPixelsFromVolatileImage(t *testing.T) {
func TestAllowReplacePixelsAfterDrawTriangles(t *testing.T) {
const w, h = 16, 16
src := restorable.NewImage(w, h)
dst := restorable.NewImage(w, h)
src := restorable.NewImage(w, h, restorable.ImageTypeRegular)
dst := restorable.NewImage(w, h, restorable.ImageTypeRegular)
vs := quadVertices(src, w, h, 0, 0)
is := graphics.QuadIndices()
@ -804,8 +803,8 @@ func TestDisallowReplacePixelsForPartAfterDrawTriangles(t *testing.T) {
}()
const w, h = 16, 16
src := restorable.NewImage(w, h)
dst := restorable.NewImage(w, h)
src := restorable.NewImage(w, h, restorable.ImageTypeRegular)
dst := restorable.NewImage(w, h, restorable.ImageTypeRegular)
vs := quadVertices(src, w, h, 0, 0)
is := graphics.QuadIndices()
@ -825,7 +824,7 @@ func TestExtend(t *testing.T) {
}
const w, h = 16, 16
orig := restorable.NewImage(w, h)
orig := restorable.NewImage(w, h, restorable.ImageTypeRegular)
pix := make([]byte, 4*w*h)
for j := 0; j < h; j++ {
for i := 0; i < w; i++ {
@ -860,7 +859,7 @@ func TestExtend(t *testing.T) {
func TestClearPixels(t *testing.T) {
const w, h = 16, 16
img := restorable.NewImage(w, h)
img := restorable.NewImage(w, h, restorable.ImageTypeRegular)
img.ReplacePixels(make([]byte, 4*4*4), nil, 0, 0, 4, 4)
img.ReplacePixels(make([]byte, 4*4*4), nil, 4, 0, 4, 4)
img.ClearPixels(0, 0, 4, 4)
@ -872,8 +871,8 @@ func TestClearPixels(t *testing.T) {
func TestMutateSlices(t *testing.T) {
const w, h = 16, 16
dst := restorable.NewImage(w, h)
src := restorable.NewImage(w, h)
dst := restorable.NewImage(w, h, restorable.ImageTypeRegular)
src := restorable.NewImage(w, h, restorable.ImageTypeRegular)
pix := make([]byte, 4*w*h)
for i := 0; i < w*h; i++ {
pix[4*i] = byte(i)
@ -926,7 +925,7 @@ func TestMutateSlices(t *testing.T) {
}
func TestOverlappedPixels(t *testing.T) {
dst := restorable.NewImage(3, 3)
dst := restorable.NewImage(3, 3, restorable.ImageTypeRegular)
pix0 := make([]byte, 4*2*2)
for j := 0; j < 2; j++ {
@ -1070,7 +1069,7 @@ func TestOverlappedPixels(t *testing.T) {
}
func TestReplacePixelsWithMask(t *testing.T) {
dst := restorable.NewImage(3, 3)
dst := restorable.NewImage(3, 3, restorable.ImageTypeRegular)
pix0 := make([]byte, 4*2*2)
for j := 0; j < 2; j++ {

View File

@ -27,7 +27,7 @@ import (
)
func clearImage(img *restorable.Image, w, h int) {
emptyImage := restorable.NewImage(3, 3)
emptyImage := restorable.NewImage(3, 3, restorable.ImageTypeRegular)
defer emptyImage.Dispose()
dx0 := float32(0)
@ -55,7 +55,7 @@ func clearImage(img *restorable.Image, w, h int) {
}
func TestShader(t *testing.T) {
img := restorable.NewImage(1, 1)
img := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
defer img.Dispose()
s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff))
@ -85,7 +85,7 @@ func TestShaderChain(t *testing.T) {
const num = 10
imgs := []*restorable.Image{}
for i := 0; i < num; i++ {
img := restorable.NewImage(1, 1)
img := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
defer img.Dispose()
imgs = append(imgs, img)
}
@ -122,13 +122,13 @@ func TestShaderChain(t *testing.T) {
func TestShaderMultipleSources(t *testing.T) {
var srcs [graphics.ShaderImageNum]*restorable.Image
for i := range srcs {
srcs[i] = restorable.NewImage(1, 1)
srcs[i] = restorable.NewImage(1, 1, restorable.ImageTypeRegular)
}
srcs[0].ReplacePixels([]byte{0x40, 0, 0, 0xff}, nil, 0, 0, 1, 1)
srcs[1].ReplacePixels([]byte{0, 0x80, 0, 0xff}, nil, 0, 0, 1, 1)
srcs[2].ReplacePixels([]byte{0, 0, 0xc0, 0xff}, nil, 0, 0, 1, 1)
dst := restorable.NewImage(1, 1)
dst := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
s := restorable.NewShader(etesting.ShaderProgramImages(3))
var offsets [graphics.ShaderImageNum - 1][2]float32
@ -158,7 +158,7 @@ func TestShaderMultipleSources(t *testing.T) {
}
func TestShaderMultipleSourcesOnOneTexture(t *testing.T) {
src := restorable.NewImage(3, 1)
src := restorable.NewImage(3, 1, restorable.ImageTypeRegular)
src.ReplacePixels([]byte{
0x40, 0, 0, 0xff,
0, 0x80, 0, 0xff,
@ -166,7 +166,7 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) {
}, nil, 0, 0, 3, 1)
srcs := [graphics.ShaderImageNum]*restorable.Image{src, src, src}
dst := restorable.NewImage(1, 1)
dst := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
s := restorable.NewShader(etesting.ShaderProgramImages(3))
offsets := [graphics.ShaderImageNum - 1][2]float32{
@ -199,7 +199,7 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) {
}
func TestShaderDispose(t *testing.T) {
img := restorable.NewImage(1, 1)
img := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
defer img.Dispose()
s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff))