buffered: Use the pending pixels when possible at At

(*Image).At can be unnecessarily slow since this tries to get
pixels from GPU. This change reduces the chance to read GPU by
using its pending pixels when possible.

Fixes #1137
This commit is contained in:
Hajime Hoshi 2020-04-17 21:34:46 +09:00
parent 4dad044ad1
commit 1d701577d6
2 changed files with 21 additions and 1 deletions

View File

@ -1996,3 +1996,20 @@ func TestImageDrawTrianglesWithColorM(t *testing.T) {
}
}
}
// Issue #1137
func TestImageDrawOver(t *testing.T) {
dst, _ := NewImage(320, 240, FilterDefault)
src := image.NewUniform(color.RGBA{0xff, 0, 0, 0xff})
// This must not cause infinite-loop.
draw.Draw(dst, dst.Bounds(), src, image.ZP, draw.Over)
for j := 0; j < 240; j++ {
for i := 0; i < 320; i++ {
got := dst.At(i, j)
want := color.RGBA{0xff, 0, 0, 0xff}
if got != want {
t.Errorf("At(%d, %d): got: %v, want: %v", i, j, got, want)
}
}
}
}

View File

@ -127,7 +127,10 @@ func (i *Image) At(x, y int) (r, g, b, a byte, err error) {
if needsToDelayCommands {
panic("buffered: the command queue is not available yet at At")
}
// TODO: Use pending pixels
if i.pixels != nil {
idx := i.width*y + x
return i.pixels[4*idx], i.pixels[4*idx+1], i.pixels[4*idx+2], i.pixels[4*idx+3], nil
}
i.resolvePendingPixels(true)
return i.img.At(x, y)
}