mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-26 03:38:55 +01:00
restorable: Refactoring: Use width/height instead of length at Pixels
This commit is contained in:
parent
efb6f9c453
commit
b4dddd330a
@ -28,7 +28,8 @@ import (
|
|||||||
type Pixels struct {
|
type Pixels struct {
|
||||||
pixels []byte
|
pixels []byte
|
||||||
|
|
||||||
length int
|
width int
|
||||||
|
height int
|
||||||
|
|
||||||
// color is used only when pixels == nil
|
// color is used only when pixels == nil
|
||||||
color color.RGBA
|
color color.RGBA
|
||||||
@ -36,30 +37,23 @@ type Pixels struct {
|
|||||||
|
|
||||||
func (p *Pixels) CopyFrom(pix []byte, from int) {
|
func (p *Pixels) CopyFrom(pix []byte, from int) {
|
||||||
if p.pixels == nil {
|
if p.pixels == nil {
|
||||||
p.pixels = make([]byte, p.length)
|
p.pixels = make([]byte, 4*p.width*p.height)
|
||||||
}
|
}
|
||||||
copy(p.pixels[from:from+len(pix)], pix)
|
copy(p.pixels[from:from+len(pix)], pix)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pixels) At(i int) byte {
|
func (p *Pixels) At(i, j int) (byte, byte, byte, byte) {
|
||||||
if i < 0 || p.length <= i {
|
if i < 0 || p.width <= i {
|
||||||
panic(fmt.Sprintf("restorable: index out of range: %d for length: %d", i, p.length))
|
panic(fmt.Sprintf("restorable: index out of range: %d for the width: %d", i, p.width))
|
||||||
|
}
|
||||||
|
if j < 0 || p.height <= j {
|
||||||
|
panic(fmt.Sprintf("restorable: index out of range: %d for the height: %d", i, p.height))
|
||||||
}
|
}
|
||||||
if p.pixels != nil {
|
if p.pixels != nil {
|
||||||
return p.pixels[i]
|
idx := 4 * (j*p.width + i)
|
||||||
}
|
return p.pixels[idx], p.pixels[idx+1], p.pixels[idx+2], p.pixels[idx+3]
|
||||||
switch i % 4 {
|
|
||||||
case 0:
|
|
||||||
return p.color.R
|
|
||||||
case 1:
|
|
||||||
return p.color.G
|
|
||||||
case 2:
|
|
||||||
return p.color.B
|
|
||||||
case 3:
|
|
||||||
return p.color.A
|
|
||||||
default:
|
|
||||||
panic("not reached")
|
|
||||||
}
|
}
|
||||||
|
return p.color.R, p.color.G, p.color.B, p.color.A
|
||||||
}
|
}
|
||||||
|
|
||||||
// drawTrianglesHistoryItem is an item for history of draw-image commands.
|
// drawTrianglesHistoryItem is an item for history of draw-image commands.
|
||||||
@ -165,7 +159,8 @@ func (i *Image) Extend(width, height int) *Image {
|
|||||||
// Copy basePixels.
|
// Copy basePixels.
|
||||||
newImg.basePixels = &Pixels{
|
newImg.basePixels = &Pixels{
|
||||||
pixels: make([]byte, 4*width*height),
|
pixels: make([]byte, 4*width*height),
|
||||||
length: 4 * width * height,
|
width: width,
|
||||||
|
height: height,
|
||||||
}
|
}
|
||||||
pix := i.basePixels.pixels
|
pix := i.basePixels.pixels
|
||||||
idx := 0
|
idx := 0
|
||||||
@ -258,7 +253,8 @@ func (i *Image) fill(r, g, b, a byte) {
|
|||||||
w, h := i.Size()
|
w, h := i.Size()
|
||||||
i.basePixels = &Pixels{
|
i.basePixels = &Pixels{
|
||||||
color: color.RGBA{r, g, b, a},
|
color: color.RGBA{r, g, b, a},
|
||||||
length: 4 * w * h,
|
width: w,
|
||||||
|
height: h,
|
||||||
}
|
}
|
||||||
i.drawTrianglesHistory = nil
|
i.drawTrianglesHistory = nil
|
||||||
i.stale = false
|
i.stale = false
|
||||||
@ -349,7 +345,8 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
|||||||
if x == 0 && y == 0 && width == w && height == h {
|
if x == 0 && y == 0 && width == w && height == h {
|
||||||
if i.basePixels == nil {
|
if i.basePixels == nil {
|
||||||
i.basePixels = &Pixels{
|
i.basePixels = &Pixels{
|
||||||
length: 4 * w * h,
|
width: w,
|
||||||
|
height: h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i.basePixels.CopyFrom(pixels, 0)
|
i.basePixels.CopyFrom(pixels, 0)
|
||||||
@ -378,7 +375,8 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
|||||||
idx := 4 * (y*w + x)
|
idx := 4 * (y*w + x)
|
||||||
if i.basePixels == nil {
|
if i.basePixels == nil {
|
||||||
i.basePixels = &Pixels{
|
i.basePixels = &Pixels{
|
||||||
length: 4 * w * h,
|
width: w,
|
||||||
|
height: h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for j := 0; j < height; j++ {
|
for j := 0; j < height; j++ {
|
||||||
@ -455,8 +453,7 @@ func (i *Image) At(x, y int) (byte, byte, byte, byte) {
|
|||||||
return 0, 0, 0, 0
|
return 0, 0, 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
idx := 4*x + 4*y*w
|
return i.basePixels.At(x, y)
|
||||||
return i.basePixels.At(idx), i.basePixels.At(idx + 1), i.basePixels.At(idx + 2), i.basePixels.At(idx + 3)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeStaleIfDependingOn makes the image stale if the image depends on target.
|
// makeStaleIfDependingOn makes the image stale if the image depends on target.
|
||||||
@ -471,10 +468,12 @@ func (i *Image) makeStaleIfDependingOn(target *Image) {
|
|||||||
|
|
||||||
// readPixelsFromGPU reads the pixels from GPU and resolves the image's 'stale' state.
|
// readPixelsFromGPU reads the pixels from GPU and resolves the image's 'stale' state.
|
||||||
func (i *Image) readPixelsFromGPU() {
|
func (i *Image) readPixelsFromGPU() {
|
||||||
|
w, h := i.Size()
|
||||||
pix := i.image.Pixels()
|
pix := i.image.Pixels()
|
||||||
i.basePixels = &Pixels{
|
i.basePixels = &Pixels{
|
||||||
pixels: pix,
|
pixels: pix,
|
||||||
length: len(pix),
|
width: w,
|
||||||
|
height: h,
|
||||||
}
|
}
|
||||||
i.drawTrianglesHistory = nil
|
i.drawTrianglesHistory = nil
|
||||||
i.stale = false
|
i.stale = false
|
||||||
@ -578,7 +577,8 @@ func (i *Image) restore() error {
|
|||||||
pix := gimg.Pixels()
|
pix := gimg.Pixels()
|
||||||
i.basePixels = &Pixels{
|
i.basePixels = &Pixels{
|
||||||
pixels: pix,
|
pixels: pix,
|
||||||
length: len(pix),
|
width: w,
|
||||||
|
height: h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,9 +45,9 @@ func TestMain(m *testing.M) {
|
|||||||
os.Exit(code)
|
os.Exit(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pixelsToColor(p *Pixels, index int) color.RGBA {
|
func pixelsToColor(p *Pixels, i, j int) color.RGBA {
|
||||||
i := index * 4
|
r, g, b, a := p.At(i, j)
|
||||||
return color.RGBA{p.At(i), p.At(i + 1), p.At(i + 2), p.At(i + 3)}
|
return color.RGBA{r, g, b, a}
|
||||||
}
|
}
|
||||||
|
|
||||||
func abs(x int) int {
|
func abs(x int) int {
|
||||||
@ -80,7 +80,7 @@ func TestRestore(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
want := clr0
|
want := clr0
|
||||||
got := pixelsToColor(img0.BasePixelsForTesting(), 0)
|
got := pixelsToColor(img0.BasePixelsForTesting(), 0, 0)
|
||||||
if !sameColors(got, want, 1) {
|
if !sameColors(got, want, 1) {
|
||||||
t.Errorf("got %v, want %v", got, want)
|
t.Errorf("got %v, want %v", got, want)
|
||||||
}
|
}
|
||||||
@ -97,11 +97,13 @@ func TestRestoreWithoutDraw(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 1024*1024; i++ {
|
for j := 0; j < 1024; j++ {
|
||||||
want := color.RGBA{0x00, 0x00, 0x00, 0x00}
|
for i := 0; i < 1024; i++ {
|
||||||
got := pixelsToColor(img0.BasePixelsForTesting(), i)
|
want := color.RGBA{0x00, 0x00, 0x00, 0x00}
|
||||||
if !sameColors(got, want, 0) {
|
got := pixelsToColor(img0.BasePixelsForTesting(), i, j)
|
||||||
t.Errorf("got %v, want %v", got, want)
|
if !sameColors(got, want, 0) {
|
||||||
|
t.Errorf("got %v, want %v", got, want)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,7 +141,7 @@ func TestRestoreChain(t *testing.T) {
|
|||||||
}
|
}
|
||||||
want := clr
|
want := clr
|
||||||
for i, img := range imgs {
|
for i, img := range imgs {
|
||||||
got := pixelsToColor(img.BasePixelsForTesting(), 0)
|
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0)
|
||||||
if !sameColors(got, want, 1) {
|
if !sameColors(got, want, 1) {
|
||||||
t.Errorf("%d: got %v, want %v", i, got, want)
|
t.Errorf("%d: got %v, want %v", i, got, want)
|
||||||
}
|
}
|
||||||
@ -186,7 +188,7 @@ func TestRestoreChain2(t *testing.T) {
|
|||||||
if i == 8 || i == 9 {
|
if i == 8 || i == 9 {
|
||||||
want = clr7
|
want = clr7
|
||||||
}
|
}
|
||||||
got := pixelsToColor(img.BasePixelsForTesting(), 0)
|
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0)
|
||||||
if !sameColors(got, want, 1) {
|
if !sameColors(got, want, 1) {
|
||||||
t.Errorf("%d: got %v, want %v", i, got, want)
|
t.Errorf("%d: got %v, want %v", i, got, want)
|
||||||
}
|
}
|
||||||
@ -228,22 +230,22 @@ func TestRestoreOverrideSource(t *testing.T) {
|
|||||||
{
|
{
|
||||||
"0",
|
"0",
|
||||||
clr1,
|
clr1,
|
||||||
pixelsToColor(img0.BasePixelsForTesting(), 0),
|
pixelsToColor(img0.BasePixelsForTesting(), 0, 0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"1",
|
"1",
|
||||||
clr1,
|
clr1,
|
||||||
pixelsToColor(img1.BasePixelsForTesting(), 0),
|
pixelsToColor(img1.BasePixelsForTesting(), 0, 0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"2",
|
"2",
|
||||||
clr0,
|
clr0,
|
||||||
pixelsToColor(img2.BasePixelsForTesting(), 0),
|
pixelsToColor(img2.BasePixelsForTesting(), 0, 0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"3",
|
"3",
|
||||||
clr0,
|
clr0,
|
||||||
pixelsToColor(img3.BasePixelsForTesting(), 0),
|
pixelsToColor(img3.BasePixelsForTesting(), 0, 0),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, c := range testCases {
|
for _, c := range testCases {
|
||||||
@ -365,7 +367,7 @@ func TestRestoreComplexGraph(t *testing.T) {
|
|||||||
if c.out[i] == '*' {
|
if c.out[i] == '*' {
|
||||||
want = color.RGBA{0xff, 0xff, 0xff, 0xff}
|
want = color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||||
}
|
}
|
||||||
got := pixelsToColor(c.image.BasePixelsForTesting(), i)
|
got := pixelsToColor(c.image.BasePixelsForTesting(), i, 0)
|
||||||
if !sameColors(got, want, 1) {
|
if !sameColors(got, want, 1) {
|
||||||
t.Errorf("%s[%d]: got %v, want %v", c.name, i, got, want)
|
t.Errorf("%s[%d]: got %v, want %v", c.name, i, got, want)
|
||||||
}
|
}
|
||||||
@ -426,7 +428,7 @@ func TestRestoreRecursive(t *testing.T) {
|
|||||||
if c.out[i] == '*' {
|
if c.out[i] == '*' {
|
||||||
want = color.RGBA{0xff, 0xff, 0xff, 0xff}
|
want = color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||||
}
|
}
|
||||||
got := pixelsToColor(c.image.BasePixelsForTesting(), i)
|
got := pixelsToColor(c.image.BasePixelsForTesting(), i, 0)
|
||||||
if !sameColors(got, want, 1) {
|
if !sameColors(got, want, 1) {
|
||||||
t.Errorf("%s[%d]: got %v, want %v", c.name, i, got, want)
|
t.Errorf("%s[%d]: got %v, want %v", c.name, i, got, want)
|
||||||
}
|
}
|
||||||
@ -543,55 +545,66 @@ func TestClear(t *testing.T) {
|
|||||||
img.ReplacePixels(make([]byte, 4*4*4), 1, 1, 2, 2)
|
img.ReplacePixels(make([]byte, 4*4*4), 1, 1, 2, 2)
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
Index int
|
i int
|
||||||
Want color.RGBA
|
j int
|
||||||
|
want color.RGBA
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Index: 0,
|
i: 0,
|
||||||
Want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
j: 0,
|
||||||
|
want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Index: 3,
|
i: 3,
|
||||||
Want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
j: 0,
|
||||||
|
want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Index: 4,
|
i: 0,
|
||||||
Want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
j: 1,
|
||||||
|
want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Index: 5,
|
i: 1,
|
||||||
Want: color.RGBA{0, 0, 0, 0},
|
j: 1,
|
||||||
|
want: color.RGBA{0, 0, 0, 0},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Index: 7,
|
i: 3,
|
||||||
Want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
j: 1,
|
||||||
|
want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Index: 8,
|
i: 0,
|
||||||
Want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
j: 2,
|
||||||
|
want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Index: 10,
|
i: 2,
|
||||||
Want: color.RGBA{0, 0, 0, 0},
|
j: 2,
|
||||||
|
want: color.RGBA{0, 0, 0, 0},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Index: 11,
|
i: 3,
|
||||||
Want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
j: 2,
|
||||||
|
want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Index: 12,
|
i: 0,
|
||||||
Want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
j: 3,
|
||||||
|
want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Index: 15,
|
i: 3,
|
||||||
Want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
j: 3,
|
||||||
|
want: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
got := pixelsToColor(img.BasePixelsForTesting(), c.Index)
|
got := pixelsToColor(img.BasePixelsForTesting(), c.i, c.j)
|
||||||
want := c.Want
|
want := c.want
|
||||||
if got != want {
|
if got != want {
|
||||||
t.Errorf("base pixel [%d]: got %v, want %v", c.Index, got, want)
|
t.Errorf("base pixel (%d, %d): got %v, want %v", c.i, c.j, got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -613,17 +626,20 @@ func TestReplacePixelsOnly(t *testing.T) {
|
|||||||
img0.ReplacePixels([]byte{5, 6, 7, 8}, 0, 0, 1, 1)
|
img0.ReplacePixels([]byte{5, 6, 7, 8}, 0, 0, 1, 1)
|
||||||
|
|
||||||
// BasePixelsForTesting is available without GPU accessing.
|
// BasePixelsForTesting is available without GPU accessing.
|
||||||
for i := 0; i < w*h; i++ {
|
for j := 0; j < h; j++ {
|
||||||
var want color.RGBA
|
for i := 0; i < w; i++ {
|
||||||
switch {
|
idx := j*w + i
|
||||||
case i == 0:
|
var want color.RGBA
|
||||||
want = color.RGBA{5, 6, 7, 8}
|
switch {
|
||||||
case i%5 == 0:
|
case idx == 0:
|
||||||
want = color.RGBA{1, 2, 3, 4}
|
want = color.RGBA{5, 6, 7, 8}
|
||||||
}
|
case idx%5 == 0:
|
||||||
got := pixelsToColor(img0.BasePixelsForTesting(), i)
|
want = color.RGBA{1, 2, 3, 4}
|
||||||
if !sameColors(got, want, 0) {
|
}
|
||||||
t.Errorf("got %v, want %v", got, want)
|
got := pixelsToColor(img0.BasePixelsForTesting(), i, j)
|
||||||
|
if !sameColors(got, want, 0) {
|
||||||
|
t.Errorf("got %v, want %v", got, want)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,7 +648,7 @@ func TestReplacePixelsOnly(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
want := color.RGBA{1, 2, 3, 4}
|
want := color.RGBA{1, 2, 3, 4}
|
||||||
got := pixelsToColor(img1.BasePixelsForTesting(), 0)
|
got := pixelsToColor(img1.BasePixelsForTesting(), 0, 0)
|
||||||
if !sameColors(got, want, 0) {
|
if !sameColors(got, want, 0) {
|
||||||
t.Errorf("got %v, want %v", got, want)
|
t.Errorf("got %v, want %v", got, want)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user