Merge pull request #2977 from DKolter/issue_2934

Fix tiny skia primitive rendering
This commit is contained in:
Héctor 2025-11-27 04:41:16 +01:00 • committed by GitHub
commit b3e1be5def
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 29 additions and 41 deletions

View file

@ -36,15 +36,6 @@ impl Engine {
clip_mask: &mut tiny_skia::Mask, clip_mask: &mut tiny_skia::Mask,
clip_bounds: Rectangle, clip_bounds: Rectangle,
) { ) {
debug_assert!(
quad.bounds.width.is_normal(),
"Quad with non-normal width!"
);
debug_assert!(
quad.bounds.height.is_normal(),
"Quad with non-normal height!"
);
let physical_bounds = quad.bounds * transformation; let physical_bounds = quad.bounds * transformation;
if !clip_bounds.intersects(&physical_bounds) { if !clip_bounds.intersects(&physical_bounds) {
@ -497,7 +488,7 @@ impl Engine {
transformation: Transformation, transformation: Transformation,
pixels: &mut tiny_skia::PixmapMut<'_>, pixels: &mut tiny_skia::PixmapMut<'_>,
clip_mask: &mut tiny_skia::Mask, clip_mask: &mut tiny_skia::Mask,
layer_bounds: Rectangle, clip_bounds: Rectangle,
) { ) {
match primitive { match primitive {
Primitive::Fill { path, paint, rule } => { Primitive::Fill { path, paint, rule } => {
@ -512,14 +503,12 @@ impl Engine {
} * transformation } * transformation
}; };
let Some(clip_bounds) = if !clip_bounds.intersects(&physical_bounds) {
layer_bounds.intersection(&physical_bounds)
else {
return; return;
}; }
let clip_mask = let clip_mask = (!physical_bounds.is_within(&clip_bounds))
(physical_bounds != clip_bounds).then_some(clip_mask as &_); .then_some(clip_mask as &_);
pixels.fill_path( pixels.fill_path(
path, path,
@ -545,14 +534,12 @@ impl Engine {
} * transformation } * transformation
}; };
let Some(clip_bounds) = if !clip_bounds.intersects(&physical_bounds) {
layer_bounds.intersection(&physical_bounds)
else {
return; return;
}; }
let clip_mask = let clip_mask = (!physical_bounds.is_within(&clip_bounds))
(physical_bounds != clip_bounds).then_some(clip_mask as &_); .then_some(clip_mask as &_);
pixels.stroke_path( pixels.stroke_path(
path, path,

View file

@ -268,8 +268,8 @@ impl Layer {
.filter_map(|bounds| bounds.intersection(group_bounds)) .filter_map(|bounds| bounds.intersection(group_bounds))
.collect() .collect()
} }
Item::Cached(_, bounds, _) => { Item::Cached(_, bounds, transformation) => {
vec![*bounds] vec![*bounds * *transformation]
} }
}, },
|primitive_a, primitive_b| match (primitive_a, primitive_b) { |primitive_a, primitive_b| match (primitive_a, primitive_b) {

View file

@ -76,15 +76,15 @@ impl Renderer {
self.layers.flush(); self.layers.flush();
for &region in damage { for &damage_bounds in damage {
let region = region * scale_factor; let damage_bounds = damage_bounds * scale_factor;
let path = tiny_skia::PathBuilder::from_rect( let path = tiny_skia::PathBuilder::from_rect(
tiny_skia::Rect::from_xywh( tiny_skia::Rect::from_xywh(
region.x, damage_bounds.x,
region.y, damage_bounds.y,
region.width, damage_bounds.width,
region.height, damage_bounds.height,
) )
.expect("Create damage rectangle"), .expect("Create damage rectangle"),
); );
@ -105,13 +105,13 @@ impl Renderer {
); );
for layer in self.layers.iter() { for layer in self.layers.iter() {
let Some(clip_bounds) = let Some(layer_bounds) =
region.intersection(&(layer.bounds * scale_factor)) damage_bounds.intersection(&(layer.bounds * scale_factor))
else { else {
continue; continue;
}; };
engine::adjust_clip_mask(clip_mask, clip_bounds); engine::adjust_clip_mask(clip_mask, layer_bounds);
if !layer.quads.is_empty() { if !layer.quads.is_empty() {
let render_span = debug::render(debug::Primitive::Quad); let render_span = debug::render(debug::Primitive::Quad);
@ -122,7 +122,7 @@ impl Renderer {
Transformation::scale(scale_factor), Transformation::scale(scale_factor),
pixels, pixels,
clip_mask, clip_mask,
clip_bounds, layer_bounds,
); );
} }
render_span.finish(); render_span.finish();
@ -132,14 +132,15 @@ impl Renderer {
let render_span = debug::render(debug::Primitive::Triangle); let render_span = debug::render(debug::Primitive::Triangle);
for group in &layer.primitives { for group in &layer.primitives {
let Some(new_clip_bounds) = (group.clip_bounds() let Some(group_bounds) = (group.clip_bounds()
* group.transformation()
* scale_factor) * scale_factor)
.intersection(&clip_bounds) .intersection(&layer_bounds)
else { else {
continue; continue;
}; };
engine::adjust_clip_mask(clip_mask, new_clip_bounds); engine::adjust_clip_mask(clip_mask, group_bounds);
for primitive in group.as_slice() { for primitive in group.as_slice() {
self.engine.draw_primitive( self.engine.draw_primitive(
@ -148,11 +149,11 @@ impl Renderer {
* Transformation::scale(scale_factor), * Transformation::scale(scale_factor),
pixels, pixels,
clip_mask, clip_mask,
clip_bounds, group_bounds,
); );
} }
engine::adjust_clip_mask(clip_mask, clip_bounds); engine::adjust_clip_mask(clip_mask, layer_bounds);
} }
render_span.finish(); render_span.finish();
@ -167,7 +168,7 @@ impl Renderer {
Transformation::scale(scale_factor), Transformation::scale(scale_factor),
pixels, pixels,
clip_mask, clip_mask,
clip_bounds, layer_bounds,
); );
} }
@ -185,7 +186,7 @@ impl Renderer {
* Transformation::scale(scale_factor), * Transformation::scale(scale_factor),
pixels, pixels,
clip_mask, clip_mask,
clip_bounds, layer_bounds,
); );
} }
} }