gioui.org@v0.6.1-0.20240506124620-7a9ce51988ce/gpu/headless/headless_test.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  package headless
     4  
     5  import (
     6  	"image"
     7  	"image/color"
     8  	"testing"
     9  
    10  	"gioui.org/internal/f32color"
    11  	"gioui.org/op"
    12  	"gioui.org/op/clip"
    13  	"gioui.org/op/paint"
    14  )
    15  
    16  func TestHeadless(t *testing.T) {
    17  	w, release := newTestWindow(t)
    18  	defer release()
    19  
    20  	sz := w.size
    21  	col := color.NRGBA{A: 0xff, R: 0xca, G: 0xfe}
    22  	var ops op.Ops
    23  	paint.ColorOp{Color: col}.Add(&ops)
    24  	// Paint only part of the screen to avoid the glClear optimization.
    25  	paint.FillShape(&ops, col, clip.Rect(image.Rect(0, 0, sz.X-100, sz.Y-100)).Op())
    26  	if err := w.Frame(&ops); err != nil {
    27  		t.Fatal(err)
    28  	}
    29  
    30  	img := image.NewRGBA(image.Rectangle{Max: w.Size()})
    31  	err := w.Screenshot(img)
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  	if isz := img.Bounds().Size(); isz != sz {
    36  		t.Errorf("got %v screenshot, expected %v", isz, sz)
    37  	}
    38  	if got := img.RGBAAt(0, 0); got != f32color.NRGBAToRGBA(col) {
    39  		t.Errorf("got color %v, expected %v", got, f32color.NRGBAToRGBA(col))
    40  	}
    41  }
    42  
    43  func TestClipping(t *testing.T) {
    44  	w, release := newTestWindow(t)
    45  	defer release()
    46  
    47  	col := color.NRGBA{A: 0xff, R: 0xca, G: 0xfe}
    48  	col2 := color.NRGBA{A: 0xff, R: 0x00, G: 0xfe}
    49  	var ops op.Ops
    50  	paint.ColorOp{Color: col}.Add(&ops)
    51  	clip.RRect{
    52  		Rect: image.Rect(50, 50, 250, 250),
    53  		SE:   75,
    54  	}.Push(&ops)
    55  	paint.PaintOp{}.Add(&ops)
    56  	paint.ColorOp{Color: col2}.Add(&ops)
    57  	clip.RRect{
    58  		Rect: image.Rect(100, 100, 350, 350),
    59  		NW:   75,
    60  	}.Push(&ops)
    61  	paint.PaintOp{}.Add(&ops)
    62  	if err := w.Frame(&ops); err != nil {
    63  		t.Fatal(err)
    64  	}
    65  
    66  	img := image.NewRGBA(image.Rectangle{Max: w.Size()})
    67  	err := w.Screenshot(img)
    68  	if err != nil {
    69  		t.Fatal(err)
    70  	}
    71  	if *dumpImages {
    72  		if err := saveImage("clip.png", img); err != nil {
    73  			t.Fatal(err)
    74  		}
    75  	}
    76  	var bg color.NRGBA
    77  	tests := []struct {
    78  		x, y  int
    79  		color color.NRGBA
    80  	}{
    81  		{120, 120, col},
    82  		{130, 130, col2},
    83  		{210, 210, col2},
    84  		{230, 230, bg},
    85  	}
    86  	for _, test := range tests {
    87  		if got := img.RGBAAt(test.x, test.y); got != f32color.NRGBAToRGBA(test.color) {
    88  			t.Errorf("(%d,%d): got color %v, expected %v", test.x, test.y, got, f32color.NRGBAToRGBA(test.color))
    89  		}
    90  	}
    91  }
    92  
    93  func TestDepth(t *testing.T) {
    94  	w, release := newTestWindow(t)
    95  	defer release()
    96  	var ops op.Ops
    97  
    98  	blue := color.NRGBA{B: 0xFF, A: 0xFF}
    99  	paint.FillShape(&ops, blue, clip.Rect(image.Rect(0, 0, 50, 100)).Op())
   100  	red := color.NRGBA{R: 0xFF, A: 0xFF}
   101  	paint.FillShape(&ops, red, clip.Rect(image.Rect(0, 0, 100, 50)).Op())
   102  	if err := w.Frame(&ops); err != nil {
   103  		t.Fatal(err)
   104  	}
   105  
   106  	img := image.NewRGBA(image.Rectangle{Max: w.Size()})
   107  	err := w.Screenshot(img)
   108  	if err != nil {
   109  		t.Fatal(err)
   110  	}
   111  	if *dumpImages {
   112  		if err := saveImage("depth.png", img); err != nil {
   113  			t.Fatal(err)
   114  		}
   115  	}
   116  	tests := []struct {
   117  		x, y  int
   118  		color color.NRGBA
   119  	}{
   120  		{25, 25, red},
   121  		{75, 25, red},
   122  		{25, 75, blue},
   123  	}
   124  	for _, test := range tests {
   125  		if got := img.RGBAAt(test.x, test.y); got != f32color.NRGBAToRGBA(test.color) {
   126  			t.Errorf("(%d,%d): got color %v, expected %v", test.x, test.y, got, f32color.NRGBAToRGBA(test.color))
   127  		}
   128  	}
   129  }
   130  
   131  func TestNoOps(t *testing.T) {
   132  	w, release := newTestWindow(t)
   133  	defer release()
   134  	if err := w.Frame(nil); err != nil {
   135  		t.Error(err)
   136  	}
   137  }
   138  
   139  func newTestWindow(t *testing.T) (*Window, func()) {
   140  	t.Helper()
   141  	sz := image.Point{X: 800, Y: 600}
   142  	w, err := NewWindow(sz.X, sz.Y)
   143  	if err != nil {
   144  		t.Skipf("headless windows not supported: %v", err)
   145  	}
   146  	return w, func() {
   147  		w.Release()
   148  	}
   149  }