use std::collections::HashMap;
use wayland_server::backend::ObjectId;
use super::imp::{PixelData, Surface};
#[inline]
pub(crate) fn to_physical(logical: u32, scale_120: u32) -> u32 {
(logical * scale_120).div_ceil(120)
}
pub(crate) struct GpuLayer<'a> {
pub x: i32,
pub y: i32,
pub logical_w: u32,
pub logical_h: u32,
pub pixel_w: u32,
pub pixel_h: u32,
pub pixels: &'a PixelData,
pub y_invert: bool,
}
pub(crate) fn collect_gpu_layers<'a>(
surface_id: &ObjectId,
surfaces: &HashMap<ObjectId, Surface>,
cache: &'a HashMap<ObjectId, (u32, u32, i32, bool, PixelData)>,
parent_x: i32,
parent_y: i32,
layers: &mut Vec<GpuLayer<'a>>,
) {
let Some(surf) = surfaces.get(surface_id) else {
return;
};
let (x, y) = (
parent_x + surf.subsurface_position.0,
parent_y + surf.subsurface_position.1,
);
if let Some((w, h, scale, _is_opaque, pixels)) = cache.get(surface_id)
&& !pixels.is_empty()
{
let s = (*scale).max(1) as u32;
let (lw, lh) = surf
.viewport_destination
.filter(|&(dw, dh)| dw > 0 && dh > 0)
.map(|(dw, dh)| (dw as u32, dh as u32))
.unwrap_or((*w / s, *h / s));
static DBG: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
let n = DBG.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
if n < 20 || n.is_multiple_of(1000) {
eprintln!(
"[gpu-layer #{n}] sid={surface_id:?} pos=({x},{y}) pixel={}x{} scale={} viewport={:?} logical={}x{}",
w, h, scale, surf.viewport_destination, lw, lh,
);
}
let y_invert = matches!(pixels, PixelData::DmaBuf { y_invert: true, .. });
layers.push(GpuLayer {
x,
y,
logical_w: lw,
logical_h: lh,
pixel_w: *w,
pixel_h: *h,
pixels,
y_invert,
});
}
for child_id in &surf.children {
collect_gpu_layers(child_id, surfaces, cache, x, y, layers);
}
}