kms: screencopy decouple

This commit is contained in:
Victoria Brekenfeld 2023-05-02 17:24:18 +02:00
parent 8943aa5a15
commit 18bac3e5ba

View file

@ -19,13 +19,13 @@ use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::Fai
use smithay::{ use smithay::{
backend::{ backend::{
allocator::{ allocator::{
dmabuf::{AnyError, AsDmabuf, Dmabuf, DmabufAllocator}, dmabuf::{AnyError, Dmabuf, DmabufAllocator},
gbm::{GbmAllocator, GbmBufferFlags, GbmDevice}, gbm::{GbmAllocator, GbmBufferFlags, GbmDevice},
vulkan::{ImageUsageFlags, VulkanAllocator}, vulkan::{ImageUsageFlags, VulkanAllocator},
Allocator, Format, Fourcc, Allocator, Format, Fourcc,
}, },
drm::{ drm::{
compositor::{DrmCompositor, PrimaryPlaneElement}, compositor::{BlitFrameResultError, DrmCompositor, FrameError},
DrmDevice, DrmDeviceFd, DrmEvent, DrmEventTime, DrmNode, NodeType, DrmDevice, DrmDeviceFd, DrmEvent, DrmEventTime, DrmNode, NodeType,
}, },
egl::{EGLContext, EGLDevice, EGLDisplay}, egl::{EGLContext, EGLDevice, EGLDisplay},
@ -34,11 +34,11 @@ use smithay::{
renderer::{ renderer::{
buffer_dimensions, buffer_dimensions,
damage::{Error as RenderError, OutputNoMode}, damage::{Error as RenderError, OutputNoMode},
element::Element,
gles::{GlesRenderbuffer, GlesTexture}, gles::{GlesRenderbuffer, GlesTexture},
glow::GlowRenderer, glow::GlowRenderer,
multigpu::{gbm::GbmGlesBackend, Error as MultiError, GpuManager}, multigpu::{gbm::GbmGlesBackend, Error as MultiError, GpuManager},
utils::draw_render_elements, Bind, ImportDma, Offscreen,
Bind, Blit, ImportDma, Offscreen, Renderer, TextureFilter,
}, },
session::{libseat::LibSeatSession, Event as SessionEvent, Session}, session::{libseat::LibSeatSession, Event as SessionEvent, Session},
udev::{all_gpus, primary_gpu, UdevBackend, UdevEvent}, udev::{all_gpus, primary_gpu, UdevBackend, UdevEvent},
@ -1055,22 +1055,26 @@ impl Surface {
})?; })?;
self.fps.elements(); self.fps.elements();
let res = compositor.render_frame::<_, _, GlesTexture>( let res =
&mut renderer, compositor.render_frame::<_, _, GlesTexture>(&mut renderer, &elements, CLEAR_COLOR);
&elements,
CLEAR_COLOR,
);
self.fps.render(); self.fps.render();
match res { match res {
Ok(frame_result) => { Ok(frame_result) => {
let feedback = if frame_result.damage.is_some() {
Some(state.take_presentation_feedback(&self.output, &frame_result.states))
} else {
None
};
match compositor.queue_frame(feedback) {
Ok(()) | Err(FrameError::EmptyFrame) => {}
Err(err) => {
return Err(err).with_context(|| "Failed to submit result for display")
}
};
if let Some(screencopy) = screencopy { if let Some(screencopy) = screencopy {
let primary_element = frame_result.primary_element;
let mut plane_elements = frame_result
.cursor_element
.into_iter()
.chain(frame_result.overlay_elements.into_iter())
.collect::<Vec<_>>();
for (session, params) in screencopy { for (session, params) in screencopy {
match render_session( match render_session(
Some(*render_node), Some(*render_node),
@ -1085,7 +1089,9 @@ impl Surface {
if let Ok(dmabuf) = get_dmabuf(buffer) { if let Ok(dmabuf) = get_dmabuf(buffer) {
renderer.bind(dmabuf).map_err(RenderError::Rendering)?; renderer.bind(dmabuf).map_err(RenderError::Rendering)?;
} else { } else {
let size = buffer_dimensions(buffer).unwrap(); let size = buffer_dimensions(buffer).ok_or(
RenderError::Rendering(MultiError::ImportFailed),
)?;
let format = let format =
with_buffer_contents(buffer, |_, _, data| shm_format_to_fourcc(data.format)) with_buffer_contents(buffer, |_, _, data| shm_format_to_fourcc(data.format))
.map_err(|_| OutputNoMode)? // eh, we have to do some error .map_err(|_| OutputNoMode)? // eh, we have to do some error
@ -1099,43 +1105,30 @@ impl Surface {
.bind(render_buffer) .bind(render_buffer)
.map_err(RenderError::Rendering)?; .map_err(RenderError::Rendering)?;
} }
match primary_element {
PrimaryPlaneElement::Swapchain { slot, .. } => {
let source = slot.export().map_err(|_| {
// TODO AnyError::from
RenderError::Rendering(MultiError::ImportFailed)
})?;
for rect in damage {
renderer
.blit_from(
source.clone(),
*rect,
*rect,
TextureFilter::Nearest,
)
.map_err(RenderError::Rendering)?;
}
}
PrimaryPlaneElement::Element(e) => plane_elements.push(e),
};
let (output_size, output_scale, output_transform) = ( let (output_size, output_scale, output_transform) = (
self.output.current_mode().ok_or(OutputNoMode)?.size, self.output.current_mode().ok_or(OutputNoMode)?.size,
self.output.current_scale().fractional_scale(), self.output.current_scale().fractional_scale(),
self.output.current_transform(), self.output.current_transform(),
); );
{ frame_result
let mut frame = renderer .blit_frame_result(
.render(output_size, output_transform) output_size,
.map_err(RenderError::Rendering)?; output_transform,
draw_render_elements(
&mut frame,
output_scale, output_scale,
&plane_elements, renderer,
damage, damage.iter().copied(),
// TODO: Filter cursor element
elements.iter().map(|e| e.id().clone()),
) )
.map_err(RenderError::Rendering)?; .map_err(|err| match err {
} BlitFrameResultError::Rendering(err) => {
RenderError::Rendering(err)
}
BlitFrameResultError::Export(_) => {
RenderError::Rendering(MultiError::DeviceMissing)
}
})?;
} }
Ok(res) Ok(res)
@ -1152,12 +1145,6 @@ impl Surface {
self.fps.screencopy(); self.fps.screencopy();
} }
let feedback = if frame_result.damage.is_some() {
Some(state.take_presentation_feedback(&self.output, &frame_result.states))
} else {
None
};
state.send_frames(&self.output, &frame_result.states, |source_node| { state.send_frames(&self.output, &frame_result.states, |source_node| {
Some( Some(
self.feedback self.feedback
@ -1183,9 +1170,6 @@ impl Surface {
.clone(), .clone(),
) )
}); });
compositor
.queue_frame(feedback)
.with_context(|| "Failed to submit result for display")?
} }
Err(err) => { Err(err) => {
compositor.reset_buffers(); compositor.reset_buffers();