From 1dd5de46177fbd69282024245fd97aeb6410fa18 Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Sun, 21 Jun 2026 15:23:42 -0400 Subject: [PATCH] Render clip instances on top of a layer's loose shapes Within a vector layer, groups and movie clips (clip instances) were drawn before the layer's own VectorGraph, so they appeared underneath the loose shapes. Draw the loose shapes first and the clip instances on top, in both the Vello and CPU render paths. --- .../lightningbeam-core/src/renderer.rs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lightningbeam-ui/lightningbeam-core/src/renderer.rs b/lightningbeam-ui/lightningbeam-core/src/renderer.rs index a13203c..6a9c059 100644 --- a/lightningbeam-ui/lightningbeam-core/src/renderer.rs +++ b/lightningbeam-ui/lightningbeam-core/src/renderer.rs @@ -1356,7 +1356,12 @@ fn render_vector_layer( // Cascade opacity: parent_opacity × layer.opacity let layer_opacity = parent_opacity * layer.layer.opacity; - // Render clip instances first (they appear under shape instances) + // Render the layer's own VectorGraph (loose shapes) first, then clip instances + // (groups / movie clips) on top. + if let Some(graph) = layer.graph_at_time(time) { + render_vector_graph(graph, scene, base_transform, layer_opacity, document, image_cache); + } + for clip_instance in &layer.clip_instances { // For groups, compute the visibility end from keyframe data let group_end_time = document.vector_clips.get(&clip_instance.clip_id) @@ -1367,11 +1372,6 @@ fn render_vector_layer( }); render_clip_instance(document, time, clip_instance, layer_opacity, scene, base_transform, &layer.layer.animation_data, image_cache, video_manager, group_end_time); } - - // Render VectorGraph from active keyframe - if let Some(graph) = layer.graph_at_time(time) { - render_vector_graph(graph, scene, base_transform, layer_opacity, document, image_cache); - } } // ============================================================================ @@ -1667,6 +1667,11 @@ fn render_vector_layer_cpu( ) { let layer_opacity = parent_opacity * layer.layer.opacity; + // Loose shapes first, then clip instances (groups / movie clips) on top. + if let Some(graph) = layer.graph_at_time(time) { + render_vector_graph_cpu(graph, pixmap, affine_to_ts(base_transform), layer_opacity as f32, document, image_cache); + } + for clip_instance in &layer.clip_instances { let group_end_time = document.vector_clips.get(&clip_instance.clip_id) .filter(|vc| vc.is_group) @@ -1679,10 +1684,6 @@ fn render_vector_layer_cpu( &layer.layer.animation_data, image_cache, group_end_time, ); } - - if let Some(graph) = layer.graph_at_time(time) { - render_vector_graph_cpu(graph, pixmap, affine_to_ts(base_transform), layer_opacity as f32, document, image_cache); - } } /// Render a clip instance (and its nested layers) to a CPU pixmap.