1package vulkan
2
3import (
4 "image"
5 "testing"
6
7 "github.com/bnema/neferwl/internal/ports"
8)
9
10// A window under a presentation-only rect transition shows a rect that differs from its content
11// (the client has its final size already). These walk tests need no Vulkan
12// device: a single-pixel buffer is a solid quad.
13func TestSceneContentVsWindowRect(t *testing.T) {
14 r := &Renderer{width: 80, height: 60}
15 // A draw's rect is its corners: x0, y0, x1, y1.
16 // walk returns the content draws: the window's background fill is first.
17 walk := func(rect ports.Rect, lw, lh int, geo ports.Rect) []draw {
18 c := ports.SurfaceContent{
19 ID: 1, Width: 1, Height: 1, LogicalW: lw, LogicalH: lh, Geometry: geo,
20 Solid: &ports.SolidColor{R: 1, A: 1}, Opaque: true,
21 }
22 s := ports.Scene{Windows: []ports.SceneWindow{{ID: 1, Rect: rect}}}
23 contents := map[ports.WindowID]ports.SurfaceContent{1: c}
24 ds := r.draws(s, contents, newDamage(&target{}, s, image.Rect(0, 0, 80, 60)))
25 if len(ds) < 2 {
26 t.Fatalf("no content draw: %+v", ds)
27 }
28 return append([]draw(nil), ds[1:]...)
29 }
30
31 t.Run("rect smaller than content is clipped", func(t *testing.T) {
32 rect := ports.Rect{X: 10, Y: 10, W: 20, H: 20}
33 for _, geo := range []ports.Rect{{}, {X: 5, Y: 5, W: 30, H: 30}} {
34 ds := walk(rect, 40, 40, geo)
35 clip := image.Rect(10, 10, 30, 30)
36 for _, d := range ds {
37 got := image.Rect(int(d.pc.rect[0]), int(d.pc.rect[1]), int(d.pc.rect[2]), int(d.pc.rect[3]))
38 if !got.In(clip) {
39 t.Fatalf("geometry %+v: draw %v outside rect %v", geo, got, clip)
40 }
41 }
42 if d := ds[0].pc.rect; d != [4]int32{10, 10, 30, 30} {
43 t.Fatalf("geometry %+v: content = %v, want the whole rect", geo, d)
44 }
45 }
46 })
47
48 t.Run("rect larger than content shows only the content", func(t *testing.T) {
49 rect := ports.Rect{X: 10, Y: 10, W: 50, H: 40}
50 ds := walk(rect, 20, 16, ports.Rect{})
51 if len(ds) != 1 || ds[0].pc.rect != [4]int32{10, 10, 30, 26} {
52 t.Fatalf("content = %+v, want 20x16 at the rect origin", ds)
53 }
54 // Geometry shifts the surface so its geometry origin sits at the rect origin.
55 ds = walk(rect, 24, 20, ports.Rect{X: 4, Y: 4, W: 20, H: 16})
56 if len(ds) != 1 || ds[0].pc.rect != [4]int32{10, 10, 30, 26} {
57 t.Fatalf("content with geometry = %+v, want 20x16 at the rect origin", ds)
58 }
59 })
60}