ebiten: remove returning error from ReadPixels

- As ReadPixels should often be used at Draw, error handling would be hard.
- Make the API consistent with ReplacePixels.

Updates #1995
This commit is contained in:
Hajime Hoshi 2022-08-08 02:48:23 +09:00
parent 39790c257b
commit ea04e2a9de
3 changed files with 12 additions and 21 deletions

View File

@ -787,31 +787,29 @@ func (i *Image) ColorModel() color.Model {
// //
// ReadPixels always sets a transparent color if the image is disposed. // ReadPixels always sets a transparent color if the image is disposed.
// //
// ReadPixels returns an error when an error occurs during reading pixels from GPU. // len(pixels) must be 4*width*height. If the sizes don't match, ReadPixels panics.
//
// len(pixels) must be 4*width*height. If the sizes don't match, ReadPixels returns an error.
// //
// Note that an important logic should not rely on values returned by ReadPixels, since // Note that an important logic should not rely on values returned by ReadPixels, since
// the returned values can include very slight differences between some machines. // the returned values can include very slight differences between some machines.
// //
// ReadPixels can't be called outside the main loop (ebiten.Run's updating function) starts. // ReadPixels can't be called outside the main loop (ebiten.Run's updating function) starts.
func (i *Image) ReadPixels(pixels []byte) error { func (i *Image) ReadPixels(pixels []byte) {
b := i.Bounds() b := i.Bounds()
if got, want := len(pixels), 4*b.Dx()*b.Dy(); got != want { if got, want := len(pixels), 4*b.Dx()*b.Dy(); got != want {
return fmt.Errorf("ebiten: len(pixels) must be %d but %d at ReadPixels", want, got) panic(fmt.Sprintf("ebiten: len(pixels) must be %d but %d at ReadPixels", want, got))
} }
if i.isDisposed() { if i.isDisposed() {
for i := range pixels { for i := range pixels {
pixels[i] = 0 pixels[i] = 0
} }
return nil return
} }
i.resolveSetVerticesCacheIfNeeded() i.resolveSetVerticesCacheIfNeeded()
x, y := i.adjustPosition(b.Min.X, b.Min.Y) x, y := i.adjustPosition(b.Min.X, b.Min.Y)
return i.image.ReadPixels(pixels, x, y, b.Dx(), b.Dy()) i.image.ReadPixels(pixels, x, y, b.Dx(), b.Dy())
} }
// At returns the color of the image at (x, y). // At returns the color of the image at (x, y).
@ -858,7 +856,9 @@ func (i *Image) at(x, y int) (r, g, b, a byte) {
if c, ok := i.setVerticesCache[[2]int{x, y}]; ok { if c, ok := i.setVerticesCache[[2]int{x, y}]; ok {
return c[0], c[1], c[2], c[3] return c[0], c[1], c[2], c[3]
} }
return i.image.At(x, y) var pix [4]byte
i.image.ReadPixels(pix[:], x, y, 1, 1)
return pix[0], pix[1], pix[2], pix[3]
} }
// Set sets the color at (x, y). // Set sets the color at (x, y).

View File

@ -112,9 +112,7 @@ func TestImagePixels(t *testing.T) {
} }
pix := make([]byte, 4*w*h) pix := make([]byte, 4*w*h)
if err := img0.ReadPixels(pix); err != nil { img0.ReadPixels(pix)
t.Fatal(err)
}
for j := 0; j < h; j++ { for j := 0; j < h; j++ {
for i := 0; i < w; i++ { for i := 0; i < w; i++ {
idx := 4 * (j*w + i) idx := 4 * (j*w + i)

View File

@ -75,25 +75,18 @@ func (i *Image) ReplacePixels(pix []byte, x, y, width, height int) {
i.mipmap.ReplacePixels(pix, x, y, width, height) i.mipmap.ReplacePixels(pix, x, y, width, height)
} }
func (i *Image) ReadPixels(pixels []byte, x, y, width, height int) error { func (i *Image) ReadPixels(pixels []byte, x, y, width, height int) {
return theUI.readPixels(i.mipmap, pixels, x, y, width, height)
}
func (i *Image) At(x, y int) (r, g, b, a byte) {
// Check the error existence and avoid unnecessary calls. // Check the error existence and avoid unnecessary calls.
if theGlobalState.error() != nil { if theGlobalState.error() != nil {
return 0, 0, 0, 0 return
} }
var pix [4]byte if err := theUI.readPixels(i.mipmap, pixels, x, y, width, height); err != nil {
if err := theUI.readPixels(i.mipmap, pix[:], x, y, 1, 1); err != nil {
if panicOnErrorOnReadingPixels { if panicOnErrorOnReadingPixels {
panic(err) panic(err)
} }
theGlobalState.setError(err) theGlobalState.setError(err)
return 0, 0, 0, 0
} }
return pix[0], pix[1], pix[2], pix[3]
} }
func (i *Image) DumpScreenshot(name string, blackbg bool) error { func (i *Image) DumpScreenshot(name string, blackbg bool) error {