1
0
Fork 0
forked from wry/wry

video: render hardware cursor in screencasts

This commit is contained in:
Julian Orth 2024-02-16 19:12:50 +01:00
parent d4fc672fb3
commit 4d8e744c2f
4 changed files with 86 additions and 10 deletions

View file

@ -149,7 +149,12 @@ impl JayScreencast {
}); });
} }
pub fn copy_texture(&self, on: &OutputNode, texture: &Rc<dyn GfxTexture>) { pub fn copy_texture(
&self,
on: &OutputNode,
texture: &Rc<dyn GfxTexture>,
render_hardware_cursors: bool,
) {
if !self.running.get() { if !self.running.get() {
return; return;
} }
@ -165,7 +170,15 @@ impl JayScreencast {
let mut buffer = self.buffers.borrow_mut(); let mut buffer = self.buffers.borrow_mut();
for (idx, buffer) in buffer.deref_mut().iter_mut().enumerate() { for (idx, buffer) in buffer.deref_mut().iter_mut().enumerate() {
if buffer.free { if buffer.free {
buffer.fb.copy_texture(texture, 0, 0); self.client.state.perform_screencopy(
texture,
&buffer.fb,
on.global.preferred_scale.get(),
on.global.pos.get(),
render_hardware_cursors,
0,
0,
);
self.client.event(Ready { self.client.event(Ready {
self_id: self.id, self_id: self.id,
idx: idx as _, idx: idx as _,

View file

@ -202,7 +202,12 @@ impl WlOutputGlobal {
Ok(()) Ok(())
} }
pub fn perform_screencopies(&self, fb: &dyn GfxFramebuffer, tex: &Rc<dyn GfxTexture>) { pub fn perform_screencopies(
&self,
fb: &dyn GfxFramebuffer,
tex: &Rc<dyn GfxTexture>,
render_hardware_cursors: bool,
) {
if self.pending_captures.is_empty() { if self.pending_captures.is_empty() {
return; return;
} }
@ -278,7 +283,15 @@ impl WlOutputGlobal {
continue; continue;
} }
}; };
fb.copy_texture(tex, -capture.rect.x1(), -capture.rect.y1()); self.state.perform_screencopy(
tex,
&fb,
self.preferred_scale.get(),
self.pos.get(),
render_hardware_cursors,
-capture.rect.x1(),
-capture.rect.y1(),
);
} }
if capture.with_damage.get() { if capture.with_damage.get() {
capture.send_damage(); capture.send_damage();

View file

@ -13,6 +13,7 @@ use {
cursor::{Cursor, ServerCursors}, cursor::{Cursor, ServerCursors},
dbus::Dbus, dbus::Dbus,
drm_feedback::DrmFeedback, drm_feedback::DrmFeedback,
fixed::Fixed,
forker::ForkerProxy, forker::ForkerProxy,
gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture}, gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture},
gfx_apis::create_gfx_context, gfx_apis::create_gfx_context,
@ -36,9 +37,9 @@ use {
leaks::Tracker, leaks::Tracker,
logger::Logger, logger::Logger,
rect::Rect, rect::Rect,
renderer::RenderResult, renderer::{renderer_base::RendererBase, RenderResult, Renderer},
scale::Scale, scale::Scale,
theme::Theme, theme::{Color, Theme},
tree::{ tree::{
ContainerNode, ContainerSplit, Direction, DisplayNode, FloatNode, Node, NodeIds, ContainerNode, ContainerSplit, Direction, DisplayNode, FloatNode, Node, NodeIds,
NodeVisitorBase, OutputNode, PlaceholderNode, ToplevelNode, WorkspaceNode, NodeVisitorBase, OutputNode, PlaceholderNode, ToplevelNode, WorkspaceNode,
@ -752,6 +753,49 @@ impl State {
fr.send_done(); fr.send_done();
let _ = fr.client.remove_obj(&*fr); let _ = fr.client.remove_obj(&*fr);
} }
output.perform_screencopies(&**fb, tex); output.perform_screencopies(&**fb, tex, !render_hw_cursor);
}
pub fn perform_screencopy(
&self,
src: &Rc<dyn GfxTexture>,
target: &Rc<dyn GfxFramebuffer>,
scale: Scale,
position: Rect,
render_hardware_cursors: bool,
x_off: i32,
y_off: i32,
) {
let mut ops = target.take_render_ops();
let (width, height) = target.size();
let mut renderer = Renderer {
base: RendererBase {
ops: &mut ops,
scaled: scale != 1,
scale,
scalef: scale.to_f64(),
},
state: self,
result: None,
logical_extents: position.at_point(0, 0),
physical_extents: Rect::new_sized(0, 0, width, height).unwrap(),
};
renderer
.base
.render_texture(src, x_off, y_off, None, None, scale, None);
if render_hardware_cursors {
for seat in self.globals.lock_seats().values() {
if let Some(cursor) = seat.get_cursor() {
let (mut x, mut y) = seat.get_position();
if seat.hardware_cursor() {
x = x + x_off - Fixed::from_int(position.x1());
y = y + y_off - Fixed::from_int(position.y1());
cursor.render(&mut renderer, x, y);
}
}
}
}
let clear = target.format().has_alpha.then_some(&Color::TRANSPARENT);
target.render(ops, clear);
} }
} }

View file

@ -78,15 +78,21 @@ pub async fn output_render_data(state: Rc<State>) {
} }
impl OutputNode { impl OutputNode {
pub fn perform_screencopies(&self, fb: &dyn GfxFramebuffer, tex: &Rc<dyn GfxTexture>) { pub fn perform_screencopies(
&self,
fb: &dyn GfxFramebuffer,
tex: &Rc<dyn GfxTexture>,
render_hardware_cursor: bool,
) {
if let Some(workspace) = self.workspace.get() { if let Some(workspace) = self.workspace.get() {
if !workspace.capture.get() { if !workspace.capture.get() {
return; return;
} }
} }
self.global.perform_screencopies(fb, tex); self.global
.perform_screencopies(fb, tex, render_hardware_cursor);
for sc in self.screencasts.lock().values() { for sc in self.screencasts.lock().values() {
sc.copy_texture(self, tex); sc.copy_texture(self, tex, render_hardware_cursor);
} }
} }