Skip to content

Commit 21f6038

Browse files
author
Ericky Dos Santos
committed
fix: post blur render pass fix
1 parent f91a2a2 commit 21f6038

1 file changed

Lines changed: 100 additions & 1 deletion

File tree

wgpu/src/lib.rs

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,10 +1319,11 @@ impl Renderer {
13191319
}
13201320

13211321
log::trace!(
1322-
"Rendering post-blur layer {}: has_quads={}, has_triangles={}, has_text={}",
1322+
"Rendering post-blur layer {}: has_quads={}, has_triangles={}, has_primitives={}, has_text={}",
13231323
layer_index,
13241324
!layer.quads.is_empty(),
13251325
!layer.triangles.is_empty(),
1326+
!layer.primitives.is_empty(),
13261327
!layer.text.is_empty()
13271328
);
13281329

@@ -1392,6 +1393,104 @@ impl Renderer {
13921393
));
13931394
}
13941395

1396+
// Custom shader primitives are prepared with the rest of the
1397+
// layer, but the post-blur replay used to omit them entirely. A
1398+
// shader-backed child (for example the voice orb) was therefore
1399+
// skipped in the main pass as intended and never drawn again.
1400+
// Mirror the normal render path here so every primitive held back
1401+
// for backdrop blur is actually composited above it.
1402+
if !layer.primitives.is_empty() {
1403+
let render_span = debug::render(debug::Primitive::Shader);
1404+
1405+
let primitive_storage = self
1406+
.engine
1407+
.primitive_storage
1408+
.read()
1409+
.expect("Read primitive storage");
1410+
1411+
let mut need_render = Vec::new();
1412+
1413+
for instance in &layer.primitives {
1414+
let bounds = instance.bounds * scale;
1415+
1416+
if let Some(clip_bounds) = (instance.bounds * scale)
1417+
.intersection(&physical_bounds)
1418+
.and_then(Rectangle::snap)
1419+
{
1420+
render_pass.set_viewport(
1421+
bounds.x,
1422+
bounds.y,
1423+
bounds.width,
1424+
bounds.height,
1425+
0.0,
1426+
1.0,
1427+
);
1428+
1429+
render_pass.set_scissor_rect(
1430+
clip_bounds.x,
1431+
clip_bounds.y,
1432+
clip_bounds.width,
1433+
clip_bounds.height,
1434+
);
1435+
1436+
let drawn = instance
1437+
.primitive
1438+
.draw(&primitive_storage, &mut render_pass);
1439+
1440+
if !drawn {
1441+
need_render.push((instance, clip_bounds));
1442+
}
1443+
}
1444+
}
1445+
1446+
render_pass.set_viewport(
1447+
0.0,
1448+
0.0,
1449+
viewport.physical_width() as f32,
1450+
viewport.physical_height() as f32,
1451+
0.0,
1452+
1.0,
1453+
);
1454+
1455+
render_pass.set_scissor_rect(
1456+
0,
1457+
0,
1458+
viewport.physical_width(),
1459+
viewport.physical_height(),
1460+
);
1461+
1462+
if !need_render.is_empty() {
1463+
let _ = std::mem::ManuallyDrop::into_inner(render_pass);
1464+
1465+
for (instance, clip_bounds) in need_render {
1466+
instance
1467+
.primitive
1468+
.render(&primitive_storage, encoder, frame, &clip_bounds);
1469+
}
1470+
1471+
render_pass = std::mem::ManuallyDrop::new(encoder.begin_render_pass(
1472+
&wgpu::RenderPassDescriptor {
1473+
label: Some("iced_wgpu post-blur render pass"),
1474+
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
1475+
view: frame,
1476+
depth_slice: None,
1477+
resolve_target: None,
1478+
ops: wgpu::Operations {
1479+
load: wgpu::LoadOp::Load,
1480+
store: wgpu::StoreOp::Store,
1481+
},
1482+
})],
1483+
depth_stencil_attachment: None,
1484+
timestamp_writes: None,
1485+
occlusion_query_set: None,
1486+
multiview_mask: None,
1487+
},
1488+
));
1489+
}
1490+
1491+
render_span.finish();
1492+
}
1493+
13951494
if !layer.text.is_empty() {
13961495
log::trace!("Rendering text at text_layer {}", text_layer);
13971496
text_layer += self.text.render(

0 commit comments

Comments
 (0)