1package ports
2
3import "os"
4
5// Scene carries core → renderer immutable snapshots with fresh Windows slices,
6// one per output. Rects and the output size are logical and local to the
7// output; the renderer multiplies by Scale.
8type Scene struct {
9 // Security is the owner epoch captured when this scene was published.
10 // Output owners reject stale scenes rather than showing a queued desktop
11 // or accepting old locker buffers across acquisition/release.
12 Security SecurityState
13 Output string
14 Seq uint64
15 OutputWidth, OutputHeight int
16 Scale float64
17 // Off turns the display off (output power management): nothing is
18 // drawn until a scene without it.
19 Off bool
20 Background string
21 Border Border
22 // WorkspaceClip bounds workspace windows, their popups and separators
23 // in logical output coordinates. Zero inherits the full output. Layers
24 // remain output-wide; overview previews do not use this clip.
25 WorkspaceClip Rect
26 // Dim darkens the background, bottom layers and tiles (tile lines
27 // included) inside WorkspaceClip when set, with black at this opacity,
28 // 0 to 1, under the first
29 // visible float. 0 draws nothing.
30 Dim float64
31 Windows []SceneWindow
32 // Separators are the lines between windows, drawn in slice order with
33 // the Border colors: tile lines over the tiles, under the floats; a
34 // float's border right after the float.
35 Separators []Separator
36 // DropHints show where a dragged tile lands, filled with Border.Active
37 // over the windows of the workspace, under the top layers. Only the
38 // output under the pointer has them, during a drag.
39 DropHints []Rect
40 // Layers are the shown layer surfaces, drawn in slice order: background
41 // and bottom before windows, top and overlay after. Core leaves out
42 // those a fullscreen window hides (all but the background and a surface
43 // taking the keyboard exclusively); adapters draw every layer given.
44 // Window popups are drawn after the windows, layer popups
45 // (SceneWindow.OverLayers) last, over every layer.
46 Layers []SceneLayer
47 // Capture is the capture state of this output: exclusion and hidden
48 // workspace; nil while nothing is captured (capture.go).
49 Capture *SceneCapture
50 // CaptureScene is the workspace captured off screen (Capture.Workspace)
51 // drawn for capture only: a workspace that is not on screen. Only the
52 // root scene carries it; CaptureScene.Capture and .CaptureScene are nil.
53 CaptureScene *Scene
54 // CaptureIndicators are the marks of live captures of this output,
55 // drawn over everything; nil when none. Captures never hold them: the
56 // capture pipeline serves requests from a scene without them.
57 CaptureIndicators []CaptureIndicator
58}
59
60// Shows reports whether the scene draws the surface of id: only its
61// content changes need a new frame. A window scrolled off the output is
62// not drawn. WorkspaceClip also excludes off-viewport windows; OverLayers
63// popups remain output-wide.
64func (s Scene) Shows(id WindowID) bool {
65 for _, w := range s.Windows {
66 if w.ID == id && !w.Hidden && w.Rect.Overlaps(Rect{W: s.OutputWidth, H: s.OutputHeight}) &&
67 (w.OverLayers || s.WorkspaceClip == (Rect{}) || w.Rect.Overlaps(s.WorkspaceClip)) {
68 return true
69 }
70 }
71 for _, l := range s.Layers {
72 if l.ID == id {
73 return true
74 }
75 }
76 return false
77}
78
79// Border carries the window border style; colors are #rrggbb, "" skips
80// drawing. Width is in logical pixels.
81type Border struct {
82 Width int
83 Active, Inactive string
84}
85
86// Separator is a line between windows, in logical pixels. Active lines
87// mark the focused window and use Border.Active, others Border.Inactive.
88// Window is the float whose border it is; 0 for lines between tiles.
89type Separator struct {
90 Rect Rect
91 Active bool
92 Window WindowID
93}
94
95// SceneLayer carries core → renderer layer surface placement.
96type SceneLayer struct {
97 ID WindowID
98 Layer Layer
99 Rect Rect
100}
101
102// SurfaceColor is the committed encoding of a surface. Zero means sRGB.
103// PQ+BT.2020 and extended-linear sRGB are color-managed; zero is legacy
104// sRGB. MaxCLL/MaxFALL are in nits. YUV metadata is per surface commit.
105type SurfaceColor struct {
106 TF, Primaries uint8
107 MaxCLL, MaxFALL uint16
108 // Coefficients/range follow wp_color_representation_v1 (zero =
109 // unspecified, for YUV interpreted as BT.709 limited). Chroma is a
110 // H.273 Chroma420SampleLocType + 1 (zero defaults to type 0).
111 Coefficients, Range, Chroma uint8
112}
113
114const (
115 ColorTFPQ uint8 = 11 // wp_color_manager_v1 ST2084 PQ
116 ColorTFExtendedLinear uint8 = 5 // wp_color_manager_v1 ext_linear
117 ColorPrimariesBT2020 uint8 = 6 // wp_color_manager_v1 BT.2020
118 ColorPrimariesSRGB uint8 = 1
119)
120
121func (c SurfaceColor) IsPQ2020() bool {
122 return c.TF == ColorTFPQ && c.Primaries == ColorPrimariesBT2020
123}
124
125func (c SurfaceColor) IsExtendedLinear() bool {
126 return c.TF == ColorTFExtendedLinear && c.Primaries == ColorPrimariesSRGB
127}
128
129// ContentType is the committed wp_content_type_v1 hint.
130type ContentType uint8
131
132const (
133 ContentNone ContentType = iota
134 ContentPhoto
135 ContentVideo
136 ContentGame
137)
138
139// SurfaceContent carries wayland → output the latest committed content of a
140// window: SHM, a client shared-memory buffer, or DMABuf, a GPU buffer.
141// Renderers read both in place and never modify them. Empty means the window
142// has no content. LogicalW and LogicalH are the surface size in logical
143// pixels (buffer scale and viewport applied). Subsurfaces come in Children;
144// Geometry is the part of the surface that is the window (xdg window
145// geometry), the rest being client shadows.
146type SurfaceContent struct {
147 ID WindowID
148 ContentType ContentType
149 // Surface is a never-reused wl_surface identity; Version identifies its
150 // applied buffer content independently of the window publication Seq.
151 Surface, Version uint64
152 // Seq counts the window's contents (wayland sets it), for release.
153 Seq uint64
154 Width, Height int
155 LogicalW, LogicalH int
156 // Source is the committed crop in buffer pixels: x, y, width, height.
157 // Zero width means the entire buffer is used.
158 Source [4]float32
159 // Transform is the wl_output.transform the client applied to the
160 // buffer: readers apply its inverse. Width and Height stay the buffer's.
161 Transform BufferTransform
162 // Opaque ignores the alpha byte: an x format, or an opaque region that
163 // covers the whole surface. It is false while Fade is set.
164 Opaque bool
165 // Fade is how much wp_alpha_modifier_v1 fades the surface: 0 none,
166 // 1 invisible. Its opacity is multiplied by 1-Fade.
167 Fade float32
168 Color SurfaceColor
169 SHM *SHMBuffer
170 DMABuf *DMABuf
171 // Children are the subsurfaces, bottom to top, flattened.
172 Children []Subsurface
173 // Geometry is in logical pixels from the surface origin; empty means
174 // the whole surface.
175 Geometry Rect
176 // Async asks for tearing presentation (wp_tearing_control_v1); outputs
177 // honour it only in direct scanout.
178 Async bool
179 // Acquire is the explicit-sync fence of this content's root buffer
180 // (wp_linux_drm_syncobj_v1): readers wait on it before reading the
181 // buffer, instead of the buffer's implicit fences. Wayland owns it and
182 // closes it when the buffer is released; a reader that keeps it past
183 // the call duplicates it under Acquire.SyscallConn. nil: implicit sync.
184 // Wayland closes it only after every output reported a later content of
185 // the window as seen, so a reader never gets it already closed.
186 Acquire *os.File
187 // DamageHistory is what changed in the root surface's buffer over the
188 // window's last contents, oldest first, ending with this one (Seq).
189 // A renderer holding an older content redraws the union of the
190 // entries after it, or everything when the history does not reach it.
191 DamageHistory []SeqDamage
192}
193
194// BufferTransform is a wl_output.transform value: bit 0 rotates 90°
195// counter-clockwise, bit 1 rotates 180°, bit 2 flips around the vertical
196// axis first.
197type BufferTransform uint8
198
199// Rotated reports whether width and height swap between buffer and surface.
200func (t BufferTransform) Rotated() bool { return t&1 != 0 }
201
202// ToBuffer maps a point of a w×h surface (logical, before scale) to the
203// same point of its buffer, in the buffer's untransformed w'×h' axes, where
204// w' and h' swap when the transform is Rotated.
205func (t BufferTransform) ToBuffer(x, y, w, h float64) (float64, float64) {
206 if t&4 != 0 {
207 x = w - x
208 }
209 switch t & 3 {
210 case 1:
211 return y, w - x
212 case 2:
213 return w - x, h - y
214 case 3:
215 return h - y, x
216 }
217 return x, y
218}
219
220// SeqDamage is what content Seq changed from the one before: Rects in
221// root buffer pixels, or everything when Full.
222type SeqDamage struct {
223 Seq uint64
224 Full bool
225 Rects []Rect
226}
227
228// DamageSince is the union of changes after content seq up to this one,
229// and false when the history does not reach back to seq (redraw all).
230func (c SurfaceContent) DamageSince(seq uint64) ([]Rect, bool) {
231 if seq >= c.Seq {
232 return nil, true
233 }
234 h := c.DamageHistory
235 if len(h) == 0 || h[0].Seq > seq+1 || h[len(h)-1].Seq != c.Seq {
236 return nil, false
237 }
238 var out []Rect
239 for _, d := range h {
240 if d.Seq <= seq {
241 continue
242 }
243 if d.Full {
244 return nil, false
245 }
246 out = append(out, d.Rects...)
247 }
248 return out, true
249}
250
251// Subsurface is a child surface at X, Y logical pixels from the root
252// surface origin. Below children are drawn under the root surface.
253type Subsurface struct {
254 X, Y int
255 Below bool
256 SurfaceContent
257}
258
259// Empty reports whether the content has nothing to draw.
260func (c SurfaceContent) Empty() bool {
261 return c.SHM == nil && c.DMABuf == nil && len(c.Children) == 0
262}
263
264// SHMBuffer is a client wl_shm buffer: B8G8R8A8 pixels (argb8888/xrgb8888
265// little-endian) at Offset in the pool File, Stride bytes per row. The
266// client keeps writing the file, so renderers copy from it when they draw.
267// Pool is unique per wl_shm pool for the session: renderers map a pool
268// once. File stays open while the client's buffer exists and follows the
269// DMABuf rules: duplicate it under File.SyscallConn before keeping it. A
270// client may shrink the file at any time, so readers must survive faults.
271type SHMBuffer struct {
272 Pool uint64
273 File *os.File
274 Offset, Stride int
275}
276
277// DMABuf is a client GPU buffer (linux-dmabuf). Its files stay open while
278// the client's buffer exists; a renderer that keeps it must duplicate the
279// descriptors under File.SyscallConn so a concurrent close cannot hand it a
280// reused one. ID is unique per buffer for the whole session: renderers key
281// their imports on it.
282type DMABuf struct {
283 ID uint64
284 Width, Height int
285 Format uint32 // DRM fourcc
286 Modifier uint64
287 Planes []DMABufPlane
288}
289
290// DMABufPlane is one plane of a DMABuf.
291type DMABufPlane struct {
292 File *os.File
293 Offset, Stride uint32
294}
295
296// DMABufFormat is a DRM fourcc with a modifier the renderer can import.
297type DMABufFormat struct {
298 Format uint32
299 Modifier uint64
300}
301
302// DMABufSupport is what the renderer imports: the render device (a dev_t,
303// 0 when unknown) and the formats. No formats means no dmabuf.
304type DMABufSupport struct {
305 Device uint64
306 Formats []DMABufFormat
307}
308
309// SceneWindow carries core → renderer window placement.
310type SceneWindow struct {
311 ID WindowID
312 Rect Rect
313 Focused, Fullscreen, Hidden bool
314 // Inset sides carry a separator line inside Rect: the client is drawn
315 // inside it.
316 Inset Sides
317 // Floating windows draw at their placed size. Below marks a native
318 // covering float behind the column group.
319 Floating, Below bool
320 // Dim darkens the window, border included, with black at this
321 // opacity, 0 to 1: a stashed window peeking in. 0 draws nothing.
322 Dim float64
323 // FocusEffect, above 0, is the focus indicator's effect at this frame
324 // (focus.animation, focus.effect): the window's surfaces are lifted
325 // toward white by that fraction (screen blend). Renderers without the
326 // effect ignore it.
327 //
328 // Only focus.effect = screen exists, so the effect kind is not carried:
329 // core ignores Config.Focus.Effect and the shaders always apply screen
330 // (compose.frag, compose_hdr.frag, push constant mapy.z). A second effect
331 // needs its kind here and in the push constants (a misc flag).
332 FocusEffect float64
333 // Preview, above 0, draws the window's surfaces that much smaller in
334 // Rect (an overview thumbnail): the client keeps its size.
335 Preview float64
336 // Popups are drawn from their content only: no border, no background.
337 Popup bool
338 // OverLayers popups hang from a layer surface: drawn over the top and
339 // overlay layers. Window popups stay with the windows, under them.
340 OverLayers bool
341}