-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Desktop abstractions #423
Desktop abstractions #423
Conversation
62ee10e
to
6b500a0
Compare
211e043
to
99776b7
Compare
src/desktop/window.rs
Outdated
damage.extend(attributes.damage.iter().map(|dmg| { | ||
let mut rect = match dmg { | ||
Damage::Buffer(rect) => rect.to_logical(attributes.buffer_scale), | ||
Damage::Surface(rect) => *rect, | ||
}; | ||
rect.loc += location; | ||
rect | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the longer-term, this could take into account the opaque_region
specified by the client to discard damage that is completely behind an opaque surface.
To transpose that on the space level, the Window would need to have a method returning a Vec<Region>
describing which parts of it are opaque I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah definitely. There is definitely room for improvement, but this is getting us probably already 80% of the way in terms of performance. (I still need to actually benchmark/profile it.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets make another ticket for this one.
src/desktop/space.rs
Outdated
} | ||
|
||
if let Some(surface) = kind.get_surface() { | ||
with_surface_tree_downward( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if it makes sense to give enter/leave information at the subsurface granularity detail.
Wouldn't it be simpler to just always send the same enter/leave to the whole subsurface tree, based only on intersection with the bounding box? I seems to me that it's unnecessary detail computed and sent to the client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Not sure actually. While that would probably be fine for most clients, I am not sure if more complex clients like firefox would agree?? But potentially worth a try? This is at least what anvil has been doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the wayland core protocol say something about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not much, tbh. The information of enter/leave is mostly used for deciding the scaling factor when drawing, the client cannot assume that its surface is actually visible on all the wl_outputs it is "entered" (as it might be hidden behind an other for example).
So I don't think it's actually possible for a client to rely on precise tracking of the wl_output its surface are entered on.
3893274
to
1341535
Compare
f2e182a
to
e2b5560
Compare
e2b5560
to
5166023
Compare
5166023
to
7a0dedd
Compare
be4c99f
to
02e582b
Compare
c2d6236
to
37e7efa
Compare
30fb667
to
8059bdc
Compare
deba1cd
to
7fc80e3
Compare
7fc80e3
to
067e849
Compare
067e849
to
36d9100
Compare
5ef4b76
to
811421c
Compare
/// If `all` is set this will be send to `all` mapped surfaces. | ||
/// Otherwise only windows and layers previously drawn during the | ||
/// previous frame will be send frame events. | ||
pub fn send_frames(&self, all: bool, time: u32) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For future reference (as this was discussed not long ago on matrix), instead of iterating over all windows, we could maintain a list of windows that have requested a frame (by inspecting their state on commit) and only iterate that list.
That is a small optimization, I don't know if it's actually worth it at all, and in any case this is not blocking this PR imo.
damage.push(old_toplevel); | ||
} | ||
|
||
// lets iterate front to back and figure out, what new windows or unmoved windows we have |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I understand correctly that this damage tracking does not take into account Z-order, for example a changed window will cause damage to the output even if it is completely occulted by an other, undamaged window?
If so, maybe worth letting a TODO (and maybe a tracking issue?) to not forget that this is something that has room for improvement in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes correct, because windows can be transparent. We need to expose opaque_region
similar to surface damage and then iterate twice through the elements.
Once front to back to figure out, what we need to render. Then back to front to render the filtered surfaces.
But that will be another PR 😅
6030312
to
811421c
Compare
Co-authored-by: Victor Berger <vberger@users.noreply.github.com>
820e67f
to
399bc6e
Compare
@@ -193,11 +193,17 @@ impl Space { | |||
/// The scale is the what is rendered for the given output | |||
/// and may be fractional. It is independent from the integer scale | |||
/// reported to clients by the output. | |||
/// | |||
/// *Note:* Remapping an output does reset it's damage memory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, does that mean the output will be considered as 100% damaged, or 0% damaged?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
100% damaged.
without a memory the output assumes everything is new.
753d386
to
7632d99
Compare
this fixes issues when the damage rect is greater than the destination rect, like providing i32::Max as the damage size
7632d99
to
9f5bf25
Compare
First draft of #363.
Notable changes:
Output
more versitileWindow
abstractionSpace
abstractionSpace::render_output
anddraw_window
)Things missing:
space
this needs some kind of boolean for each window (was_moved/dirty) to track, which windows should be rendered in full and then this needs to be passed to draw_window to render only with surface damage.solution is incomplete, we need to properly track this for multiple outputs/spaces.donehas no max size and it is awkward to add because it enforces a strict order of:we can properly addtbd in a later prMoveGrab
andResizeGrab
to smithay directly and add some helpers to use them with spaceswindow
has no max-size (which would also be nice for rendering)will be part of a follow-up PR(will be implemented in a later PR)draw_window
does not play well with multi-gpu setupsxwayland supportwill be part of a larger effort to better support xwayland in smithayanvil
winit backend does not make use of damage-tracking. I think we should not bother. Lets deprecate winit for 0.4 with less features and also add a wayland-backend before 0.4 as an alternative.implement little workspace effect or something similar to show how the desktop abstraction can be temporarily avoided for fancy stuff before resuming efficient rendering.(implemented later)Open questions:
map
arbitrary elements with textures? Maybe we can have a trait that can also work for windows and layers? (probably not layers though, since they map to outputs.)Figure out a way to atomically update the size and the position of a window (wait for ack on size and next buffer before updating the position). I want to get this rid on first try, because otherwise this feels really bad for tiling. I have no good idea yet how to do that, so suggestions are very welcometbd after wayland-rs 0.30Figure out an API to support the size-constraints envisioned by @vberger s first proposal (see Window Management Abstraction #363)My focus obviously was implementing damage-tracking and seeing if that works. I also took some inspiration from the code I wrote for fireplace. So please give feedback for ... well everything. I think the api was easy enough to implement for anvil, but it could likely be better.