Window Management Abstraction #363
Replies: 7 comments 18 replies
-
Is a workspace limited to a single output or can it span multiple outputs? I would expect the latter. How should the popup constrain work in case a window is shown half/half on two outputs? I think it would be better to show the popup on a single output in most cases then, but there could be some uses cases with (near) zero bezel displays where it could be shown across both. |
Beta Was this translation helpful? Give feedback.
-
Input handling, like finding the surface and point under the pointer location could be added much like currently implemented in anvil. |
Beta Was this translation helpful? Give feedback.
-
Are use cases other than classic desktop style window management out of scope? Like mapping windows into a 3d space? |
Beta Was this translation helpful? Give feedback.
-
Given that |
Beta Was this translation helpful? Give feedback.
-
What about output tracking for sending enter/leave? Maybe it is out of scope for this abstraction, but we should outline how it is possible to do it when using this abstraction. Otherwise we could easily end up with a similar solution like currently implemented in anvil where the output map needs to iterate all windows. This could be built more reactive. |
Beta Was this translation helpful? Give feedback.
-
Alright, I have had some time to think about damage tracking and optimizations in general, so here is a brain-dump, because I think this actually has a lot to do with our current idea of window management.
Damage TrackingAs @vberger pointed out, we can skip surfaces, which is in itself an optimization. Another one would be to simply skip a page-flip, if nothing has changed, but damage tracking goes far deeper.
Smithay's What is a buffer age?Consider a frontbuffer A and a backbuffer B. Lets say we start our rendering loop by rendering everything to the backbuffer B and swap it with A. Now A is our backbuffer, but we cannot really utilize the damage tracking potential, because A was never drawn to, it contains nothing of value, that we could reuse. We need to render the whole frame again. Now consider triple buffering or more... And our swapchain does not really tell us how many buffers are used in the background, all of this is an implementation detail. It just gives us the next buffer, which ever that is. Through buffer age we can communicate how old a buffer is (meaning how many rendering steps ago it was last used). Fixing this is a first necessary step for damage tracking. Afterwards we just need to keep track of all those changes. Ok, but that still sounds like a lot of book-keeping.It is and I have been struggling with designing an abstraction to keep track of all those changes for the user. That is very flexible, but still leaves a lot of responsibility with the user. Any changes to the compositor state need to mark the next frame as damaged correctly or outdated buffer contents may be used. Ideally the user does not need to see any of this and cannot misuse it. Representing damage as a difference in stateSo what do we need to do this for the user? We need to precisely know, what has changed between rendering at one frame and the next. And this is where our current ideas for window management come in. What @vberger has described in its first brain dump already keeps track of everything we need. We have a representation of an output (or workspace), which keeps track of windows (not surfaces, because we need a position to do this correctly) and keeps track of z-order. If we can encode this into a struct that just keeps track of this state, make that easily clonable and cheaply storable, we can implement a diffing algorithm between two of these "rendering-states". Roughtly such an algorithm would do something similar to:
If the buffer age gets older, we just diff between more states and accumulate the damage. I have not looked into wlroots scene-api, but I imagine this is roughly what they are doing. But I do not see any value in representing the window structure as a graph (instead of a z-ordered array), since smithay is very shell agnostic. For tiling compositors a graph obviously makes a lot of sense, because everything fits into containers and you may easily figure if one part of the tree did remain completely unchanged. Our approach could be a little worse in performance for large surface counts, but I do not think it could be that bad for real world usecases. Does that mean custom rendering steps are becoming impossible?Not necessarily, no. First of all, I think it is easy enough to let the user insert arbitrary textures in the list of objects to compare against. E.g. for backgrounds or our FPS tracker. (Most of that stuff could be done with layer shell instead, but that might be not the easiest way.)
3D-Rendering however will likely not be able to make much use of damage tracking, but I do not think that this is that bad. E.g. if you want a fancy rotating cube transition between workspaces, you can just render the transition manually without any damage tracking. Since the perspective of the windows likely shifts with every frame, there is not much to track anyway. And once the animation is over and you are back to more traditional layouts, you can use our damage tracking abstractions again. Maybe you need an extra call to mark the whole frame as damaged, but that should be about it. Like this you can get fancy animations and still a lot of optimizations in between. Also the user is of course not required to use any of this. This means however that smithay will only use the Moving stuff out of anvil into smithaySo what exactly needs to be done, after introducing buffer age in smithay? I guess anvil will become a lot smaller. What is currently Next To make this whole setup easier, I should probably build a generalized Then the whole abstraction just needs a function to get the next buffer + its age. Pair that with a workspace, which keeps track of previous rendering-states (releasing them, once it sees a buffer age, that is younger then any state it still has) and smithay does all the hard stuff for you. Any feedback on this is welcome. |
Beta Was this translation helpful? Give feedback.
-
This has been done I believe? We could probably mark this as resolved? |
Beta Was this translation helpful? Give feedback.
-
Here is a brain dump of a potential idea for an abstraction in Smithay to do window management.
General structure
wl_shell
support at this point and not worry about it?Geometry and shell interactions
xdg_surface.set_geometry
, and is the value that should be considered to reorganize the windows on the screen and such.wl_region
attributes, defining a global boundary around where there can be content at all. This boundary is take into account in addition to the windows-wise limits to position popups and handle shell interactions (move, resize) with windows.strict
, in which no content is allowed to move outside of the defined boundary, andrelaxed
in which only the base location of a window must be inside the defined boundary, but the window itself may have parts of it that go outside.Drawing
wl_surface
whose content intersect with it. This iteration needs to be done in correct z-order (including all windows and popups), and should skip surfaces that are completely masked by other opaque surfaces (as specified by the clients telling that their surfaces are opaque). The iteration should also give easy access to the relevant metadata to draw each surface (such as its location relative to the output rectangle).Beta Was this translation helpful? Give feedback.
All reactions