vello_hybrid: Allow nested blending even if scene constraint is set to default blending only
diff --git a/sparse_strips/vello_dev_macros/src/test.rs b/sparse_strips/vello_dev_macros/src/test.rs
index 2e6f28a..af8f93a 100644
--- a/sparse_strips/vello_dev_macros/src/test.rs
+++ b/sparse_strips/vello_dev_macros/src/test.rs
@@ -205,7 +205,10 @@
 
     // Tests that use non-default blend modes will panic with `default_blending_only`.
     skip_hybrid_constrained |= skip_hybrid
-        || input_fn_name_str.contains("mix")
+        || (input_fn_name_str.contains("mix")
+            // This test is supposed to specifically show even with scene constraints enabled,
+            // blending will work fine as long as it doesn't happen on the root layer.
+            && !input_fn_name_str.contains("mix_in_inner_layer"))
         || input_fn_name_str.contains("compose")
         || (input_fn_name_str.contains("blend")
             && !input_fn_name_str.contains("default_blending_only"))
diff --git a/sparse_strips/vello_hybrid/src/scene.rs b/sparse_strips/vello_hybrid/src/scene.rs
index 48bf767..c371125 100644
--- a/sparse_strips/vello_hybrid/src/scene.rs
+++ b/sparse_strips/vello_hybrid/src/scene.rs
@@ -135,7 +135,7 @@
     ///
     /// # Panics
     ///
-    /// The renderer will panic if a non-default blend mode is used.
+    /// The renderer will panic if a non-default blend mode is used in the root layer.
     #[inline(always)]
     pub fn default_blending_only(self) -> Self {
         Self(self.0 | Self::DEFAULT_BLENDING_ONLY)
@@ -147,8 +147,8 @@
     }
 
     #[inline(always)]
-    fn assert_blend_mode(&self, blend_mode: BlendMode) {
-        if self.use_default_blending_only() {
+    fn assert_blend_mode(&self, blend_mode: BlendMode, nested_layer: bool) {
+        if self.use_default_blending_only() && !nested_layer {
             assert!(
                 blend_mode == DEFAULT_BLEND_MODE,
                 "scene constrained to default blending"
@@ -614,7 +614,8 @@
         filter: Option<Filter>,
     ) {
         let blend_mode_val = blend_mode.unwrap_or(DEFAULT_BLEND_MODE);
-        self.constraints.assert_blend_mode(blend_mode_val);
+        self.constraints
+            .assert_blend_mode(blend_mode_val, self.wide.has_layers());
 
         self.layer_id_next += 1;
 
@@ -716,7 +717,8 @@
 
     /// Set the blend mode for subsequent rendering operations.
     pub fn set_blend_mode(&mut self, blend_mode: BlendMode) {
-        self.constraints.assert_blend_mode(blend_mode);
+        self.constraints
+            .assert_blend_mode(blend_mode, self.wide.has_layers());
         self.render_state.blend_mode = blend_mode;
     }
 
@@ -1475,6 +1477,22 @@
     }
 
     #[test]
+    #[should_panic(expected = "scene constrained to default blending")]
+    fn default_blending_only_rejects_root_blend_layer() {
+        let mut scene = default_blending_only();
+        scene.push_blend_layer(BlendMode::new(Mix::Multiply, Compose::SrcOver));
+    }
+
+    #[test]
+    fn default_blending_only_allows_nested_blend_layer() {
+        let mut scene = default_blending_only();
+        scene.push_layer(None, None, Some(0.5), None, None);
+        scene.push_blend_layer(BlendMode::new(Mix::Multiply, Compose::SrcOver));
+
+        assert!(scene.wide.has_layers());
+    }
+
+    #[test]
     fn reset_restores_fast_only() {
         let mut scene = unconstrained();
         scene.set_paint(Color::from_rgba8(255, 0, 0, 255));
diff --git a/sparse_strips/vello_sparse_tests/snapshots/mix_in_inner_layer.png b/sparse_strips/vello_sparse_tests/snapshots/mix_in_inner_layer.png
new file mode 100644
index 0000000..50b9197
--- /dev/null
+++ b/sparse_strips/vello_sparse_tests/snapshots/mix_in_inner_layer.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eeb13181a3fe6d96586fe8465cc3233a96ecf2ddfedbfcaf3b2a3c151131d512
+size 209
diff --git a/sparse_strips/vello_sparse_tests/tests/mix.rs b/sparse_strips/vello_sparse_tests/tests/mix.rs
index 7efdb03..5c674d9 100644
--- a/sparse_strips/vello_sparse_tests/tests/mix.rs
+++ b/sparse_strips/vello_sparse_tests/tests/mix.rs
@@ -297,3 +297,18 @@
 fn mix_non_isolated_color_dodge(ctx: &mut impl Renderer) {
     mix_non_isolated(ctx, Mix::ColorDodge);
 }
+
+#[vello_test]
+fn mix_in_inner_layer(ctx: &mut impl Renderer) {
+    ctx.push_layer(None, None, None, None, None);
+
+    ctx.set_paint(BLUE.with_alpha(0.5));
+    ctx.fill_rect(&Rect::new(10.5, 10.5, 70.5, 70.5));
+
+    ctx.push_blend_layer(BlendMode::new(Mix::Multiply, Compose::SrcOver));
+    ctx.set_paint(LIME.with_alpha(0.5));
+    ctx.fill_rect(&Rect::new(30.5, 30.5, 90.5, 90.5));
+    ctx.pop_layer();
+
+    ctx.pop_layer();
+}