video: render hardware cursor in screencasts
This commit is contained in:
parent
d4fc672fb3
commit
4d8e744c2f
4 changed files with 86 additions and 10 deletions
|
|
@ -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 _,
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
50
src/state.rs
50
src/state.rs
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue