GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
feat: param_plate_fill helper + share blur snapshot across a run
param_plate_fill() is the one source for the params plate's final fill
(tint x opacity, blur marker); ParametersBg::color() now calls it so any
surface matching the plate stays in lockstep. The renderer only takes a
fresh blur snapshot on the first of a consecutive blur-plate run — a row
of blur plates (the designer's node bodies) costs one full-frame copy,
not one each; a non-blur draw between them re-arms it.
Co-Authored-By: Claude Fable 5 <[email protected]>
src/color.rs | 14 ++++++++++++++
src/vk/renderer.rs | 14 ++++++++++++--
src/widget/container/parameters_bg.rs | 7 +------
3 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/color.rs b/src/color.rs
index a9ae58c..6cc0808 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -919,6 +919,20 @@ pub fn set_param_bg_color(color: [f32; 4]) {
}
}
+/// The params plate's final fill as the renderer consumes it: the tint scaled
+/// by the global plate opacity, alpha negated as the blur-behind marker when
+/// plate blur is on. The single source both `ParametersBg`'s own plate and any
+/// surface that wants to match it (the designer's node bodies) draw from, so
+/// they track a live retint / opacity / blur toggle together.
+pub fn param_plate_fill() -> [f32; 4] {
+ let mut c = param_bg_color();
+ c[3] *= crate::layout::plate_opacity();
+ if plate_blur() {
+ c[3] = -c[3].abs();
+ }
+ c
+}
+
pub const PANEL_MENU_BG: [f32; 4] = [0.08, 0.08, 0.12, 1.0];
pub const PANEL_MENU_HOVER: [f32; 4] = [0.18, 0.18, 0.25, 1.0];
pub const PANEL_MENU_FOCUSED: [f32; 4] = [0.08, 0.16, 0.28, 1.0];
diff --git a/src/vk/renderer.rs b/src/vk/renderer.rs
index c1573f0..704c18b 100644
--- a/src/vk/renderer.rs
+++ b/src/vk/renderer.rs
@@ -1698,11 +1698,21 @@ impl VkRenderer {
// so blur plates sample the frame-so-far, and later blur plates
// sample refreshed copies that include earlier ones.
let mut active_set = self.descriptor_set;
+ // CONSECUTIVE blur plates share one snapshot: only a non-blur
+ // draw invalidates it. A run of blur plates (the designer's
+ // node bodies) costs one copy, not one per plate — they don't
+ // see each other, which only matters where they overlap.
+ let mut snapshot_fresh = false;
for batch in batches {
if batch.blur_behind {
- self.snapshot_frame_so_far(cmd, image_index as usize);
- active_set = self.descriptor_set_snapshot;
+ if !snapshot_fresh {
+ self.snapshot_frame_so_far(cmd, image_index as usize);
+ active_set = self.descriptor_set_snapshot;
+ snapshot_fresh = true;
+ }
+ } else if batch.start < batch.end {
+ snapshot_fresh = false;
}
// Resolve the batch scissor; a degenerate one skips the
// vertex draws (images still process on their own clips).
diff --git a/src/widget/container/parameters_bg.rs b/src/widget/container/parameters_bg.rs
index 1d7c172..0f9ff82 100644
--- a/src/widget/container/parameters_bg.rs
+++ b/src/widget/container/parameters_bg.rs
@@ -1242,12 +1242,7 @@ impl Paint for ParametersBg {
if !self.visible {
return [0.0, 0.0, 0.0, 0.0];
}
- let mut c = colors::param_bg_color();
- c[3] *= crate::layout::plate_opacity();
- if colors::plate_blur() {
- c[3] = -c[3].abs();
- }
- c
+ colors::param_plate_fill()
}
/// The shared plate corner radius (rounded on all four corners when non-zero).