1
0
Fork 0
forked from wry/wry

renderer: fix rendering flickering window rendering

This commit is contained in:
kossLAN 2026-04-11 00:57:16 -04:00
parent bd3128c516
commit 4e9b6def83
No known key found for this signature in database
3 changed files with 108 additions and 41 deletions

View file

@ -923,20 +923,19 @@ impl VulkanRenderer {
#[derive(Eq, PartialEq, PartialOrd, Ord)]
enum Key {
Fill { color: [u32; 4] },
Tex(usize),
RoundedFill { z_order: u32, color: [u32; 4] },
RoundedTex(usize),
Tex(usize),
}
match o {
VulkanOp::Fill(f) => Key::Fill {
color: f.color.map(|c| c.to_bits()),
},
VulkanOp::Tex(t) => Key::Tex(t.index),
VulkanOp::RoundedFill(f) => Key::RoundedFill {
z_order: f.z_order,
color: f.color.map(|c| c.to_bits()),
},
VulkanOp::RoundedTex(t) => Key::RoundedTex(t.index),
VulkanOp::Tex(t) => Key::Tex(t.index),
VulkanOp::RoundedTex(t) => Key::Tex(t.index),
}
});
let mops = &mut memory.ops[pass];
@ -1638,6 +1637,30 @@ impl VulkanRenderer {
}
}
};
let full_scissor = Rect2D {
offset: Default::default(),
extent: Extent2D {
width: target.width,
height: target.height,
},
};
let paint_regions = &memory.paint_regions[pass];
// Draws a rounded op once per intersecting paint region using scissor
// rects. Unlike CopyTexture/FillRect which clip their geometry to each
// paint region, rounded ops must keep their full geometry so the shader
// computes correct corner rounding. Scissor rects achieve this.
macro_rules! draw_rounded {
($target_point:expr) => {
for region in paint_regions {
if region.intersects(&$target_point) {
let scissor = region.to_scissor(target);
dev.cmd_set_scissor(buf, 0, slice::from_ref(&scissor));
dev.cmd_draw(buf, 4, 1, 0, 0);
}
}
dev.cmd_set_scissor(buf, 0, slice::from_ref(&full_scissor));
};
}
for opt in &memory.ops[pass] {
match opt {
VulkanOp::Fill(r) => {
@ -1768,7 +1791,7 @@ impl VulkanRenderer {
0,
uapi::as_bytes(&push),
);
dev.cmd_draw(buf, 4, 1, 0, 0);
draw_rounded!(r.target);
}
} else {
let push = LegacyRoundedFillPushConstants {
@ -1791,7 +1814,7 @@ impl VulkanRenderer {
0,
uapi::as_bytes(&push),
);
dev.cmd_draw(buf, 4, 1, 0, 0);
draw_rounded!(r.target);
}
}
}
@ -1837,7 +1860,7 @@ impl VulkanRenderer {
0,
uapi::as_bytes(&push),
);
dev.cmd_draw(buf, 4, 1, 0, 0);
draw_rounded!(c.target);
}
} else {
let write_descriptor_set = WriteDescriptorSet::default()
@ -1872,7 +1895,7 @@ impl VulkanRenderer {
0,
uapi::as_bytes(&push),
);
dev.cmd_draw(buf, 4, 1, 0, 0);
draw_rounded!(c.target);
}
}
}
@ -2716,6 +2739,21 @@ impl PaintRegion {
}
}
fn to_scissor(&self, target: &VulkanImage) -> Rect2D {
let from_norm = |c: f32, max: u32| ((c + 1.0) * 0.5 * max as f32).round() as i32;
let x1 = from_norm(self.x1, target.width).max(0);
let y1 = from_norm(self.y1, target.height).max(0);
let x2 = from_norm(self.x2, target.width).min(target.width as i32);
let y2 = from_norm(self.y2, target.height).min(target.height as i32);
Rect2D {
offset: Offset2D { x: x1, y: y1 },
extent: Extent2D {
width: (x2 - x1).max(0) as u32,
height: (y2 - y1).max(0) as u32,
},
}
}
fn constrain(&self, pos: &mut Point, tex_pos: Option<&mut Point>) -> bool {
zone!("constrain");
let mut npos = *pos;