anvil: Do not throw rendering errors away

This commit is contained in:
Victor Brekenfeld 2021-04-29 00:02:17 +02:00
parent 795903d7e0
commit ccd86cd8c1
3 changed files with 54 additions and 45 deletions

View File

@ -32,10 +32,10 @@ pub fn draw_cursor<R, E, T>(
(x, y): (i32, i32), (x, y): (i32, i32),
token: MyCompositorToken, token: MyCompositorToken,
log: &Logger, log: &Logger,
) ) -> Result<(), SwapBuffersError>
where where
R: Renderer<Error=E, TextureId=T>, R: Renderer<Error=E, TextureId=T>,
E: std::error::Error, E: std::error::Error + Into<SwapBuffersError>,
T: Texture + 'static, T: Texture + 'static,
{ {
let (dx, dy) = match token.with_role_data::<CursorImageRole, _, _>(surface, |data| data.hotspot) { let (dx, dy) = match token.with_role_data::<CursorImageRole, _, _>(surface, |data| data.hotspot) {
@ -48,7 +48,7 @@ pub fn draw_cursor<R, E, T>(
(0, 0) (0, 0)
} }
}; };
draw_surface_tree(renderer, renderer_id, texture_destruction_callback, buffer_utils, surface, (x - dx, y - dy), token, log); draw_surface_tree(renderer, renderer_id, texture_destruction_callback, buffer_utils, surface, (x - dx, y - dy), token, log)
} }
fn draw_surface_tree<R, E, T>( fn draw_surface_tree<R, E, T>(
@ -60,12 +60,14 @@ fn draw_surface_tree<R, E, T>(
location: (i32, i32), location: (i32, i32),
compositor_token: MyCompositorToken, compositor_token: MyCompositorToken,
log: &Logger, log: &Logger,
) ) -> Result<(), SwapBuffersError>
where where
R: Renderer<Error=E, TextureId=T>, R: Renderer<Error=E, TextureId=T>,
E: std::error::Error, E: std::error::Error + Into<SwapBuffersError>,
T: Texture + 'static, T: Texture + 'static,
{ {
let mut result = Ok(());
compositor_token.with_surface_tree_upward( compositor_token.with_surface_tree_upward(
root, root,
(), (),
@ -137,12 +139,16 @@ fn draw_surface_tree<R, E, T>(
y += sub_y; y += sub_y;
} }
let texture = buffer_textures.load_texture(renderer_id, renderer, texture_destruction_callback).unwrap(); let texture = buffer_textures.load_texture(renderer_id, renderer, texture_destruction_callback).unwrap();
renderer.render_texture_at(texture, (x, y), Transform::Normal /* TODO */, 1.0); if let Err(err) = renderer.render_texture_at(texture, (x, y), Transform::Normal /* TODO */, 1.0) {
result = Err(err.into());
}
} }
} }
}, },
|_, _, _, _| true, |_, _, _, _| true,
); );
result
} }
pub fn draw_windows<R, E, T>( pub fn draw_windows<R, E, T>(
@ -154,14 +160,15 @@ pub fn draw_windows<R, E, T>(
output_rect: Option<Rectangle>, output_rect: Option<Rectangle>,
compositor_token: MyCompositorToken, compositor_token: MyCompositorToken,
log: &::slog::Logger, log: &::slog::Logger,
) ) -> Result<(), SwapBuffersError>
where where
R: Renderer<Error=E, TextureId=T>, R: Renderer<Error=E, TextureId=T>,
E: std::error::Error, E: std::error::Error + Into<SwapBuffersError>,
T: Texture + 'static, T: Texture + 'static,
{ {
let mut result = Ok(());
// redraw the frame, in a simple but inneficient way // redraw the frame, in a simple but inneficient way
{
window_map.with_windows_from_bottom_to_top( window_map.with_windows_from_bottom_to_top(
|toplevel_surface, mut initial_place, bounding_box| { |toplevel_surface, mut initial_place, bounding_box| {
// skip windows that do not overlap with a given output // skip windows that do not overlap with a given output
@ -173,7 +180,7 @@ pub fn draw_windows<R, E, T>(
} }
if let Some(wl_surface) = toplevel_surface.get_surface() { if let Some(wl_surface) = toplevel_surface.get_surface() {
// this surface is a root of a subsurface tree that needs to be drawn // this surface is a root of a subsurface tree that needs to be drawn
draw_surface_tree( if let Err(err) = draw_surface_tree(
renderer, renderer,
renderer_id, renderer_id,
texture_destruction_callback, texture_destruction_callback,
@ -182,11 +189,14 @@ pub fn draw_windows<R, E, T>(
initial_place, initial_place,
compositor_token, compositor_token,
log, log,
); ) {
result = Err(err);
}
} }
}, },
); );
}
result
} }
pub fn draw_dnd_icon<R, E, T>( pub fn draw_dnd_icon<R, E, T>(
@ -198,10 +208,10 @@ pub fn draw_dnd_icon<R, E, T>(
(x, y): (i32, i32), (x, y): (i32, i32),
token: MyCompositorToken, token: MyCompositorToken,
log: &::slog::Logger, log: &::slog::Logger,
) ) -> Result<(), SwapBuffersError>
where where
R: Renderer<Error=E, TextureId=T>, R: Renderer<Error=E, TextureId=T>,
E: std::error::Error, E: std::error::Error + Into<SwapBuffersError>,
T: Texture + 'static, T: Texture + 'static,
{ {
if !token.has_role::<DnDIconRole>(surface) { if !token.has_role::<DnDIconRole>(surface) {
@ -210,7 +220,7 @@ pub fn draw_dnd_icon<R, E, T>(
"Trying to display as a dnd icon a surface that does not have the DndIcon role." "Trying to display as a dnd icon a surface that does not have the DndIcon role."
); );
} }
draw_surface_tree(renderer, renderer_id, texture_destruction_callback, buffer_utils, surface, (x, y), token, log); draw_surface_tree(renderer, renderer_id, texture_destruction_callback, buffer_utils, surface, (x, y), token, log)
} }
pub fn schedule_initial_render<R: Renderer + 'static, Data: 'static>( pub fn schedule_initial_render<R: Renderer + 'static, Data: 'static>(

View File

@ -21,7 +21,6 @@ use smithay::{
device_bind, device_bind,
DrmRenderSurface, DrmRenderSurface,
DrmError, DrmError,
DrmRenderError,
DevPath, DevPath,
}, },
egl::{EGLDisplay, EGLContext, display::EGLBufferReader}, egl::{EGLDisplay, EGLContext, display::EGLBufferReader},
@ -781,8 +780,8 @@ impl DrmRenderer {
.unwrap_or((0, 0)); // in this case the output will be removed. .unwrap_or((0, 0)); // in this case the output will be removed.
// and draw in sync with our monitor // and draw in sync with our monitor
surface.queue_frame().unwrap(); surface.queue_frame()?;
surface.clear([0.8, 0.8, 0.9, 1.0]).unwrap(); surface.clear([0.8, 0.8, 0.9, 1.0])?;
// draw the surfaces // draw the surfaces
draw_windows( draw_windows(
surface, surface,
@ -798,7 +797,7 @@ impl DrmRenderer {
}), }),
compositor_token.clone(), compositor_token.clone(),
logger, logger,
); )?;
// get pointer coordinates // get pointer coordinates
let (ptr_x, ptr_y) = *pointer_location; let (ptr_x, ptr_y) = *pointer_location;
@ -811,7 +810,7 @@ impl DrmRenderer {
{ {
if let Some(ref wl_surface) = dnd_icon.as_ref() { if let Some(ref wl_surface) = dnd_icon.as_ref() {
if wl_surface.as_ref().is_alive() { if wl_surface.as_ref().is_alive() {
draw_dnd_icon(surface, device_id, texture_destruction_callback, buffer_utils, wl_surface, (ptr_x, ptr_y), compositor_token.clone(), logger); draw_dnd_icon(surface, device_id, texture_destruction_callback, buffer_utils, wl_surface, (ptr_x, ptr_y), compositor_token.clone(), logger)?;
} }
} }
} }
@ -836,9 +835,9 @@ impl DrmRenderer {
(ptr_x, ptr_y), (ptr_x, ptr_y),
compositor_token.clone(), compositor_token.clone(),
logger, logger,
); )?;
} else { } else {
surface.render_texture_at(pointer_image, (ptr_x, ptr_y), Transform::Normal, 1.0); surface.render_texture_at(pointer_image, (ptr_x, ptr_y), Transform::Normal, 1.0)?;
} }
} }
} }

View File

@ -114,7 +114,7 @@ pub fn run_winit(
renderer.clear([0.8, 0.8, 0.9, 1.0]).expect("Failed to clear frame"); renderer.clear([0.8, 0.8, 0.9, 1.0]).expect("Failed to clear frame");
// draw the windows // draw the windows
draw_windows(&mut renderer, 0, &texture_send, &buffer_utils, &*state.window_map.borrow(), None, state.ctoken, &log); draw_windows(&mut renderer, 0, &texture_send, &buffer_utils, &*state.window_map.borrow(), None, state.ctoken, &log).expect("Failed to renderer windows");
let (x, y) = *state.pointer_location.borrow(); let (x, y) = *state.pointer_location.borrow();
// draw the dnd icon if any // draw the dnd icon if any
@ -122,7 +122,7 @@ pub fn run_winit(
let guard = state.dnd_icon.lock().unwrap(); let guard = state.dnd_icon.lock().unwrap();
if let Some(ref surface) = *guard { if let Some(ref surface) = *guard {
if surface.as_ref().is_alive() { if surface.as_ref().is_alive() {
draw_dnd_icon(&mut renderer, 0, &texture_send, &buffer_utils, surface, (x as i32, y as i32), state.ctoken, &log); draw_dnd_icon(&mut renderer, 0, &texture_send, &buffer_utils, surface, (x as i32, y as i32), state.ctoken, &log).expect("Failed to render dnd icon");
} }
} }
} }
@ -141,7 +141,7 @@ pub fn run_winit(
// draw as relevant // draw as relevant
if let CursorImageStatus::Image(ref surface) = *guard { if let CursorImageStatus::Image(ref surface) = *guard {
renderer.window().set_cursor_visible(false); renderer.window().set_cursor_visible(false);
draw_cursor(&mut renderer, 0, &texture_send, &buffer_utils, surface, (x as i32, y as i32), state.ctoken, &log); draw_cursor(&mut renderer, 0, &texture_send, &buffer_utils, surface, (x as i32, y as i32), state.ctoken, &log).expect("Failed to render cursor");
} else { } else {
renderer.window().set_cursor_visible(true); renderer.window().set_cursor_visible(true);
} }