kms/surface: Split off part of redraw into a send_screencopy_result
This should not change behavior in any way.
This commit is contained in:
parent
e94377f4de
commit
39b1ac2955
1 changed files with 265 additions and 260 deletions
|
|
@ -22,10 +22,18 @@ use anyhow::{Context, Result};
|
||||||
use calloop::channel::Channel;
|
use calloop::channel::Channel;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
allocator::{format::FormatSet, gbm::GbmAllocator, Fourcc},
|
allocator::{
|
||||||
|
format::FormatSet,
|
||||||
|
gbm::{GbmAllocator, GbmBuffer},
|
||||||
|
Fourcc,
|
||||||
|
},
|
||||||
drm::{
|
drm::{
|
||||||
compositor::{BlitFrameResultError, FrameError, FrameFlags, PrimaryPlaneElement},
|
compositor::{
|
||||||
|
BlitFrameResultError, FrameError, FrameFlags, PrimaryPlaneElement,
|
||||||
|
RenderFrameResult,
|
||||||
|
},
|
||||||
exporter::gbm::GbmFramebufferExporter,
|
exporter::gbm::GbmFramebufferExporter,
|
||||||
|
gbm::GbmFramebuffer,
|
||||||
output::DrmOutput,
|
output::DrmOutput,
|
||||||
DrmDeviceFd, DrmEventMetadata, DrmEventTime, DrmNode, VrrSupport,
|
DrmDeviceFd, DrmEventMetadata, DrmEventTime, DrmNode, VrrSupport,
|
||||||
},
|
},
|
||||||
|
|
@ -223,6 +231,14 @@ pub enum SurfaceCommand {
|
||||||
RenderStates(RenderElementStates),
|
RenderStates(RenderElementStates),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct PrePostprocessData {
|
||||||
|
states: Option<RenderElementStates>,
|
||||||
|
texture: Option<GlesTexture>,
|
||||||
|
cursor_texture: Option<GlesTexture>,
|
||||||
|
cursor_geometry: Option<Rectangle<i32, Physical>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Surface {
|
impl Surface {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
output: &Output,
|
output: &Output,
|
||||||
|
|
@ -1107,14 +1123,6 @@ impl SurfaceThreadState {
|
||||||
|| !self.screen_filter.is_noop()
|
|| !self.screen_filter.is_noop()
|
||||||
});
|
});
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
struct PrePostprocessData {
|
|
||||||
states: Option<RenderElementStates>,
|
|
||||||
texture: Option<GlesTexture>,
|
|
||||||
cursor_texture: Option<GlesTexture>,
|
|
||||||
cursor_geometry: Option<Rectangle<i32, Physical>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut pre_postprocess_data = PrePostprocessData::default();
|
let mut pre_postprocess_data = PrePostprocessData::default();
|
||||||
|
|
||||||
let res = if let Some(source_output) = source_output {
|
let res = if let Some(source_output) = source_output {
|
||||||
|
|
@ -1454,257 +1462,18 @@ impl SurfaceThreadState {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (session, frame, res) in frames {
|
let now = self.clock.now();
|
||||||
let damage = match res {
|
for frame in frames {
|
||||||
Ok((damage, _)) => damage,
|
send_screencopy_result(
|
||||||
Err(err) => {
|
|
||||||
tracing::warn!(?err, "Failed to screencopy");
|
|
||||||
session
|
|
||||||
.user_data()
|
|
||||||
.get::<SessionData>()
|
|
||||||
.unwrap()
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.reset();
|
|
||||||
frame.fail(FailureReason::Unknown);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut sync = SyncPoint::default();
|
|
||||||
let mut dmabuf_clone;
|
|
||||||
let mut render_buffer;
|
|
||||||
let buffer = frame.buffer();
|
|
||||||
let mut shm_buffer = false;
|
|
||||||
let mut fb = if let Ok(dmabuf) = get_dmabuf(&buffer) {
|
|
||||||
dmabuf_clone = dmabuf.clone();
|
|
||||||
Some(renderer
|
|
||||||
.bind(&mut dmabuf_clone)
|
|
||||||
.map_err(RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering)?)
|
|
||||||
} else {
|
|
||||||
shm_buffer = true;
|
|
||||||
let size = buffer_dimensions(&buffer).ok_or(RenderError::<
|
|
||||||
<GlMultiRenderer as RendererSuper>::Error,
|
|
||||||
>::Rendering(
|
|
||||||
MultiError::ImportFailed,
|
|
||||||
))?;
|
|
||||||
let format =
|
|
||||||
with_buffer_contents(&buffer, |_, _, data| shm_format_to_fourcc(data.format))
|
|
||||||
.map_err(|_| OutputNoMode)? // eh, we have to do some error
|
|
||||||
.expect("We should be able to convert all hardcoded shm screencopy formats");
|
|
||||||
|
|
||||||
if pre_postprocess_data
|
|
||||||
.texture
|
|
||||||
.as_ref()
|
|
||||||
.is_some_and(|tex| tex.format() == Some(format))
|
|
||||||
&& (session.draw_cursor() == false
|
|
||||||
|| pre_postprocess_data.cursor_texture.is_none())
|
|
||||||
{
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
render_buffer =
|
|
||||||
Offscreen::<GlesRenderbuffer>::create_buffer(
|
|
||||||
&mut renderer,
|
|
||||||
format,
|
|
||||||
size,
|
|
||||||
)
|
|
||||||
.map_err(RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering)?;
|
|
||||||
Some(renderer
|
|
||||||
.bind(&mut render_buffer)
|
|
||||||
.map_err(RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering)?)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(ref damage) = damage {
|
|
||||||
let (output_size, output_scale, output_transform) = (
|
|
||||||
self.output.current_mode().ok_or(OutputNoMode)?.size,
|
|
||||||
self.output.current_scale().fractional_scale(),
|
|
||||||
self.output.current_transform(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let filter = (!session.draw_cursor())
|
|
||||||
.then(|| {
|
|
||||||
elements.iter().filter_map(|elem| {
|
|
||||||
if let CosmicElement::Cursor(_) = elem {
|
|
||||||
Some(elem.id().clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.into_iter()
|
|
||||||
.flatten();
|
|
||||||
|
|
||||||
// If the screen is rotated, we must convert damage to match output.
|
|
||||||
let adjusted = damage
|
|
||||||
.iter()
|
|
||||||
.copied()
|
|
||||||
.map(|mut d| {
|
|
||||||
d.size = d
|
|
||||||
.size
|
|
||||||
.to_logical(1)
|
|
||||||
.to_buffer(1, output_transform)
|
|
||||||
.to_logical(1, Transform::Normal)
|
|
||||||
.to_physical(1);
|
|
||||||
d
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
if let Some(tex) = pre_postprocess_data.texture.as_mut() {
|
|
||||||
let mut tex_fb = renderer.bind(tex).map_err(RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering)?;
|
|
||||||
|
|
||||||
if let Some(fb) = fb.as_mut() {
|
|
||||||
for rect in adjusted.iter().copied() {
|
|
||||||
renderer
|
|
||||||
.blit(
|
|
||||||
&mut tex_fb,
|
|
||||||
fb,
|
|
||||||
rect,
|
|
||||||
rect,
|
|
||||||
TextureFilter::Linear,
|
|
||||||
)
|
|
||||||
.map_err(
|
|
||||||
RenderError::<
|
|
||||||
<GlMultiRenderer as RendererSuper>::Error,
|
|
||||||
>::Rendering,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
if let Some(cursor_geometry) = pre_postprocess_data
|
|
||||||
.cursor_geometry
|
|
||||||
.as_ref()
|
|
||||||
.filter(|_| session.draw_cursor())
|
|
||||||
{
|
|
||||||
let cursor_damage = adjusted
|
|
||||||
.iter()
|
|
||||||
.filter_map(|rect| {
|
|
||||||
cursor_geometry.intersection(*rect)
|
|
||||||
})
|
|
||||||
.map(|rect| {
|
|
||||||
Rectangle::new(
|
|
||||||
rect.loc - cursor_geometry.loc,
|
|
||||||
rect.size,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let mut frame = renderer
|
|
||||||
.render(fb, output_size, output_transform)
|
|
||||||
.map_err(
|
|
||||||
RenderError::<
|
|
||||||
<GlMultiRenderer as RendererSuper>::Error,
|
|
||||||
>::Rendering,
|
|
||||||
)?;
|
|
||||||
frame
|
|
||||||
.as_mut()
|
|
||||||
.render_texture_from_to(
|
|
||||||
pre_postprocess_data
|
|
||||||
.cursor_texture
|
|
||||||
.as_ref()
|
|
||||||
.unwrap(),
|
|
||||||
Rectangle::new(
|
|
||||||
Point::from((0., 0.)),
|
|
||||||
cursor_geometry
|
|
||||||
.size
|
|
||||||
.to_logical(1)
|
|
||||||
.to_buffer(1, Transform::Normal)
|
|
||||||
.to_f64(),
|
|
||||||
),
|
|
||||||
*cursor_geometry,
|
|
||||||
&cursor_damage,
|
|
||||||
&[*cursor_geometry],
|
|
||||||
Transform::Normal,
|
|
||||||
1.0,
|
|
||||||
)
|
|
||||||
.map_err(GlMultiError::Render)
|
|
||||||
.map_err(
|
|
||||||
RenderError::<
|
|
||||||
<GlMultiRenderer as RendererSuper>::Error,
|
|
||||||
>::Rendering,
|
|
||||||
)?;
|
|
||||||
let sync = frame.finish().map_err(
|
|
||||||
RenderError::<
|
|
||||||
<GlMultiRenderer as RendererSuper>::Error,
|
|
||||||
>::Rendering,
|
|
||||||
)?;
|
|
||||||
renderer.wait(&sync).map_err(
|
|
||||||
RenderError::<
|
|
||||||
<GlMultiRenderer as RendererSuper>::Error,
|
|
||||||
>::Rendering,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fb = Some(tex_fb);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
match frame_result
|
|
||||||
.blit_frame_result(
|
|
||||||
output_size,
|
|
||||||
output_transform,
|
|
||||||
output_scale,
|
|
||||||
&mut renderer,
|
|
||||||
fb.as_mut().unwrap(),
|
|
||||||
adjusted,
|
|
||||||
filter,
|
|
||||||
)
|
|
||||||
.map_err(|err| match err {
|
|
||||||
BlitFrameResultError::Rendering(err) => RenderError::<
|
|
||||||
<GlMultiRenderer as RendererSuper>::Error,
|
|
||||||
>::Rendering(
|
|
||||||
err
|
|
||||||
),
|
|
||||||
BlitFrameResultError::Export(_) => RenderError::<
|
|
||||||
<GlMultiRenderer as RendererSuper>::Error,
|
|
||||||
>::Rendering(
|
|
||||||
MultiError::DeviceMissing,
|
|
||||||
),
|
|
||||||
}) {
|
|
||||||
Ok(new_sync) => {
|
|
||||||
sync = new_sync;
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
tracing::warn!(?err, "Failed to screencopy");
|
|
||||||
session
|
|
||||||
.user_data()
|
|
||||||
.get::<SessionData>()
|
|
||||||
.unwrap()
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.reset();
|
|
||||||
frame.fail(FailureReason::Unknown);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let transform = self.output.current_transform();
|
|
||||||
|
|
||||||
match submit_buffer(
|
|
||||||
frame,
|
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
shm_buffer.then_some(fb.as_mut().unwrap()),
|
&self.output,
|
||||||
transform,
|
&mut pre_postprocess_data,
|
||||||
damage.as_deref(),
|
&tx,
|
||||||
sync,
|
&frame_result,
|
||||||
) {
|
&elements,
|
||||||
Ok(Some((frame, damage))) => {
|
frame,
|
||||||
if frame_result.is_empty {
|
now.into(),
|
||||||
frame.success(transform, damage, self.clock.now());
|
)?;
|
||||||
} else {
|
|
||||||
let _ = tx.send((frame, damage));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(None) => {}
|
|
||||||
Err(err) => {
|
|
||||||
session
|
|
||||||
.user_data()
|
|
||||||
.get::<SessionData>()
|
|
||||||
.unwrap()
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.reset();
|
|
||||||
tracing::warn!(?err, "Failed to screencopy");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.mirroring.is_none() {
|
if self.mirroring.is_none() {
|
||||||
|
|
@ -1941,3 +1710,239 @@ fn get_surface_dmabuf_feedback(
|
||||||
primary_scanout_feedback,
|
primary_scanout_feedback,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_screencopy_result<'a>(
|
||||||
|
renderer: &mut GlMultiRenderer<'a>,
|
||||||
|
output: &Output,
|
||||||
|
pre_postprocess_data: &mut PrePostprocessData,
|
||||||
|
tx: &std::sync::mpsc::Sender<(ScreencopyFrame, Vec<Rectangle<i32, BufferCoords>>)>,
|
||||||
|
frame_result: &RenderFrameResult<GbmBuffer, GbmFramebuffer, CosmicElement<GlMultiRenderer<'a>>>,
|
||||||
|
elements: &[CosmicElement<GlMultiRenderer>],
|
||||||
|
(session, frame, res): (
|
||||||
|
ScreencopySessionRef,
|
||||||
|
ScreencopyFrame,
|
||||||
|
Result<(Option<Vec<Rectangle<i32, Physical>>>, RenderElementStates), OutputNoMode>,
|
||||||
|
),
|
||||||
|
presentation_time: Duration,
|
||||||
|
) -> Result<()> {
|
||||||
|
let damage = match res {
|
||||||
|
Ok((damage, _)) => damage,
|
||||||
|
Err(err) => {
|
||||||
|
tracing::warn!(?err, "Failed to screencopy");
|
||||||
|
session
|
||||||
|
.user_data()
|
||||||
|
.get::<SessionData>()
|
||||||
|
.unwrap()
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.reset();
|
||||||
|
frame.fail(FailureReason::Unknown);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut sync = SyncPoint::default();
|
||||||
|
let mut dmabuf_clone;
|
||||||
|
let mut render_buffer;
|
||||||
|
let buffer = frame.buffer();
|
||||||
|
let mut shm_buffer = false;
|
||||||
|
let mut fb = if let Ok(dmabuf) = get_dmabuf(&buffer) {
|
||||||
|
dmabuf_clone = dmabuf.clone();
|
||||||
|
Some(
|
||||||
|
renderer
|
||||||
|
.bind(&mut dmabuf_clone)
|
||||||
|
.map_err(RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering)?,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
shm_buffer = true;
|
||||||
|
let size =
|
||||||
|
buffer_dimensions(&buffer).ok_or(RenderError::<
|
||||||
|
<GlMultiRenderer as RendererSuper>::Error,
|
||||||
|
>::Rendering(MultiError::ImportFailed))?;
|
||||||
|
let format = with_buffer_contents(&buffer, |_, _, data| shm_format_to_fourcc(data.format))
|
||||||
|
.map_err(|_| OutputNoMode)? // eh, we have to do some error
|
||||||
|
.expect("We should be able to convert all hardcoded shm screencopy formats");
|
||||||
|
|
||||||
|
if pre_postprocess_data
|
||||||
|
.texture
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|tex| tex.format() == Some(format))
|
||||||
|
&& (session.draw_cursor() == false || pre_postprocess_data.cursor_texture.is_none())
|
||||||
|
{
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
render_buffer = Offscreen::<GlesRenderbuffer>::create_buffer(renderer, format, size)
|
||||||
|
.map_err(RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering)?;
|
||||||
|
Some(
|
||||||
|
renderer
|
||||||
|
.bind(&mut render_buffer)
|
||||||
|
.map_err(RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering)?,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(ref damage) = damage {
|
||||||
|
let (output_size, output_scale, output_transform) = (
|
||||||
|
output.current_mode().ok_or(OutputNoMode)?.size,
|
||||||
|
output.current_scale().fractional_scale(),
|
||||||
|
output.current_transform(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let filter = (!session.draw_cursor())
|
||||||
|
.then(|| {
|
||||||
|
elements.iter().filter_map(|elem| {
|
||||||
|
if let CosmicElement::Cursor(_) = elem {
|
||||||
|
Some(elem.id().clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.into_iter()
|
||||||
|
.flatten();
|
||||||
|
|
||||||
|
// If the screen is rotated, we must convert damage to match output.
|
||||||
|
let adjusted = damage
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.map(|mut d| {
|
||||||
|
d.size = d
|
||||||
|
.size
|
||||||
|
.to_logical(1)
|
||||||
|
.to_buffer(1, output_transform)
|
||||||
|
.to_logical(1, Transform::Normal)
|
||||||
|
.to_physical(1);
|
||||||
|
d
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if let Some(tex) = pre_postprocess_data.texture.as_mut() {
|
||||||
|
let mut tex_fb = renderer
|
||||||
|
.bind(tex)
|
||||||
|
.map_err(RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering)?;
|
||||||
|
|
||||||
|
if let Some(fb) = fb.as_mut() {
|
||||||
|
for rect in adjusted.iter().copied() {
|
||||||
|
renderer
|
||||||
|
.blit(&mut tex_fb, fb, rect, rect, TextureFilter::Linear)
|
||||||
|
.map_err(
|
||||||
|
RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
if let Some(cursor_geometry) = pre_postprocess_data
|
||||||
|
.cursor_geometry
|
||||||
|
.as_ref()
|
||||||
|
.filter(|_| session.draw_cursor())
|
||||||
|
{
|
||||||
|
let cursor_damage = adjusted
|
||||||
|
.iter()
|
||||||
|
.filter_map(|rect| cursor_geometry.intersection(*rect))
|
||||||
|
.map(|rect| Rectangle::new(rect.loc - cursor_geometry.loc, rect.size))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let mut frame = renderer.render(fb, output_size, output_transform).map_err(
|
||||||
|
RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering,
|
||||||
|
)?;
|
||||||
|
frame
|
||||||
|
.as_mut()
|
||||||
|
.render_texture_from_to(
|
||||||
|
pre_postprocess_data.cursor_texture.as_ref().unwrap(),
|
||||||
|
Rectangle::new(
|
||||||
|
Point::from((0., 0.)),
|
||||||
|
cursor_geometry
|
||||||
|
.size
|
||||||
|
.to_logical(1)
|
||||||
|
.to_buffer(1, Transform::Normal)
|
||||||
|
.to_f64(),
|
||||||
|
),
|
||||||
|
*cursor_geometry,
|
||||||
|
&cursor_damage,
|
||||||
|
&[*cursor_geometry],
|
||||||
|
Transform::Normal,
|
||||||
|
1.0,
|
||||||
|
)
|
||||||
|
.map_err(GlMultiError::Render)
|
||||||
|
.map_err(
|
||||||
|
RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering,
|
||||||
|
)?;
|
||||||
|
let sync = frame.finish().map_err(
|
||||||
|
RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering,
|
||||||
|
)?;
|
||||||
|
renderer.wait(&sync).map_err(
|
||||||
|
RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fb = Some(tex_fb);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match frame_result
|
||||||
|
.blit_frame_result(
|
||||||
|
output_size,
|
||||||
|
output_transform,
|
||||||
|
output_scale,
|
||||||
|
renderer,
|
||||||
|
fb.as_mut().unwrap(),
|
||||||
|
adjusted,
|
||||||
|
filter,
|
||||||
|
)
|
||||||
|
.map_err(|err| match err {
|
||||||
|
BlitFrameResultError::Rendering(err) => {
|
||||||
|
RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering(err)
|
||||||
|
}
|
||||||
|
BlitFrameResultError::Export(_) => {
|
||||||
|
RenderError::<<GlMultiRenderer as RendererSuper>::Error>::Rendering(
|
||||||
|
MultiError::DeviceMissing,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Ok(new_sync) => {
|
||||||
|
sync = new_sync;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
tracing::warn!(?err, "Failed to screencopy");
|
||||||
|
session
|
||||||
|
.user_data()
|
||||||
|
.get::<SessionData>()
|
||||||
|
.unwrap()
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.reset();
|
||||||
|
frame.fail(FailureReason::Unknown);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let transform = output.current_transform();
|
||||||
|
|
||||||
|
match submit_buffer(
|
||||||
|
frame,
|
||||||
|
renderer,
|
||||||
|
shm_buffer.then_some(fb.as_mut().unwrap()),
|
||||||
|
transform,
|
||||||
|
damage.as_deref(),
|
||||||
|
sync,
|
||||||
|
) {
|
||||||
|
Ok(Some((frame, damage))) => {
|
||||||
|
if frame_result.is_empty {
|
||||||
|
frame.success(transform, damage, presentation_time);
|
||||||
|
} else {
|
||||||
|
let _ = tx.send((frame, damage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(None) => {}
|
||||||
|
Err(err) => {
|
||||||
|
session
|
||||||
|
.user_data()
|
||||||
|
.get::<SessionData>()
|
||||||
|
.unwrap()
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.reset();
|
||||||
|
tracing::warn!(?err, "Failed to screencopy");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue