mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 10:42:42 +01:00
internal/restorable: refactoring: replace At with ReadPixels
Updates #1995
This commit is contained in:
parent
7b6ce7dcba
commit
bf5f7ee34d
@ -572,45 +572,20 @@ func (i *Image) replacePixels(pix []byte, x, y, width, height int) {
|
||||
i.backend.restorable.ReplacePixels(pixb, x, y, pw, ph)
|
||||
}
|
||||
|
||||
func (img *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, pixels []byte) error {
|
||||
func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, pixels []byte) error {
|
||||
backendsM.Lock()
|
||||
defer backendsM.Unlock()
|
||||
|
||||
x := img.paddingSize()
|
||||
y := img.paddingSize()
|
||||
|
||||
if got, want := len(pixels), 4*img.width*img.height; got != want {
|
||||
return fmt.Errorf("atlas: len(pixels) must be %d but %d", want, got)
|
||||
}
|
||||
|
||||
idx := 0
|
||||
for j := y; j < y+img.height; j++ {
|
||||
for i := x; i < x+img.width; i++ {
|
||||
r, g, b, a, err := img.at(graphicsDriver, i, j)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pixels[4*idx] = r
|
||||
pixels[4*idx+1] = g
|
||||
pixels[4*idx+2] = b
|
||||
pixels[4*idx+3] = a
|
||||
idx++
|
||||
if i.backend == nil || i.backend.restorable == nil {
|
||||
for i := range pixels {
|
||||
pixels[i] = 0
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Image) at(graphicsDriver graphicsdriver.Graphics, x, y int) (byte, byte, byte, byte, error) {
|
||||
if i.backend == nil {
|
||||
return 0, 0, 0, 0, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
ps := i.paddingSize()
|
||||
ox, oy, w, h := i.regionWithPadding()
|
||||
if x < 0 || y < 0 || x >= w || y >= h {
|
||||
return 0, 0, 0, 0, nil
|
||||
}
|
||||
|
||||
return i.backend.restorable.At(graphicsDriver, x+ox, y+oy)
|
||||
return i.backend.restorable.ReadPixels(graphicsDriver, pixels, ox+ps, oy+ps, w-ps*2, h-ps*2)
|
||||
}
|
||||
|
||||
// MarkDisposed marks the image as disposed. The actual operation is deferred.
|
||||
|
@ -54,13 +54,14 @@ func (p *Pixels) Clear(x, y, width, height int) {
|
||||
p.pixelsRecords.clear(x, y, width, height)
|
||||
}
|
||||
|
||||
func (p *Pixels) At(i, j int) (byte, byte, byte, byte) {
|
||||
if p.pixelsRecords != nil {
|
||||
if r, g, b, a, ok := p.pixelsRecords.at(i, j); ok {
|
||||
return r, g, b, a
|
||||
func (p *Pixels) ReadPixels(pixels []byte, x, y, width, height, imageWidth, imageHeight int) {
|
||||
if p.pixelsRecords == nil {
|
||||
for i := range pixels {
|
||||
pixels[i] = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
return 0, 0, 0, 0
|
||||
p.pixelsRecords.readPixels(pixels, x, y, width, height, imageWidth, imageHeight)
|
||||
}
|
||||
|
||||
// drawTrianglesHistoryItem is an item for history of draw-image commands.
|
||||
@ -447,20 +448,15 @@ func (i *Image) readPixelsFromGPUIfNeeded(graphicsDriver graphicsdriver.Graphics
|
||||
return nil
|
||||
}
|
||||
|
||||
// At returns a color value at (x, y).
|
||||
//
|
||||
// Note that this must not be called until context is available.
|
||||
func (i *Image) At(graphicsDriver graphicsdriver.Graphics, x, y int) (byte, byte, byte, byte, error) {
|
||||
if x < 0 || y < 0 || i.width <= x || i.height <= y {
|
||||
return 0, 0, 0, 0, nil
|
||||
}
|
||||
|
||||
func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, pixels []byte, x, y, width, height int) error {
|
||||
if err := i.readPixelsFromGPUIfNeeded(graphicsDriver); err != nil {
|
||||
return 0, 0, 0, 0, err
|
||||
return err
|
||||
}
|
||||
|
||||
r, g, b, a := i.basePixels.At(x, y)
|
||||
return r, g, b, a, nil
|
||||
if got, want := len(pixels), 4*width*height; got != want {
|
||||
return fmt.Errorf("restorable: len(pixels) must be %d but %d at ReadPixels", want, got)
|
||||
}
|
||||
i.basePixels.ReadPixels(pixels, x, y, width, height, i.width, i.height)
|
||||
return nil
|
||||
}
|
||||
|
||||
// makeStaleIfDependingOn makes the image stale if the image depends on target.
|
||||
|
@ -32,9 +32,10 @@ func TestMain(m *testing.M) {
|
||||
etesting.MainWithRunLoop(m)
|
||||
}
|
||||
|
||||
func pixelsToColor(p *restorable.Pixels, i, j int) color.RGBA {
|
||||
r, g, b, a := p.At(i, j)
|
||||
return color.RGBA{r, g, b, a}
|
||||
func pixelsToColor(p *restorable.Pixels, i, j, imageWidth, imageHeight int) color.RGBA {
|
||||
var pix [4]byte
|
||||
p.ReadPixels(pix[:], i, j, 1, 1, imageWidth, imageHeight)
|
||||
return color.RGBA{pix[0], pix[1], pix[2], pix[3]}
|
||||
}
|
||||
|
||||
func abs(x int) int {
|
||||
@ -69,7 +70,7 @@ func TestRestore(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := clr0
|
||||
got := pixelsToColor(img0.BasePixelsForTesting(), 0, 0)
|
||||
got := pixelsToColor(img0.BasePixelsForTesting(), 0, 0, 1, 1)
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
@ -91,7 +92,7 @@ func TestRestoreWithoutDraw(t *testing.T) {
|
||||
for j := 0; j < 1024; j++ {
|
||||
for i := 0; i < 1024; i++ {
|
||||
want := color.RGBA{0x00, 0x00, 0x00, 0x00}
|
||||
got := pixelsToColor(img0.BasePixelsForTesting(), i, j)
|
||||
got := pixelsToColor(img0.BasePixelsForTesting(), i, j, 1024, 1024)
|
||||
if !sameColors(got, want, 0) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
@ -155,7 +156,7 @@ func TestRestoreChain(t *testing.T) {
|
||||
}
|
||||
want := clr
|
||||
for i, img := range imgs {
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0)
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0, 1, 1)
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("%d: got %v, want %v", i, got, want)
|
||||
}
|
||||
@ -210,7 +211,7 @@ func TestRestoreChain2(t *testing.T) {
|
||||
if i == 8 || i == 9 {
|
||||
want = clr7
|
||||
}
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0)
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0, w, h)
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("%d: got %v, want %v", i, got, want)
|
||||
}
|
||||
@ -260,22 +261,22 @@ func TestRestoreOverrideSource(t *testing.T) {
|
||||
{
|
||||
"0",
|
||||
clr1,
|
||||
pixelsToColor(img0.BasePixelsForTesting(), 0, 0),
|
||||
pixelsToColor(img0.BasePixelsForTesting(), 0, 0, w, h),
|
||||
},
|
||||
{
|
||||
"1",
|
||||
clr1,
|
||||
pixelsToColor(img1.BasePixelsForTesting(), 0, 0),
|
||||
pixelsToColor(img1.BasePixelsForTesting(), 0, 0, w, h),
|
||||
},
|
||||
{
|
||||
"2",
|
||||
clr0,
|
||||
pixelsToColor(img2.BasePixelsForTesting(), 0, 0),
|
||||
pixelsToColor(img2.BasePixelsForTesting(), 0, 0, w, h),
|
||||
},
|
||||
{
|
||||
"3",
|
||||
clr0,
|
||||
pixelsToColor(img3.BasePixelsForTesting(), 0, 0),
|
||||
pixelsToColor(img3.BasePixelsForTesting(), 0, 0, w, h),
|
||||
},
|
||||
}
|
||||
for _, c := range testCases {
|
||||
@ -406,7 +407,7 @@ func TestRestoreComplexGraph(t *testing.T) {
|
||||
if c.out[i] == '*' {
|
||||
want = color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||
}
|
||||
got := pixelsToColor(c.image.BasePixelsForTesting(), i, 0)
|
||||
got := pixelsToColor(c.image.BasePixelsForTesting(), i, 0, w, h)
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("%s[%d]: got %v, want %v", c.name, i, got, want)
|
||||
}
|
||||
@ -475,7 +476,7 @@ func TestRestoreRecursive(t *testing.T) {
|
||||
if c.out[i] == '*' {
|
||||
want = color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||
}
|
||||
got := pixelsToColor(c.image.BasePixelsForTesting(), i, 0)
|
||||
got := pixelsToColor(c.image.BasePixelsForTesting(), i, 0, w, h)
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("%s[%d]: got %v, want %v", c.name, i, got, want)
|
||||
}
|
||||
@ -493,16 +494,19 @@ func TestReplacePixels(t *testing.T) {
|
||||
}
|
||||
img.ReplacePixels(pix, 5, 7, 4, 4)
|
||||
// Check the region (5, 7)-(9, 11). Outside state is indeterministic.
|
||||
for i := range pix {
|
||||
pix[i] = 0
|
||||
}
|
||||
if err := img.ReadPixels(ui.GraphicsDriverForTesting(), pix, 5, 7, 4, 4); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 7; j < 11; j++ {
|
||||
for i := 5; i < 9; i++ {
|
||||
r, g, b, a, err := img.At(ui.GraphicsDriverForTesting(), i, j)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := color.RGBA{r, g, b, a}
|
||||
idx := 4 * ((j-7)*4 + i - 5)
|
||||
got := color.RGBA{pix[idx], pix[idx+1], pix[idx+2], pix[idx+3]}
|
||||
want := color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||
if got != want {
|
||||
t.Errorf("img.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||
t.Errorf("(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -512,16 +516,16 @@ func TestReplacePixels(t *testing.T) {
|
||||
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := img.ReadPixels(ui.GraphicsDriverForTesting(), pix, 5, 7, 4, 4); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 7; j < 11; j++ {
|
||||
for i := 5; i < 9; i++ {
|
||||
r, g, b, a, err := img.At(ui.GraphicsDriverForTesting(), i, j)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := color.RGBA{r, g, b, a}
|
||||
idx := 4 * ((j-7)*4 + i - 5)
|
||||
got := color.RGBA{pix[idx], pix[idx+1], pix[idx+2], pix[idx+3]}
|
||||
want := color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||
if got != want {
|
||||
t.Errorf("img.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||
t.Errorf("(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -555,11 +559,11 @@ func TestDrawTrianglesAndReplacePixels(t *testing.T) {
|
||||
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, g, b, a, err := img1.At(ui.GraphicsDriverForTesting(), 0, 0)
|
||||
if err != nil {
|
||||
var pix [4]byte
|
||||
if err := img1.ReadPixels(ui.GraphicsDriverForTesting(), pix[:], 0, 0, 1, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := color.RGBA{r, g, b, a}
|
||||
got := color.RGBA{pix[0], pix[1], pix[2], pix[3]}
|
||||
want := color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
@ -599,11 +603,11 @@ func TestDispose(t *testing.T) {
|
||||
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, g, b, a, err := img0.At(ui.GraphicsDriverForTesting(), 0, 0)
|
||||
if err != nil {
|
||||
var pix [4]byte
|
||||
if err := img0.ReadPixels(ui.GraphicsDriverForTesting(), pix[:], 0, 0, 1, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := color.RGBA{r, g, b, a}
|
||||
got := color.RGBA{pix[0], pix[1], pix[2], pix[3]}
|
||||
want := color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
@ -677,7 +681,7 @@ func TestReplacePixelsPart(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), c.i, c.j)
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), c.i, c.j, 4, 4)
|
||||
want := c.want
|
||||
if got != want {
|
||||
t.Errorf("base pixel (%d, %d): got %v, want %v", c.i, c.j, got, want)
|
||||
@ -718,7 +722,7 @@ func TestReplacePixelsOnly(t *testing.T) {
|
||||
case idx%5 == 0:
|
||||
want = color.RGBA{1, 2, 3, 4}
|
||||
}
|
||||
got := pixelsToColor(img0.BasePixelsForTesting(), i, j)
|
||||
got := pixelsToColor(img0.BasePixelsForTesting(), i, j, w, h)
|
||||
if !sameColors(got, want, 0) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
@ -732,7 +736,7 @@ func TestReplacePixelsOnly(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := color.RGBA{1, 2, 3, 4}
|
||||
got := pixelsToColor(img1.BasePixelsForTesting(), 0, 0)
|
||||
got := pixelsToColor(img1.BasePixelsForTesting(), 0, 0, w, h)
|
||||
if !sameColors(got, want, 0) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
@ -768,10 +772,12 @@ func TestReadPixelsFromVolatileImage(t *testing.T) {
|
||||
// Read the pixels. If the implementation is correct, dst tries to read its pixels from GPU due to being
|
||||
// stale.
|
||||
want := byte(0xff)
|
||||
got, _, _, _, err := dst.At(ui.GraphicsDriverForTesting(), 0, 0)
|
||||
if err != nil {
|
||||
|
||||
var result [4]byte
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result[:], 0, 0, 1, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := result[0]
|
||||
if got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
@ -840,12 +846,13 @@ func TestExtend(t *testing.T) {
|
||||
orig.ReplacePixels(pix, 0, 0, w, h)
|
||||
extended := orig.Extend(w*2, h*2) // After this, orig is already disposed.
|
||||
|
||||
result := make([]byte, 4*(w*2)*(h*2))
|
||||
if err := extended.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, w*2, h*2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < h*2; j++ {
|
||||
for i := 0; i < w*2; i++ {
|
||||
got, _, _, _, err := extended.At(ui.GraphicsDriverForTesting(), i, j)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := result[4*(j*(w*2)+i)]
|
||||
want := byte(0)
|
||||
if i < w && j < h {
|
||||
want = pixAt(i, j)
|
||||
@ -905,18 +912,20 @@ func TestMutateSlices(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
srcPix := make([]byte, 4*w*h)
|
||||
if err := src.ReadPixels(ui.GraphicsDriverForTesting(), srcPix, 0, 0, w, h); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dstPix := make([]byte, 4*w*h)
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), dstPix, 0, 0, w, h); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for j := 0; j < h; j++ {
|
||||
for i := 0; i < w; i++ {
|
||||
r, g, b, a, err := src.At(ui.GraphicsDriverForTesting(), i, j)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := color.RGBA{r, g, b, a}
|
||||
r, g, b, a, err = dst.At(ui.GraphicsDriverForTesting(), i, j)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := color.RGBA{r, g, b, a}
|
||||
idx := 4 * (j*w + i)
|
||||
want := color.RGBA{srcPix[idx], srcPix[idx+1], srcPix[idx+2], srcPix[idx+3]}
|
||||
got := color.RGBA{dstPix[idx], dstPix[idx+1], dstPix[idx+2], dstPix[idx+3]}
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("(%d, %d): got %v, want %v", i, j, got, want)
|
||||
}
|
||||
@ -964,13 +973,15 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
{0, 0xff, 0, 0xff},
|
||||
{0, 0xff, 0, 0xff},
|
||||
}
|
||||
|
||||
result := make([]byte, 4*3*3)
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, 3, 3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < 3; j++ {
|
||||
for i := 0; i < 3; i++ {
|
||||
r, g, b, a, err := dst.At(ui.GraphicsDriverForTesting(), i, j)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := color.RGBA{r, g, b, a}
|
||||
idx := 4 * (j*3 + i)
|
||||
got := color.RGBA{result[idx], result[idx+1], result[idx+2], result[idx+3]}
|
||||
want := wantColors[3*j+i]
|
||||
if got != want {
|
||||
t.Errorf("color at (%d, %d): got %v, want: %v", i, j, got, want)
|
||||
@ -993,13 +1004,13 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
{0, 0xff, 0, 0xff},
|
||||
{0, 0xff, 0, 0xff},
|
||||
}
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, 3, 3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < 3; j++ {
|
||||
for i := 0; i < 3; i++ {
|
||||
r, g, b, a, err := dst.At(ui.GraphicsDriverForTesting(), i, j)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := color.RGBA{r, g, b, a}
|
||||
idx := 4 * (j*3 + i)
|
||||
got := color.RGBA{result[idx], result[idx+1], result[idx+2], result[idx+3]}
|
||||
want := wantColors[3*j+i]
|
||||
if got != want {
|
||||
t.Errorf("color at (%d, %d): got %v, want: %v", i, j, got, want)
|
||||
@ -1032,13 +1043,13 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
{0, 0, 0xff, 0xff},
|
||||
{0, 0, 0xff, 0xff},
|
||||
}
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, 3, 3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < 3; j++ {
|
||||
for i := 0; i < 3; i++ {
|
||||
r, g, b, a, err := dst.At(ui.GraphicsDriverForTesting(), i, j)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := color.RGBA{r, g, b, a}
|
||||
idx := 4 * (j*3 + i)
|
||||
got := color.RGBA{result[idx], result[idx+1], result[idx+2], result[idx+3]}
|
||||
want := wantColors[3*j+i]
|
||||
if got != want {
|
||||
t.Errorf("color at (%d, %d): got %v, want: %v", i, j, got, want)
|
||||
@ -1053,13 +1064,13 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, 3, 3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < 3; j++ {
|
||||
for i := 0; i < 3; i++ {
|
||||
r, g, b, a, err := dst.At(ui.GraphicsDriverForTesting(), i, j)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := color.RGBA{r, g, b, a}
|
||||
idx := 4 * (j*3 + i)
|
||||
got := color.RGBA{result[idx], result[idx+1], result[idx+2], result[idx+3]}
|
||||
want := wantColors[3*j+i]
|
||||
if got != want {
|
||||
t.Errorf("color at (%d, %d): got %v, want: %v", i, j, got, want)
|
||||
|
@ -42,12 +42,22 @@ func (p *pixelsRecord) clearIfOverlapped(rect image.Rectangle) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *pixelsRecord) at(x, y int) (r, g, b, a byte, ok bool) {
|
||||
if !image.Pt(x, y).In(p.rect) {
|
||||
return 0, 0, 0, 0, false
|
||||
func (p *pixelsRecord) readPixels(pixels []byte, x, y, width, height, imageWidth, imageHeight int) {
|
||||
r := p.rect.Intersect(image.Rect(x, y, x+width, y+height)).Intersect(image.Rect(0, 0, imageWidth, imageHeight))
|
||||
if r.Empty() {
|
||||
return
|
||||
}
|
||||
|
||||
dstBaseX := r.Min.X - x
|
||||
dstBaseY := r.Min.Y - y
|
||||
srcBaseX := r.Min.X - p.rect.Min.X
|
||||
srcBaseY := r.Min.Y - p.rect.Min.Y
|
||||
lineWidth := 4 * r.Dx()
|
||||
for j := 0; j < r.Dy(); j++ {
|
||||
dstX := 4 * ((dstBaseY+j)*width + dstBaseX)
|
||||
srcX := 4 * ((srcBaseY+j)*p.rect.Dx() + srcBaseX)
|
||||
copy(pixels[dstX:dstX+lineWidth], p.pix[srcX:srcX+lineWidth])
|
||||
}
|
||||
idx := ((y-p.rect.Min.Y)*p.rect.Dx() + (x - p.rect.Min.X))
|
||||
return p.pix[4*idx], p.pix[4*idx+1], p.pix[4*idx+2], p.pix[4*idx+3], true
|
||||
}
|
||||
|
||||
type pixelsRecords struct {
|
||||
@ -103,16 +113,13 @@ func (pr *pixelsRecords) clear(x, y, width, height int) {
|
||||
pr.records = pr.records[:n]
|
||||
}
|
||||
|
||||
func (pr *pixelsRecords) at(i, j int) (r, g, b, a byte, ok bool) {
|
||||
// Traverse the slice in the reversed order.
|
||||
for idx := len(pr.records) - 1; idx >= 0; idx-- {
|
||||
r, g, b, a, ok := pr.records[idx].at(i, j)
|
||||
if ok {
|
||||
return r, g, b, a, true
|
||||
}
|
||||
func (pr *pixelsRecords) readPixels(pixels []byte, x, y, width, height, imageWidth, imageHeight int) {
|
||||
for i := range pixels {
|
||||
pixels[i] = 0
|
||||
}
|
||||
for _, r := range pr.records {
|
||||
r.readPixels(pixels, x, y, width, height, imageWidth, imageHeight)
|
||||
}
|
||||
|
||||
return 0, 0, 0, 0, false
|
||||
}
|
||||
|
||||
func (pr *pixelsRecords) apply(img *graphicscommand.Image) {
|
||||
|
@ -75,7 +75,7 @@ func TestShader(t *testing.T) {
|
||||
}
|
||||
|
||||
want := color.RGBA{0xff, 0, 0, 0xff}
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0)
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0, 1, 1)
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
@ -112,7 +112,7 @@ func TestShaderChain(t *testing.T) {
|
||||
|
||||
for i, img := range imgs {
|
||||
want := color.RGBA{0xff, 0, 0, 0xff}
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0)
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0, 1, 1)
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("%d: got %v, want %v", i, got, want)
|
||||
}
|
||||
@ -151,7 +151,7 @@ func TestShaderMultipleSources(t *testing.T) {
|
||||
}
|
||||
|
||||
want := color.RGBA{0x40, 0x80, 0xc0, 0xff}
|
||||
got := pixelsToColor(dst.BasePixelsForTesting(), 0, 0)
|
||||
got := pixelsToColor(dst.BasePixelsForTesting(), 0, 0, 1, 1)
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
@ -192,7 +192,7 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) {
|
||||
}
|
||||
|
||||
want := color.RGBA{0x40, 0x80, 0xc0, 0xff}
|
||||
got := pixelsToColor(dst.BasePixelsForTesting(), 0, 0)
|
||||
got := pixelsToColor(dst.BasePixelsForTesting(), 0, 0, 1, 1)
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
@ -223,7 +223,7 @@ func TestShaderDispose(t *testing.T) {
|
||||
}
|
||||
|
||||
want := color.RGBA{0xff, 0, 0, 0xff}
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0)
|
||||
got := pixelsToColor(img.BasePixelsForTesting(), 0, 0, 1, 1)
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user