Skip to content

Commit b6292d5

Browse files
committed
screencopy: Use damage_output() for additional damage
The important change here is that we now apply the additional damage first, instead of using `.extend()` to add it after other elements. This is important since `OutputDamageTracker` will ignore our damage elements if there are behind an element with an opaque region. This also makes things a bit simpler, especially `take_screencopy_frames()`, which no longer needs a mutable references to extend then truncate. The implementation of `OutputDamageTracker` isn't entirely clear, but as far as I can tell this is intended to work, and it seems to work in some testing.
1 parent f339e21 commit b6292d5

File tree

4 files changed

+74
-113
lines changed

4 files changed

+74
-113
lines changed

src/backend/kms/surface/mod.rs

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,7 @@ impl SurfaceThreadState {
10721072
let frames = self
10731073
.mirroring
10741074
.is_none()
1075-
.then(|| take_screencopy_frames(&self.output, &mut elements, &mut has_cursor_mode_none))
1075+
.then(|| take_screencopy_frames(&self.output, &elements, &mut has_cursor_mode_none))
10761076
.unwrap_or_default();
10771077

10781078
// actual rendering
@@ -1591,10 +1591,9 @@ fn get_surface_dmabuf_feedback(
15911591
}
15921592
}
15931593

1594-
// TODO: Don't mutate `elements`
15951594
fn take_screencopy_frames(
15961595
output: &Output,
1597-
elements: &mut Vec<CosmicElement<GlMultiRenderer>>,
1596+
elements: &[CosmicElement<GlMultiRenderer>],
15981597
has_cursor_mode_none: &mut bool,
15991598
) -> Vec<(
16001599
ScreencopySessionRef,
@@ -1609,7 +1608,15 @@ fn take_screencopy_frames(
16091608
let session_data = session.user_data().get::<SessionData>().unwrap();
16101609
let mut damage_tracking = session_data.lock().unwrap();
16111610

1612-
let old_len = if !additional_damage.is_empty() {
1611+
let buffer = frame.buffer();
1612+
let age = if matches!(buffer_type(&buffer), Some(BufferType::Shm)) {
1613+
// TODO re-use offscreen buffer to damage track screencopy to shm
1614+
0
1615+
} else {
1616+
damage_tracking.age_for_buffer(&buffer)
1617+
};
1618+
1619+
if !additional_damage.is_empty() {
16131620
let area = output
16141621
.current_mode()
16151622
.unwrap()
@@ -1619,41 +1626,26 @@ fn take_screencopy_frames(
16191626
.to_buffer(1, Transform::Normal)
16201627
.to_f64();
16211628

1622-
let old_len = elements.len();
1623-
elements.extend(
1624-
additional_damage
1625-
.into_iter()
1626-
.map(|rect| {
1627-
rect.to_f64()
1628-
.to_logical(
1629-
output.current_scale().fractional_scale(),
1630-
output.current_transform(),
1631-
&area,
1632-
)
1633-
.to_i32_round()
1634-
})
1635-
.map(DamageElement::new)
1636-
.map(Into::into),
1637-
);
1638-
1639-
Some(old_len)
1640-
} else {
1641-
None
1629+
let additional_damage_elements: Vec<_> = additional_damage
1630+
.into_iter()
1631+
.map(|rect| {
1632+
rect.to_f64()
1633+
.to_logical(
1634+
output.current_scale().fractional_scale(),
1635+
output.current_transform(),
1636+
&area,
1637+
)
1638+
.to_i32_round()
1639+
})
1640+
.map(DamageElement::new)
1641+
.collect();
1642+
let _ = damage_tracking
1643+
.dt
1644+
.damage_output(age, &additional_damage_elements);
16421645
};
16431646

1644-
let buffer = frame.buffer();
1645-
let age = if matches!(buffer_type(&frame.buffer()), Some(BufferType::Shm)) {
1646-
// TODO re-use offscreen buffer to damage track screencopy to shm
1647-
0
1648-
} else {
1649-
damage_tracking.age_for_buffer(&buffer)
1650-
};
16511647
let res = damage_tracking.dt.damage_output(age, &elements);
16521648

1653-
if let Some(old_len) = old_len {
1654-
elements.truncate(old_len);
1655-
}
1656-
16571649
if !session.draw_cursor() {
16581650
*has_cursor_mode_none = true;
16591651
}

src/backend/render/element.rs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ where
3232
Cursor(RescaleRenderElement<RelocateRenderElement<CursorRenderElement<R>>>),
3333
Dnd(WaylandSurfaceRenderElement<R>),
3434
MoveGrab(RescaleRenderElement<CosmicMappedRenderElement<R>>),
35-
AdditionalDamage(DamageElement),
3635
Postprocess(
3736
CropRenderElement<RelocateRenderElement<RescaleRenderElement<TextureShaderElement>>>,
3837
),
@@ -53,7 +52,6 @@ where
5352
CosmicElement::Cursor(elem) => elem.id(),
5453
CosmicElement::Dnd(elem) => elem.id(),
5554
CosmicElement::MoveGrab(elem) => elem.id(),
56-
CosmicElement::AdditionalDamage(elem) => elem.id(),
5755
CosmicElement::Postprocess(elem) => elem.id(),
5856
CosmicElement::Zoom(elem) => elem.id(),
5957
#[cfg(feature = "debug")]
@@ -67,7 +65,6 @@ where
6765
CosmicElement::Cursor(elem) => elem.current_commit(),
6866
CosmicElement::Dnd(elem) => elem.current_commit(),
6967
CosmicElement::MoveGrab(elem) => elem.current_commit(),
70-
CosmicElement::AdditionalDamage(elem) => elem.current_commit(),
7168
CosmicElement::Postprocess(elem) => elem.current_commit(),
7269
CosmicElement::Zoom(elem) => elem.current_commit(),
7370
#[cfg(feature = "debug")]
@@ -81,7 +78,6 @@ where
8178
CosmicElement::Cursor(elem) => elem.src(),
8279
CosmicElement::Dnd(elem) => elem.src(),
8380
CosmicElement::MoveGrab(elem) => elem.src(),
84-
CosmicElement::AdditionalDamage(elem) => elem.src(),
8581
CosmicElement::Postprocess(elem) => elem.src(),
8682
CosmicElement::Zoom(elem) => elem.src(),
8783
#[cfg(feature = "debug")]
@@ -95,7 +91,6 @@ where
9591
CosmicElement::Cursor(elem) => elem.geometry(scale),
9692
CosmicElement::Dnd(elem) => elem.geometry(scale),
9793
CosmicElement::MoveGrab(elem) => elem.geometry(scale),
98-
CosmicElement::AdditionalDamage(elem) => elem.geometry(scale),
9994
CosmicElement::Postprocess(elem) => elem.geometry(scale),
10095
CosmicElement::Zoom(elem) => elem.geometry(scale),
10196
#[cfg(feature = "debug")]
@@ -109,7 +104,6 @@ where
109104
CosmicElement::Cursor(elem) => elem.location(scale),
110105
CosmicElement::Dnd(elem) => elem.location(scale),
111106
CosmicElement::MoveGrab(elem) => elem.location(scale),
112-
CosmicElement::AdditionalDamage(elem) => elem.location(scale),
113107
CosmicElement::Postprocess(elem) => elem.location(scale),
114108
CosmicElement::Zoom(elem) => elem.location(scale),
115109
#[cfg(feature = "debug")]
@@ -123,7 +117,6 @@ where
123117
CosmicElement::Cursor(elem) => elem.transform(),
124118
CosmicElement::Dnd(elem) => elem.transform(),
125119
CosmicElement::MoveGrab(elem) => elem.transform(),
126-
CosmicElement::AdditionalDamage(elem) => elem.transform(),
127120
CosmicElement::Postprocess(elem) => elem.transform(),
128121
CosmicElement::Zoom(elem) => elem.transform(),
129122
#[cfg(feature = "debug")]
@@ -141,7 +134,6 @@ where
141134
CosmicElement::Cursor(elem) => elem.damage_since(scale, commit),
142135
CosmicElement::Dnd(elem) => elem.damage_since(scale, commit),
143136
CosmicElement::MoveGrab(elem) => elem.damage_since(scale, commit),
144-
CosmicElement::AdditionalDamage(elem) => elem.damage_since(scale, commit),
145137
CosmicElement::Postprocess(elem) => elem.damage_since(scale, commit),
146138
CosmicElement::Zoom(elem) => elem.damage_since(scale, commit),
147139
#[cfg(feature = "debug")]
@@ -155,7 +147,6 @@ where
155147
CosmicElement::Cursor(elem) => elem.opaque_regions(scale),
156148
CosmicElement::Dnd(elem) => elem.opaque_regions(scale),
157149
CosmicElement::MoveGrab(elem) => elem.opaque_regions(scale),
158-
CosmicElement::AdditionalDamage(elem) => elem.opaque_regions(scale),
159150
CosmicElement::Postprocess(elem) => elem.opaque_regions(scale),
160151
CosmicElement::Zoom(elem) => elem.opaque_regions(scale),
161152
#[cfg(feature = "debug")]
@@ -169,7 +160,6 @@ where
169160
CosmicElement::Cursor(elem) => elem.alpha(),
170161
CosmicElement::Dnd(elem) => elem.alpha(),
171162
CosmicElement::MoveGrab(elem) => elem.alpha(),
172-
CosmicElement::AdditionalDamage(elem) => elem.alpha(),
173163
CosmicElement::Postprocess(elem) => elem.alpha(),
174164
CosmicElement::Zoom(elem) => elem.alpha(),
175165
#[cfg(feature = "debug")]
@@ -183,7 +173,6 @@ where
183173
CosmicElement::Cursor(elem) => elem.kind(),
184174
CosmicElement::Dnd(elem) => elem.kind(),
185175
CosmicElement::MoveGrab(elem) => elem.kind(),
186-
CosmicElement::AdditionalDamage(elem) => elem.kind(),
187176
CosmicElement::Postprocess(elem) => elem.kind(),
188177
CosmicElement::Zoom(elem) => elem.kind(),
189178
#[cfg(feature = "debug")]
@@ -212,9 +201,6 @@ where
212201
CosmicElement::Cursor(elem) => elem.draw(frame, src, dst, damage, opaque_regions),
213202
CosmicElement::Dnd(elem) => elem.draw(frame, src, dst, damage, opaque_regions),
214203
CosmicElement::MoveGrab(elem) => elem.draw(frame, src, dst, damage, opaque_regions),
215-
CosmicElement::AdditionalDamage(elem) => {
216-
RenderElement::<R>::draw(elem, frame, src, dst, damage, opaque_regions)
217-
}
218204
CosmicElement::Postprocess(elem) => {
219205
let glow_frame = R::glow_frame_mut(frame);
220206
RenderElement::<GlowRenderer>::draw(
@@ -250,7 +236,6 @@ where
250236
CosmicElement::Cursor(elem) => elem.underlying_storage(renderer),
251237
CosmicElement::Dnd(elem) => elem.underlying_storage(renderer),
252238
CosmicElement::MoveGrab(elem) => elem.underlying_storage(renderer),
253-
CosmicElement::AdditionalDamage(elem) => elem.underlying_storage(renderer),
254239
CosmicElement::Postprocess(elem) => {
255240
let glow_renderer = renderer.glow_renderer_mut();
256241
elem.underlying_storage(glow_renderer)
@@ -281,17 +266,6 @@ where
281266
}
282267
}
283268

284-
impl<R> From<DamageElement> for CosmicElement<R>
285-
where
286-
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
287-
R::TextureId: 'static,
288-
CosmicMappedRenderElement<R>: RenderElement<R>,
289-
{
290-
fn from(elem: DamageElement) -> Self {
291-
Self::AdditionalDamage(elem)
292-
}
293-
}
294-
295269
impl<R> From<MemoryRenderBufferRenderElement<R>> for CosmicElement<R>
296270
where
297271
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,

src/backend/render/mod.rs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,21 +1353,20 @@ where
13531353
)?;
13541354

13551355
let old_len = elements.len();
1356-
elements.extend(
1357-
additional_damage
1358-
.into_iter()
1359-
.map(|rect| {
1360-
rect.to_f64()
1361-
.to_logical(
1362-
output.current_scale().fractional_scale(),
1363-
output.current_transform(),
1364-
&area,
1365-
)
1366-
.to_i32_round()
1367-
})
1368-
.map(DamageElement::new)
1369-
.map(Into::into),
1370-
);
1356+
let additional_damage_elements: Vec<_> = additional_damage
1357+
.into_iter()
1358+
.map(|rect| {
1359+
rect.to_f64()
1360+
.to_logical(
1361+
output.current_scale().fractional_scale(),
1362+
output.current_transform(),
1363+
&area,
1364+
)
1365+
.to_i32_round()
1366+
})
1367+
.map(DamageElement::new)
1368+
.collect();
1369+
dt.damage_output(age, &additional_damage_elements)?;
13711370

13721371
Some(old_len)
13731372
} else {
@@ -1473,7 +1472,7 @@ where
14731472
CosmicMappedRenderElement<R>: RenderElement<R>,
14741473
WorkspaceRenderElement<R>: RenderElement<R>,
14751474
{
1476-
let mut elements: Vec<CosmicElement<R>> = workspace_elements(
1475+
let elements: Vec<CosmicElement<R>> = workspace_elements(
14771476
gpu,
14781477
renderer,
14791478
shell,
@@ -1488,13 +1487,12 @@ where
14881487

14891488
if let Some(additional_damage) = additional_damage {
14901489
let output_geo = output.geometry().to_local(&output).as_logical();
1491-
elements.extend(
1492-
additional_damage
1493-
.into_iter()
1494-
.filter_map(|rect| rect.intersection(output_geo))
1495-
.map(DamageElement::new)
1496-
.map(Into::<CosmicElement<R>>::into),
1497-
);
1490+
let additional_damage_elements: Vec<_> = additional_damage
1491+
.into_iter()
1492+
.filter_map(|rect| rect.intersection(output_geo))
1493+
.map(DamageElement::new)
1494+
.collect();
1495+
damage_tracker.damage_output(age, &additional_damage_elements)?;
14981496
}
14991497

15001498
let res = damage_tracker.render_output(

src/wayland/handlers/screencopy/render.rs

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,6 @@ smithay::render_elements! {
490490
pub WindowCaptureElement<R> where R: ImportAll + ImportMem;
491491
WaylandElement=WaylandSurfaceRenderElement<R>,
492492
CursorElement=RelocateRenderElement<cursor::CursorRenderElement<R>>,
493-
AdditionalDamage=DamageElement,
494493
}
495494

496495
pub fn render_window_to_buffer(
@@ -541,22 +540,19 @@ pub fn render_window_to_buffer(
541540
CosmicElement<R>: RenderElement<R>,
542541
CosmicMappedRenderElement<R>: RenderElement<R>,
543542
{
544-
let mut elements = Vec::new();
545-
546-
elements.extend(
547-
additional_damage
548-
.into_iter()
549-
.filter_map(|rect| {
550-
let logical_rect = rect.to_logical(
551-
1,
552-
Transform::Normal,
553-
&geometry.size.to_buffer(1, Transform::Normal),
554-
);
555-
logical_rect.intersection(Rectangle::from_size(geometry.size))
556-
})
557-
.map(DamageElement::new)
558-
.map(Into::<WindowCaptureElement<R>>::into),
559-
);
543+
let additional_damage_elements: Vec<_> = additional_damage
544+
.into_iter()
545+
.filter_map(|rect| {
546+
let logical_rect = rect.to_logical(
547+
1,
548+
Transform::Normal,
549+
&geometry.size.to_buffer(1, Transform::Normal),
550+
);
551+
logical_rect.intersection(Rectangle::from_size(geometry.size))
552+
})
553+
.map(DamageElement::new)
554+
.collect();
555+
dt.damage_output(age, &additional_damage_elements)?;
560556

561557
let shell = common.shell.read();
562558
let seat = shell.seats.last_active().clone();
@@ -579,6 +575,8 @@ pub fn render_window_to_buffer(
579575
};
580576
std::mem::drop(shell);
581577

578+
let mut elements = Vec::new();
579+
582580
if let Some(location) = location {
583581
if draw_cursor {
584582
elements.extend(
@@ -777,7 +775,17 @@ pub fn render_cursor_to_buffer(
777775
CosmicElement<R>: RenderElement<R>,
778776
CosmicMappedRenderElement<R>: RenderElement<R>,
779777
{
780-
let mut elements = cursor::draw_cursor(
778+
let additional_damage_elements: Vec<_> = additional_damage
779+
.into_iter()
780+
.filter_map(|rect| {
781+
let logical_rect = rect.to_logical(1, Transform::Normal, &Size::from((64, 64)));
782+
logical_rect.intersection(Rectangle::from_size((64, 64).into()))
783+
})
784+
.map(DamageElement::new)
785+
.collect();
786+
dt.damage_output(age, &additional_damage_elements)?;
787+
788+
let elements = cursor::draw_cursor(
781789
renderer,
782790
&seat,
783791
Point::from((0.0, 0.0)),
@@ -791,17 +799,6 @@ pub fn render_cursor_to_buffer(
791799
.map(WindowCaptureElement::from)
792800
.collect::<Vec<_>>();
793801

794-
elements.extend(
795-
additional_damage
796-
.into_iter()
797-
.filter_map(|rect| {
798-
let logical_rect = rect.to_logical(1, Transform::Normal, &Size::from((64, 64)));
799-
logical_rect.intersection(Rectangle::from_size((64, 64).into()))
800-
})
801-
.map(DamageElement::new)
802-
.map(Into::<WindowCaptureElement<R>>::into),
803-
);
804-
805802
if let Ok(dmabuf) = get_dmabuf(buffer) {
806803
let mut dmabuf_clone = dmabuf.clone();
807804
let mut fb = renderer

0 commit comments

Comments
 (0)