fit layer buffers during output resize
This commit is contained in:
1 parent
05fb4280f5
commit
0420242350
1 file changed
+52
-18
+52
-18
@@ -1452,27 +1452,31 @@ fn layer_elements(
|
|||||||
|
|
||||||
let mut elements = Vec::new();
|
let mut elements = Vec::new();
|
||||||
for (geometry, layer) in layers {
|
for (geometry, layer) in layers {
|
||||||
elements.extend(
|
let target = geometry.to_physical_precise_round(scale);
|
||||||
AsRenderElements::<GlesRenderer>::render_elements::<
|
let surface_elements = AsRenderElements::<GlesRenderer>::render_elements::<
|
||||||
WaylandSurfaceRenderElement<GlesRenderer>,
|
WaylandSurfaceRenderElement<GlesRenderer>,
|
||||||
>(
|
>(&layer, renderer, target.loc, scale.into(), 1.0);
|
||||||
&layer,
|
let source_bounds = surface_elements
|
||||||
renderer,
|
.iter()
|
||||||
geometry.loc.to_physical_precise_round(scale),
|
.map(|element| element.geometry(scale.into()))
|
||||||
scale.into(),
|
.reduce(Rectangle::merge);
|
||||||
1.0,
|
let content_scale = source_bounds
|
||||||
)
|
.map(|source| layer_content_scale(source.size, target.size))
|
||||||
.into_iter()
|
.unwrap_or_else(|| RenderScale::from(1.0));
|
||||||
.filter_map(|element| {
|
let scale_origin = source_bounds.map_or(target.loc, |source| source.loc);
|
||||||
let origin = Point::<i32, Physical>::default();
|
let crop = target.intersection(output_crop).unwrap_or_default();
|
||||||
let element = RescaleRenderElement::from_element(element, origin, 1.0);
|
|
||||||
let element =
|
|
||||||
RelocateRenderElement::from_element(element, origin, Relocate::Relative);
|
|
||||||
|
|
||||||
CropRenderElement::from_element(element, scale, output_crop).map(Into::into)
|
elements.extend(surface_elements.into_iter().filter_map(|element| {
|
||||||
}),
|
let element = RescaleRenderElement::from_element(element, scale_origin, content_scale);
|
||||||
|
let element = RelocateRenderElement::from_element(
|
||||||
|
element,
|
||||||
|
Point::<i32, Physical>::default(),
|
||||||
|
Relocate::Relative,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CropRenderElement::from_element(element, scale, crop).map(Into::into)
|
||||||
|
}));
|
||||||
|
|
||||||
if let Some(material) = material_element(state, renderer, output, &layer, geometry) {
|
if let Some(material) = material_element(state, renderer, output, &layer, geometry) {
|
||||||
elements.push(material);
|
elements.push(material);
|
||||||
}
|
}
|
||||||
@@ -1481,6 +1485,20 @@ fn layer_elements(
|
|||||||
elements
|
elements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn layer_content_scale(
|
||||||
|
source: Size<i32, Physical>,
|
||||||
|
target: Size<i32, Physical>,
|
||||||
|
) -> RenderScale<f64> {
|
||||||
|
if source.w <= 0 || source.h <= 0 || target.w <= 0 || target.h <= 0 {
|
||||||
|
return RenderScale::from(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderScale::from((
|
||||||
|
f64::from(target.w) / f64::from(source.w),
|
||||||
|
f64::from(target.h) / f64::from(source.h),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
fn material_element(
|
fn material_element(
|
||||||
state: &mut Ferese,
|
state: &mut Ferese,
|
||||||
renderer: &mut GlesRenderer,
|
renderer: &mut GlesRenderer,
|
||||||
@@ -1813,7 +1831,8 @@ mod tests {
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
color_with_alpha, expanded_blur_region, framebuffer_capture_rect, framebuffer_clip_rect,
|
color_with_alpha, expanded_blur_region, framebuffer_capture_rect, framebuffer_clip_rect,
|
||||||
normalized_scale, rounded_visual_rect, scaled_visual_rect, shadow_bounds,
|
layer_content_scale, normalized_scale, rounded_visual_rect, scaled_visual_rect,
|
||||||
|
shadow_bounds,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -1866,6 +1885,21 @@ mod tests {
|
|||||||
assert_eq!(normalized_scale(f64::INFINITY), 1.0);
|
assert_eq!(normalized_scale(f64::INFINITY), 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn layer_content_tracks_new_allocation_before_the_client_repaints() {
|
||||||
|
let scale = layer_content_scale((1_000, 40).into(), (1_600, 40).into());
|
||||||
|
|
||||||
|
assert_eq!(scale, Scale::from((1.6, 1.0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn layer_content_scale_ignores_empty_allocations() {
|
||||||
|
assert_eq!(
|
||||||
|
layer_content_scale((0, 40).into(), (1_600, 40).into()),
|
||||||
|
Scale::from(1.0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn clip_rect_matches_smithay_gles_projection() {
|
fn clip_rect_matches_smithay_gles_projection() {
|
||||||
let geometry = Rectangle::<i32, Physical>::new((10, 5).into(), (30, 40).into());
|
let geometry = Rectangle::<i32, Physical>::new((10, 5).into(), (30, 40).into());
|
||||||
|
|||||||
Reference in new issue
Block a user