kms: screencopy decouple
This commit is contained in:
parent
8943aa5a15
commit
18bac3e5ba
1 changed files with 38 additions and 54 deletions
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue