gpu/headless: make Screenshot take an input image to tranfer into

When extracting headless.Window's content via screenshots,
it can be useful to keep reusing the same image for output,
as well as specify which area of the Window is to be
extracted.
The updated Screenshot method does this by using the supplied
image.

API change: users must pass an existing image to Window.Screenshot.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
This commit is contained in:
Pierre Curto
2021-12-15 13:22:21 +01:00
committed by Elias Naur
parent 0c7b0b1d0b
commit af63c089f6
7 changed files with 34 additions and 32 deletions
+4 -4
View File
@@ -199,17 +199,17 @@ func (f Features) Has(feats Features) bool {
return f&feats == feats
}
func DownloadImage(d Device, t Texture, r image.Rectangle) (*image.RGBA, error) {
img := image.NewRGBA(r)
func DownloadImage(d Device, t Texture, img *image.RGBA) error {
r := img.Bounds()
if err := t.ReadPixels(r, img.Pix, img.Stride); err != nil {
return nil, err
return err
}
if d.Caps().BottomLeftOrigin {
// OpenGL origin is in the lower-left corner. Flip the image to
// match.
flipImageY(r.Dx()*4, r.Dy(), img.Pix)
}
return img, nil
return nil
}
func flipImageY(stride, height int, pixels []byte) {
+2 -1
View File
@@ -47,7 +47,8 @@ func resetOps(gtx layout.Context) {
func finishBenchmark(b *testing.B, w *headless.Window) {
b.StopTimer()
if *dumpImages {
img, err := w.Screenshot()
img := image.NewRGBA(image.Rectangle{Max: w.Size()})
err := w.Screenshot(img)
w.Release()
if err != nil {
b.Error(err)
+6 -4
View File
@@ -59,7 +59,7 @@ func buildSquares(size int) paint.ImageOp {
return paint.NewImageOp(im)
}
func drawImage(t *testing.T, size int, ops *op.Ops, draw func(o *op.Ops)) (im *image.RGBA, err error) {
func drawImage(t *testing.T, size int, ops *op.Ops, draw func(o *op.Ops)) (*image.RGBA, error) {
sz := image.Point{X: size, Y: size}
w := newWindow(t, sz.X, sz.Y)
defer w.Release()
@@ -67,7 +67,9 @@ func drawImage(t *testing.T, size int, ops *op.Ops, draw func(o *op.Ops)) (im *i
if err := w.Frame(ops); err != nil {
return nil, err
}
return w.Screenshot()
img := image.NewRGBA(image.Rectangle{Max: sz})
err := w.Screenshot(img)
return img, err
}
func run(t *testing.T, f func(o *op.Ops), c func(r result)) {
@@ -106,7 +108,6 @@ type frameT struct {
func multiRun(t *testing.T, frames ...frameT) {
// draw a few times and check that it is correct each time, to
// ensure any caching effects still generate the correct images.
var img *image.RGBA
var err error
sz := image.Point{X: 128, Y: 128}
w := newWindow(t, sz.X, sz.Y)
@@ -119,7 +120,8 @@ func multiRun(t *testing.T, frames ...frameT) {
t.Errorf("rendering failed: %v", err)
continue
}
img, err = w.Screenshot()
img := image.NewRGBA(image.Rectangle{Max: sz})
err = w.Screenshot(img)
if err != nil {
t.Errorf("screenshot failed: %v", err)
continue