Define a RendererRef enum, referencing multi or glow renderer
Avoids a little duplication (matching two variants, instead of three backends). The behavior, including errors and panics, should be unchanged for now. Performance should also not be impacted. This should help for adding llvmpipe rendering without a device node on the kms backend, or for adding a variant for pixman.
This commit is contained in:
parent
4748916ff9
commit
87020c79ba
5 changed files with 215 additions and 233 deletions
|
|
@ -53,6 +53,7 @@ use smithay::{
|
|||
element::PixelShaderElement, GlesError, GlesPixelProgram, GlesRenderer, Uniform,
|
||||
UniformName, UniformType,
|
||||
},
|
||||
glow::GlowRenderer,
|
||||
multigpu::{Error as MultiError, MultiFrame, MultiRenderer},
|
||||
sync::SyncPoint,
|
||||
Bind, Blit, ExportMem, ImportAll, ImportMem, Offscreen, Renderer, TextureFilter,
|
||||
|
|
@ -86,6 +87,29 @@ pub type GlMultiFrame<'a, 'frame> =
|
|||
MultiFrame<'a, 'a, 'frame, GbmGlowBackend<DrmDeviceFd>, GbmGlowBackend<DrmDeviceFd>>;
|
||||
pub type GlMultiError = MultiError<GbmGlowBackend<DrmDeviceFd>, GbmGlowBackend<DrmDeviceFd>>;
|
||||
|
||||
pub enum RendererRef<'a> {
|
||||
Glow(&'a mut GlowRenderer),
|
||||
GlMulti(GlMultiRenderer<'a>),
|
||||
}
|
||||
|
||||
impl<'a> AsRef<GlowRenderer> for RendererRef<'a> {
|
||||
fn as_ref(&self) -> &GlowRenderer {
|
||||
match self {
|
||||
Self::Glow(renderer) => renderer,
|
||||
Self::GlMulti(renderer) => renderer.as_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AsMut<GlowRenderer> for RendererRef<'a> {
|
||||
fn as_mut(&mut self) -> &mut GlowRenderer {
|
||||
match self {
|
||||
Self::Glow(renderer) => renderer,
|
||||
Self::GlMulti(renderer) => renderer.as_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0];
|
||||
pub static OUTLINE_SHADER: &str = include_str!("./shaders/rounded_outline.frag");
|
||||
pub static RECTANGLE_SHADER: &str = include_str!("./shaders/rounded_rectangle.frag");
|
||||
|
|
|
|||
53
src/state.rs
53
src/state.rs
|
|
@ -1,7 +1,12 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::{
|
||||
backend::{kms::KmsState, winit::WinitState, x11::X11State},
|
||||
backend::{
|
||||
kms::KmsState,
|
||||
render::{GlMultiError, RendererRef},
|
||||
winit::WinitState,
|
||||
x11::X11State,
|
||||
},
|
||||
config::{Config, OutputConfig, OutputState},
|
||||
input::gestures::GestureState,
|
||||
shell::{grabs::SeatMoveGrabState, CosmicSurface, SeatExt, Shell},
|
||||
|
|
@ -26,7 +31,7 @@ use once_cell::sync::Lazy;
|
|||
use rust_embed::RustEmbed;
|
||||
use smithay::{
|
||||
backend::{
|
||||
allocator::dmabuf::Dmabuf,
|
||||
allocator::{dmabuf::Dmabuf, Fourcc},
|
||||
drm::DrmNode,
|
||||
renderer::{
|
||||
element::{
|
||||
|
|
@ -380,6 +385,50 @@ impl BackendData {
|
|||
};
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Get an offscreen renderer for screen capture / screenshot rendering
|
||||
///
|
||||
/// `kms_node_cb` callback use used to determine nodes to render with when using kms backend.
|
||||
/// Panics if this returns `None`.
|
||||
pub fn offscreen_renderer<N: Into<KmsNodes>, F: FnOnce(&mut KmsState) -> Option<N>>(
|
||||
&mut self,
|
||||
kms_node_cb: F,
|
||||
) -> Result<RendererRef, GlMultiError> {
|
||||
match self {
|
||||
BackendData::Kms(kms) => {
|
||||
let KmsNodes {
|
||||
render_node,
|
||||
target_node,
|
||||
copy_format,
|
||||
} = kms_node_cb(kms).expect("No Software Rendering").into();
|
||||
Ok(RendererRef::GlMulti(kms.api.renderer(
|
||||
&render_node,
|
||||
&target_node,
|
||||
copy_format,
|
||||
)?))
|
||||
}
|
||||
BackendData::Winit(winit) => Ok(RendererRef::Glow(winit.backend.renderer())),
|
||||
BackendData::X11(x11) => Ok(RendererRef::Glow(&mut x11.renderer)),
|
||||
_ => unreachable!("No backend set when getting offscreen renderer"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct KmsNodes {
|
||||
pub render_node: DrmNode,
|
||||
pub target_node: DrmNode,
|
||||
pub copy_format: Fourcc,
|
||||
}
|
||||
|
||||
impl From<DrmNode> for KmsNodes {
|
||||
fn from(node: DrmNode) -> Self {
|
||||
KmsNodes {
|
||||
render_node: node,
|
||||
target_node: node,
|
||||
// Ignored if render == target
|
||||
copy_format: Fourcc::Abgr8888,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn client_has_no_security_context(client: &Client) -> bool {
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@ use smithay::{
|
|||
use tracing::warn;
|
||||
|
||||
use crate::{
|
||||
backend::render::RendererRef,
|
||||
shell::element::CosmicSurface,
|
||||
state::{advertised_node_for_surface, BackendData, State},
|
||||
state::{advertised_node_for_surface, State},
|
||||
};
|
||||
|
||||
pub fn screenshot_window(state: &mut State, surface: &CosmicSurface) {
|
||||
|
|
@ -96,27 +97,21 @@ pub fn screenshot_window(state: &mut State, surface: &CosmicSurface) {
|
|||
}
|
||||
|
||||
if let Some(wl_surface) = surface.wl_surface() {
|
||||
let res = match &mut state.backend {
|
||||
BackendData::Kms(kms) => {
|
||||
let node = advertised_node_for_surface(&wl_surface, &state.common.display_handle)
|
||||
.unwrap_or(kms.primary_node.expect("No Software Rendering"));
|
||||
kms.api
|
||||
.single_renderer(&node)
|
||||
.with_context(|| "Failed to get renderer for screenshot")
|
||||
.and_then(|mut multirenderer| {
|
||||
render_window(&mut multirenderer, surface, &state.common.local_offset)
|
||||
})
|
||||
}
|
||||
BackendData::Winit(winit) => render_window(
|
||||
winit.backend.renderer(),
|
||||
surface,
|
||||
&state.common.local_offset,
|
||||
),
|
||||
BackendData::X11(x11) => {
|
||||
render_window(&mut x11.renderer, surface, &state.common.local_offset)
|
||||
}
|
||||
BackendData::Unset => unreachable!(),
|
||||
};
|
||||
let res = state
|
||||
.backend
|
||||
.offscreen_renderer(|kms| {
|
||||
advertised_node_for_surface(&wl_surface, &state.common.display_handle)
|
||||
.or(kms.primary_node)
|
||||
})
|
||||
.with_context(|| "Failed to get renderer for screenshot")
|
||||
.and_then(|renderer| match renderer {
|
||||
RendererRef::Glow(renderer) => {
|
||||
render_window(renderer, surface, &state.common.local_offset)
|
||||
}
|
||||
RendererRef::GlMulti(mut renderer) => {
|
||||
render_window(&mut renderer, surface, &state.common.local_offset)
|
||||
}
|
||||
});
|
||||
if let Err(err) = res {
|
||||
warn!(?err, "Failed to take screenshot")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -351,21 +351,10 @@ fn constraints_for_output(output: &Output, backend: &mut BackendData) -> Option<
|
|||
}
|
||||
};
|
||||
|
||||
let mut _kms_renderer = None;
|
||||
let renderer = match backend {
|
||||
BackendData::Kms(ref mut kms) => {
|
||||
let node = kms
|
||||
.target_node_for_output(&output)
|
||||
.unwrap_or(kms.primary_node.expect("No Software Rendering"));
|
||||
_kms_renderer = Some(kms.api.single_renderer(&node).unwrap());
|
||||
_kms_renderer.as_mut().unwrap().as_mut()
|
||||
}
|
||||
BackendData::Winit(ref mut winit) => winit.backend.renderer(),
|
||||
BackendData::X11(ref mut x11) => &mut x11.renderer,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Some(constraints_for_renderer(mode, renderer))
|
||||
let mut renderer = backend
|
||||
.offscreen_renderer(|kms| kms.target_node_for_output(&output).or(kms.primary_node))
|
||||
.unwrap();
|
||||
Some(constraints_for_renderer(mode, renderer.as_mut()))
|
||||
}
|
||||
|
||||
fn constraints_for_toplevel(
|
||||
|
|
@ -375,9 +364,8 @@ fn constraints_for_toplevel(
|
|||
let size = surface.geometry().size.to_buffer(1, Transform::Normal);
|
||||
let wl_surface = surface.wl_surface()?;
|
||||
|
||||
let mut _kms_renderer = None;
|
||||
let renderer = match backend {
|
||||
BackendData::Kms(ref mut kms) => {
|
||||
let mut renderer = backend
|
||||
.offscreen_renderer(|kms| {
|
||||
let dma_node = with_renderer_surface_state(&wl_surface, |state| {
|
||||
let buffer = state.buffer()?;
|
||||
let dmabuf = get_dmabuf(&*buffer).ok()?;
|
||||
|
|
@ -385,16 +373,11 @@ fn constraints_for_toplevel(
|
|||
})
|
||||
.flatten();
|
||||
|
||||
let node = dma_node.unwrap_or(kms.primary_node.expect("No Software Rendering"));
|
||||
_kms_renderer = Some(kms.api.single_renderer(&node).unwrap());
|
||||
_kms_renderer.as_mut().unwrap().as_mut()
|
||||
}
|
||||
BackendData::Winit(ref mut winit) => winit.backend.renderer(),
|
||||
BackendData::X11(ref mut x11) => &mut x11.renderer,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
dma_node.or(kms.primary_node)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Some(constraints_for_renderer(size, renderer))
|
||||
Some(constraints_for_renderer(size, renderer.as_mut()))
|
||||
}
|
||||
|
||||
fn constraints_for_renderer(
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@ use crate::{
|
|||
backend::render::{
|
||||
cursor,
|
||||
element::{AsGlowRenderer, CosmicElement, DamageElement, FromGlesError},
|
||||
render_workspace, CursorMode, ElementFilter, CLEAR_COLOR,
|
||||
render_workspace, CursorMode, ElementFilter, RendererRef, CLEAR_COLOR,
|
||||
},
|
||||
shell::{CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement},
|
||||
state::{BackendData, Common, State},
|
||||
state::{Common, KmsNodes, State},
|
||||
utils::prelude::SeatExt,
|
||||
wayland::{
|
||||
handlers::screencopy::{
|
||||
|
|
@ -326,39 +326,39 @@ pub fn render_workspace_to_buffer(
|
|||
let transform = output.current_transform();
|
||||
let common = &mut state.common;
|
||||
|
||||
let result = match &mut state.backend {
|
||||
BackendData::Kms(kms) => {
|
||||
let render_node = kms
|
||||
.target_node_for_output(&output)
|
||||
.unwrap_or(kms.primary_node.expect("No Software Rendering"));
|
||||
let target_node = get_dmabuf(&buffer)
|
||||
.ok()
|
||||
.and_then(|dma| dma.node())
|
||||
.unwrap_or(render_node);
|
||||
let renderer = match state.backend.offscreen_renderer(|kms| {
|
||||
let render_node = kms.target_node_for_output(&output).or(kms.primary_node)?;
|
||||
let target_node = get_dmabuf(&buffer)
|
||||
.ok()
|
||||
.and_then(|dma| dma.node())
|
||||
.unwrap_or(render_node);
|
||||
|
||||
let buffer_format = match buffer_type(&buffer) {
|
||||
Some(BufferType::Dma) => Some(get_dmabuf(&buffer).unwrap().format().code),
|
||||
Some(BufferType::Shm) => {
|
||||
with_buffer_contents(&buffer, |_, _, data| shm_format_to_fourcc(data.format))
|
||||
.unwrap()
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let mut multirenderer = match kms.api.renderer(
|
||||
&render_node,
|
||||
&target_node,
|
||||
buffer_format.unwrap_or(Fourcc::Abgr8888),
|
||||
) {
|
||||
Ok(renderer) => renderer,
|
||||
Err(err) => {
|
||||
warn!(?err, "Couldn't use nodes for screencopy");
|
||||
frame.fail(FailureReason::Unknown);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let buffer_format = match buffer_type(&buffer) {
|
||||
Some(BufferType::Dma) => Some(get_dmabuf(&buffer).unwrap().format().code),
|
||||
Some(BufferType::Shm) => {
|
||||
with_buffer_contents(&buffer, |_, _, data| shm_format_to_fourcc(data.format))
|
||||
.unwrap()
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
Some(KmsNodes {
|
||||
render_node,
|
||||
target_node,
|
||||
copy_format: buffer_format.unwrap_or(Fourcc::Abgr8888),
|
||||
})
|
||||
}) {
|
||||
Ok(renderer) => renderer,
|
||||
Err(err) => {
|
||||
warn!(?err, "Couldn't use node for screencopy");
|
||||
frame.fail(FailureReason::Unknown);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let result = match renderer {
|
||||
RendererRef::Glow(renderer) => {
|
||||
match render_session::<_, _>(
|
||||
&mut multirenderer,
|
||||
renderer,
|
||||
session.user_data().get::<SessionData>().unwrap(),
|
||||
frame,
|
||||
transform,
|
||||
|
|
@ -383,57 +383,33 @@ pub fn render_workspace_to_buffer(
|
|||
}
|
||||
}
|
||||
}
|
||||
BackendData::Winit(winit) => match render_session::<_, _>(
|
||||
winit.backend.renderer(),
|
||||
session.user_data().get::<SessionData>().unwrap(),
|
||||
frame,
|
||||
transform,
|
||||
|buffer, renderer, dt, age, additional_damage| {
|
||||
render_fn(
|
||||
buffer,
|
||||
renderer,
|
||||
dt,
|
||||
age,
|
||||
additional_damage,
|
||||
draw_cursor,
|
||||
common,
|
||||
&output,
|
||||
(handle, idx),
|
||||
)
|
||||
},
|
||||
) {
|
||||
Ok(frame) => frame,
|
||||
Err(err) => {
|
||||
tracing::warn!(?err, "Failed to render to screencopy buffer");
|
||||
None
|
||||
RendererRef::GlMulti(mut renderer) => {
|
||||
match render_session::<_, _>(
|
||||
&mut renderer,
|
||||
session.user_data().get::<SessionData>().unwrap(),
|
||||
frame,
|
||||
transform,
|
||||
|buffer, renderer, dt, age, additional_damage| {
|
||||
render_fn(
|
||||
buffer,
|
||||
renderer,
|
||||
dt,
|
||||
age,
|
||||
additional_damage,
|
||||
draw_cursor,
|
||||
common,
|
||||
&output,
|
||||
(handle, idx),
|
||||
)
|
||||
},
|
||||
) {
|
||||
Ok(frame) => frame,
|
||||
Err(err) => {
|
||||
tracing::warn!(?err, "Failed to render to screencopy buffer");
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
BackendData::X11(x11) => match render_session::<_, _>(
|
||||
&mut x11.renderer,
|
||||
session.user_data().get::<SessionData>().unwrap(),
|
||||
frame,
|
||||
transform,
|
||||
|buffer, renderer, dt, age, additional_damage| {
|
||||
render_fn(
|
||||
buffer,
|
||||
renderer,
|
||||
dt,
|
||||
age,
|
||||
additional_damage,
|
||||
draw_cursor,
|
||||
common,
|
||||
&output,
|
||||
(handle, idx),
|
||||
)
|
||||
},
|
||||
) {
|
||||
Ok(frame) => frame,
|
||||
Err(err) => {
|
||||
tracing::warn!(?err, "Failed to render to screencopy buffer");
|
||||
None
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
};
|
||||
|
||||
if let Some((frame, damage)) = result {
|
||||
|
|
@ -601,61 +577,34 @@ pub fn render_window_to_buffer(
|
|||
let common = &mut state.common;
|
||||
let draw_cursor = session.draw_cursor();
|
||||
|
||||
let result = match &mut state.backend {
|
||||
BackendData::Kms(kms) => {
|
||||
let node = get_dmabuf(&buffer)
|
||||
.ok()
|
||||
.and_then(|dmabuf| dmabuf.node())
|
||||
.or_else(|| {
|
||||
toplevel
|
||||
.wl_surface()
|
||||
.and_then(|wl_surface| {
|
||||
with_renderer_surface_state(&wl_surface, |state| {
|
||||
let buffer = state.buffer()?;
|
||||
let dmabuf = get_dmabuf(&*buffer).ok()?;
|
||||
dmabuf.node()
|
||||
})
|
||||
let renderer = match state.backend.offscreen_renderer(|kms| {
|
||||
get_dmabuf(&buffer)
|
||||
.ok()
|
||||
.and_then(|dmabuf| dmabuf.node())
|
||||
.or_else(|| {
|
||||
toplevel
|
||||
.wl_surface()
|
||||
.and_then(|wl_surface| {
|
||||
with_renderer_surface_state(&wl_surface, |state| {
|
||||
let buffer = state.buffer()?;
|
||||
let dmabuf = get_dmabuf(&*buffer).ok()?;
|
||||
dmabuf.node()
|
||||
})
|
||||
.flatten()
|
||||
})
|
||||
.unwrap_or(kms.primary_node.expect("No Software Rendering"));
|
||||
|
||||
let mut multirenderer = match kms.api.single_renderer(&node) {
|
||||
Ok(renderer) => renderer,
|
||||
Err(err) => {
|
||||
warn!(?err, "Couldn't use node for screencopy");
|
||||
frame.fail(FailureReason::Unknown);
|
||||
return;
|
||||
}
|
||||
};
|
||||
match render_session::<_, _>(
|
||||
&mut multirenderer,
|
||||
session.user_data().get::<SessionData>().unwrap(),
|
||||
frame,
|
||||
Transform::Normal,
|
||||
|buffer, renderer, dt, age, additional_damage| {
|
||||
render_fn(
|
||||
buffer,
|
||||
renderer,
|
||||
dt,
|
||||
age,
|
||||
additional_damage,
|
||||
draw_cursor,
|
||||
common,
|
||||
toplevel,
|
||||
geometry,
|
||||
)
|
||||
},
|
||||
) {
|
||||
Ok(frame) => frame,
|
||||
Err(err) => {
|
||||
tracing::warn!(?err, "Failed to render to screencopy buffer");
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
})
|
||||
.or(kms.primary_node)
|
||||
}) {
|
||||
Ok(renderer) => renderer,
|
||||
Err(err) => {
|
||||
warn!(?err, "Couldn't use node for screencopy");
|
||||
frame.fail(FailureReason::Unknown);
|
||||
return;
|
||||
}
|
||||
BackendData::Winit(winit) => match render_session::<_, _>(
|
||||
winit.backend.renderer(),
|
||||
};
|
||||
let result = match renderer {
|
||||
RendererRef::Glow(renderer) => match render_session::<_, _>(
|
||||
renderer,
|
||||
session.user_data().get::<SessionData>().unwrap(),
|
||||
frame,
|
||||
Transform::Normal,
|
||||
|
|
@ -679,8 +628,8 @@ pub fn render_window_to_buffer(
|
|||
None
|
||||
}
|
||||
},
|
||||
BackendData::X11(x11) => match render_session::<_, _>(
|
||||
&mut x11.renderer,
|
||||
RendererRef::GlMulti(mut renderer) => match render_session::<_, _>(
|
||||
&mut renderer,
|
||||
session.user_data().get::<SessionData>().unwrap(),
|
||||
frame,
|
||||
Transform::Normal,
|
||||
|
|
@ -704,7 +653,6 @@ pub fn render_window_to_buffer(
|
|||
None
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if let Some((frame, damage)) = result {
|
||||
|
|
@ -811,21 +759,18 @@ pub fn render_cursor_to_buffer(
|
|||
}
|
||||
|
||||
let common = &mut state.common;
|
||||
let result = match &mut state.backend {
|
||||
BackendData::Kms(kms) => {
|
||||
let mut multirenderer = match kms
|
||||
.api
|
||||
.single_renderer(&kms.primary_node.expect("No Software Rendering"))
|
||||
{
|
||||
Ok(renderer) => renderer,
|
||||
Err(err) => {
|
||||
warn!(?err, "Couldn't use node for screencopy");
|
||||
frame.fail(FailureReason::Unknown);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let renderer = match state.backend.offscreen_renderer(|kms| kms.primary_node) {
|
||||
Ok(renderer) => renderer,
|
||||
Err(err) => {
|
||||
warn!(?err, "Couldn't use node for screencopy");
|
||||
frame.fail(FailureReason::Unknown);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let result = match renderer {
|
||||
RendererRef::Glow(renderer) => {
|
||||
match render_session::<_, _>(
|
||||
&mut multirenderer,
|
||||
renderer,
|
||||
session.user_data().get::<SessionData>().unwrap(),
|
||||
frame,
|
||||
Transform::Normal,
|
||||
|
|
@ -840,37 +785,23 @@ pub fn render_cursor_to_buffer(
|
|||
}
|
||||
}
|
||||
}
|
||||
BackendData::Winit(winit) => match render_session::<_, _>(
|
||||
winit.backend.renderer(),
|
||||
session.user_data().get::<SessionData>().unwrap(),
|
||||
frame,
|
||||
Transform::Normal,
|
||||
|buffer, renderer, dt, age, additional_damage| {
|
||||
render_fn(buffer, renderer, dt, age, additional_damage, common, seat)
|
||||
},
|
||||
) {
|
||||
Ok(frame) => frame,
|
||||
Err(err) => {
|
||||
tracing::warn!(?err, "Failed to render to screencopy buffer");
|
||||
None
|
||||
RendererRef::GlMulti(mut renderer) => {
|
||||
match render_session::<_, _>(
|
||||
&mut renderer,
|
||||
session.user_data().get::<SessionData>().unwrap(),
|
||||
frame,
|
||||
Transform::Normal,
|
||||
|buffer, renderer, dt, age, additional_damage| {
|
||||
render_fn(buffer, renderer, dt, age, additional_damage, common, seat)
|
||||
},
|
||||
) {
|
||||
Ok(frame) => frame,
|
||||
Err(err) => {
|
||||
tracing::warn!(?err, "Failed to render to screencopy buffer");
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
BackendData::X11(x11) => match render_session::<_, _>(
|
||||
&mut x11.renderer,
|
||||
session.user_data().get::<SessionData>().unwrap(),
|
||||
frame,
|
||||
Transform::Normal,
|
||||
|buffer, renderer, dt, age, additional_damage| {
|
||||
render_fn(buffer, renderer, dt, age, additional_damage, common, seat)
|
||||
},
|
||||
) {
|
||||
Ok(frame) => frame,
|
||||
Err(err) => {
|
||||
tracing::warn!(?err, "Failed to render to screencopy buffer");
|
||||
None
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
};
|
||||
|
||||
if let Some((frame, damage)) = result {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue