From ea04e2a9de78c87ff9c5828dac11f380716ca976 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Mon, 8 Aug 2022 02:48:23 +0900 Subject: [PATCH] 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 --- image.go | 16 ++++++++-------- image_test.go | 4 +--- internal/ui/image.go | 13 +++---------- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/image.go b/image.go index fb5df68f7..4c6f79553 100644 --- a/image.go +++ b/image.go @@ -787,31 +787,29 @@ func (i *Image) ColorModel() color.Model { // // 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 returns an error. +// len(pixels) must be 4*width*height. If the sizes don't match, ReadPixels panics. // // 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. // // 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() 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() { for i := range pixels { pixels[i] = 0 } - return nil + return } i.resolveSetVerticesCacheIfNeeded() 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). @@ -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 { 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). diff --git a/image_test.go b/image_test.go index 2c83d5ea9..280b6f6a0 100644 --- a/image_test.go +++ b/image_test.go @@ -112,9 +112,7 @@ func TestImagePixels(t *testing.T) { } pix := make([]byte, 4*w*h) - if err := img0.ReadPixels(pix); err != nil { - t.Fatal(err) - } + img0.ReadPixels(pix) for j := 0; j < h; j++ { for i := 0; i < w; i++ { idx := 4 * (j*w + i) diff --git a/internal/ui/image.go b/internal/ui/image.go index a4519c12a..904f5962a 100644 --- a/internal/ui/image.go +++ b/internal/ui/image.go @@ -75,25 +75,18 @@ func (i *Image) ReplacePixels(pix []byte, x, y, width, height int) { i.mipmap.ReplacePixels(pix, x, y, width, height) } -func (i *Image) ReadPixels(pixels []byte, x, y, width, height int) error { - return theUI.readPixels(i.mipmap, pixels, x, y, width, height) -} - -func (i *Image) At(x, y int) (r, g, b, a byte) { +func (i *Image) ReadPixels(pixels []byte, x, y, width, height int) { // Check the error existence and avoid unnecessary calls. if theGlobalState.error() != nil { - return 0, 0, 0, 0 + return } - var pix [4]byte - if err := theUI.readPixels(i.mipmap, pix[:], x, y, 1, 1); err != nil { + if err := theUI.readPixels(i.mipmap, pixels, x, y, width, height); err != nil { if panicOnErrorOnReadingPixels { panic(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 {