use smithay::backend::renderer::element::texture::TextureBuffer; use smithay::backend::renderer::gles::{GlesRenderer, GlesTexture}; use smithay::backend::renderer::utils::{import_surface, RendererSurfaceStateUserData}; use smithay::backend::renderer::Renderer as _; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::utils::{Logical, Point}; use smithay::wayland::compositor::{with_surface_tree_downward, TraversalAction}; use super::BakedBuffer; /// Renders elements from a surface tree as textures into `storage`. pub fn render_snapshot_from_surface_tree( renderer: &mut GlesRenderer, surface: &WlSurface, location: Point, storage: &mut Vec>>, ) { let _span = tracy_client::span!("render_snapshot_from_surface_tree"); with_surface_tree_downward( surface, location, |_, states, location| { let mut location = *location; let data = states.data_map.get::(); if let Some(data) = data { let data = &*data.borrow(); if let Some(view) = data.view() { location += view.offset; TraversalAction::DoChildren(location) } else { TraversalAction::SkipChildren } } else { TraversalAction::SkipChildren } }, |_, states, location| { let mut location = *location; let data = states.data_map.get::(); if let Some(data) = data { if let Some(view) = data.borrow().view() { location += view.offset; } else { return; } if let Err(err) = import_surface(renderer, states) { warn!("failed to import surface: {err:?}"); return; } let data = data.borrow(); let view = data.view().unwrap(); let Some(texture) = data.texture::(renderer.id()) else { return; }; let buffer = TextureBuffer::from_texture( renderer, texture.clone(), data.buffer_scale(), data.buffer_transform(), None, ); let baked = BakedBuffer { buffer, location, src: Some(view.src), dst: Some(view.dst), }; storage.push(baked); } }, |_, _, _| true, ); }