@@ -1732,7 +1732,66 @@ void effects_dirty_corner_masks(output_t *output) {
17321732 tl -> rounded -> corner_mask_dirty = true;
17331733}
17341734
1735- static bool rebuild_corner_masks (output_t * output , uint64_t bg_tex ) {
1735+ static uint64_t capture_corner_mask_bg (output_t * output , effects_output_t * ctx , toplevel_t * tl ) {
1736+ int w = output -> width ;
1737+ wlr_scene_output_set_position (ctx -> capture_scene_output , output -> lx , output -> ly );
1738+
1739+ if (server .top_tree -> node .enabled )
1740+ wlr_scene_node_set_enabled (& server .top_tree -> node , false);
1741+ if (server .full_tree -> node .enabled )
1742+ wlr_scene_node_set_enabled (& server .full_tree -> node , false);
1743+ if (server .over_tree -> node .enabled )
1744+ wlr_scene_node_set_enabled (& server .over_tree -> node , false);
1745+ if (server .lock_tree -> node .enabled )
1746+ wlr_scene_node_set_enabled (& server .lock_tree -> node , false);
1747+
1748+ bool hidden = false;
1749+ if (tl -> scene_tree && tl -> scene_tree -> node .enabled ) {
1750+ wlr_scene_node_set_enabled (& tl -> scene_tree -> node , false);
1751+ hidden = true;
1752+ }
1753+
1754+ wlr_damage_ring_add_whole (& ctx -> capture_scene_output -> damage_ring );
1755+ struct wlr_output_state cap_state ;
1756+ wlr_output_state_init (& cap_state );
1757+ wlr_output_state_set_enabled (& cap_state , true);
1758+ wlr_output_state_set_custom_mode (& cap_state , ctx -> blur_w , ctx -> blur_h , 0 );
1759+ wlr_output_state_set_scale (& cap_state , (float )ctx -> blur_w / (float )w );
1760+ struct wlr_scene_output_state_options opts = { .swapchain = ctx -> blur_swapchain };
1761+ bool ok = wlr_scene_output_build_state (ctx -> capture_scene_output , & cap_state , & opts );
1762+
1763+ if (hidden )
1764+ wlr_scene_node_set_enabled (& tl -> scene_tree -> node , true);
1765+ if (!server .top_tree -> node .enabled )
1766+ wlr_scene_node_set_enabled (& server .top_tree -> node , true);
1767+ if (!server .full_tree -> node .enabled )
1768+ wlr_scene_node_set_enabled (& server .full_tree -> node , true);
1769+ if (!server .over_tree -> node .enabled )
1770+ wlr_scene_node_set_enabled (& server .over_tree -> node , true);
1771+ if (!server .lock_tree -> node .enabled )
1772+ wlr_scene_node_set_enabled (& server .lock_tree -> node , true);
1773+
1774+ wlr_scene_output_set_position (ctx -> capture_scene_output , -0x7fff , -0x7fff );
1775+
1776+ if (!ok || !cap_state .buffer ) {
1777+ wlr_output_state_finish (& cap_state );
1778+ return 0 ;
1779+ }
1780+
1781+ uint64_t result = 0 ;
1782+ effects_backend -> capture_readback (cap_state .buffer , & ctx -> be_state ,
1783+ ctx -> be_state .pong .native_handle [0 ], 0 , 0 , ctx -> blur_w , ctx -> blur_h , 0 , 0 , ctx -> blur_w ,
1784+ ctx -> blur_h , & result );
1785+ wlr_output_state_finish (& cap_state );
1786+
1787+ if (result ) {
1788+ ctx -> shared_bg_valid = false;
1789+ ctx -> combined_bg_valid = false;
1790+ }
1791+ return result ;
1792+ }
1793+
1794+ static bool rebuild_corner_masks (output_t * output ) {
17361795 effects_output_t * ctx = output -> effects ;
17371796 int w = output -> width , h = output -> height ;
17381797 bool any = false;
@@ -1766,88 +1825,9 @@ static bool rebuild_corner_masks(output_t *output, uint64_t bg_tex) {
17661825 if (content_r .width <= 0 || content_r .height <= 0 )
17671826 continue ;
17681827
1769- uint64_t src ;
1770- if (bg_tex ) {
1771- src = bg_tex ;
1772- } else {
1773- int cw = output -> width , ch = output -> height ;
1774-
1775- wlr_scene_output_set_position (ctx -> capture_scene_output , output -> lx , output -> ly );
1776- if (server .top_tree -> node .enabled )
1777- wlr_scene_node_set_enabled (& server .top_tree -> node , false);
1778- if (server .full_tree -> node .enabled )
1779- wlr_scene_node_set_enabled (& server .full_tree -> node , false);
1780- if (server .over_tree -> node .enabled )
1781- wlr_scene_node_set_enabled (& server .over_tree -> node , false);
1782- if (server .lock_tree -> node .enabled )
1783- wlr_scene_node_set_enabled (& server .lock_tree -> node , false);
1784-
1785- struct {
1786- struct wlr_scene_node * node ;
1787- bool was ;
1788- } restore [8 ];
1789- int nr = 0 ;
1790-
1791- #define HIDE_IF (n ) \
1792- do { \
1793- if ((n) && (n)->enabled) { \
1794- restore[nr].node = (n); \
1795- restore[nr].was = true; \
1796- wlr_scene_node_set_enabled((n), false); \
1797- nr++; \
1798- } \
1799- } while (0)
1800-
1801- HIDE_IF (& tl -> content_tree -> node );
1802- HIDE_IF (& tl -> border_tree -> node );
1803- if (tl -> blur ) {
1804- for (size_t bi = 0 ; bi < blur_count (tl -> blur ); bi ++ ) {
1805- struct wlr_scene_buffer * bnode = blur_get (tl -> blur , bi );
1806- if (bnode )
1807- HIDE_IF (& bnode -> node );
1808- }
1809- HIDE_IF (& tl -> blur -> mica_node -> node );
1810- HIDE_IF (& tl -> blur -> acrylic_node -> node );
1811- }
1812- if (tl -> rounded )
1813- HIDE_IF (& tl -> rounded -> corner_mask_node -> node );
1814-
1815- wlr_damage_ring_add_whole (& ctx -> capture_scene_output -> damage_ring );
1816- struct wlr_output_state cap_state ;
1817- wlr_output_state_init (& cap_state );
1818- wlr_output_state_set_enabled (& cap_state , true);
1819- wlr_output_state_set_custom_mode (& cap_state , cw , ch , 0 );
1820- struct wlr_scene_output_state_options opts = { .swapchain = ctx -> full_swapchain };
1821- bool ok = wlr_scene_output_build_state (ctx -> capture_scene_output , & cap_state , & opts );
1822-
1823- for (int i = 0 ; i < nr ; i ++ )
1824- wlr_scene_node_set_enabled (restore [i ].node , true);
1825-
1826- #undef HIDE_IF
1827-
1828- if (!server .top_tree -> node .enabled )
1829- wlr_scene_node_set_enabled (& server .top_tree -> node , true);
1830- if (!server .full_tree -> node .enabled )
1831- wlr_scene_node_set_enabled (& server .full_tree -> node , true);
1832- if (!server .over_tree -> node .enabled )
1833- wlr_scene_node_set_enabled (& server .over_tree -> node , true);
1834- if (!server .lock_tree -> node .enabled )
1835- wlr_scene_node_set_enabled (& server .lock_tree -> node , true);
1836- wlr_scene_output_set_position (ctx -> capture_scene_output , -0x7fff , -0x7fff );
1837-
1838- if (!ok || !cap_state .buffer ) {
1839- wlr_output_state_finish (& cap_state );
1840- continue ;
1841- }
1842-
1843- effects_backend -> capture_readback (cap_state .buffer , & ctx -> be_state ,
1844- ctx -> be_state .pong .native_handle [0 ], 0 , 0 , ctx -> blur_w , ctx -> blur_h , 0 , 0 , cw , ch , & src );
1845- wlr_output_state_finish (& cap_state );
1846- if (!src )
1847- continue ;
1848- ctx -> shared_bg_valid = false;
1849- ctx -> combined_bg_valid = false;
1850- }
1828+ uint64_t src = capture_corner_mask_bg (output , ctx , tl );
1829+ if (!src )
1830+ continue ;
18511831
18521832 if (!ensure_output_buf (& tl -> rounded -> corner_mask_buf , tl -> rounded -> corner_mask_native , w , h ))
18531833 continue ;
@@ -2409,16 +2389,21 @@ void effects_output_frame(output_t *output, struct wlr_scene_output *scene_outpu
24092389 }
24102390 }
24112391
2392+ // apply mica before corner masks so its bg capture (into the shared pong
2393+ // buffer) isn't invalidated by the per-window corner-mask captures
2394+ if (mica_dirty ) {
2395+ uint64_t mica_bg = capture_bg_to_tex1 (output , ctx , true, NULL , NULL );
2396+ if (mica_bg )
2397+ rebuild_mica (output , mica_bg );
2398+ }
2399+
24122400 // apply corner masks and blur if needed
2413- uint64_t cm_bg_tex = 0 ;
24142401 if (has_layer_blur ) {
24152402 if (unified ) {
24162403 // single capture already blurred into blur_buf above; layers reuse it
24172404 push_blur_to_layers (output , ctx -> blur_buf );
24182405 if (any_cm_dirty )
2419- cm_bg_tex = capture_bg_to_tex1 (output , ctx , true, NULL , NULL );
2420- if (any_cm_dirty )
2421- rebuild_corner_masks (output , cm_bg_tex );
2406+ rebuild_corner_masks (output );
24222407 push_corner_masks_to_toplevels (output , any_cm_dirty );
24232408 goto cm_done ;
24242409 }
@@ -2435,32 +2420,23 @@ void effects_output_frame(output_t *output, struct wlr_scene_output *scene_outpu
24352420 push_blur_to_layers (output , ctx -> layer_blur_buf );
24362421 }
24372422 if (any_cm_dirty )
2438- cm_bg_tex = capture_bg_to_tex1 (output , ctx , true, NULL , NULL );
2439- if (any_cm_dirty )
2440- rebuild_corner_masks (output , cm_bg_tex );
2423+ rebuild_corner_masks (output );
24412424 push_corner_masks_to_toplevels (output , any_cm_dirty );
24422425 } else if (any_layer_needs_blur ) {
24432426 rebuild_live_blur_layers (output , 0 , & scene_output -> damage_ring .current );
24442427 push_blur_to_layers (output , ctx -> layer_blur_buf );
24452428 } else if (any_cm ) {
24462429 if (any_cm_dirty )
2447- cm_bg_tex = capture_bg_to_tex1 (output , ctx , true, NULL , NULL );
2448- if (any_cm_dirty )
2449- rebuild_corner_masks (output , cm_bg_tex );
2430+ rebuild_corner_masks (output );
24502431 push_corner_masks_to_toplevels (output , any_cm_dirty );
24512432 }
24522433 } else if (any_cm ) {
24532434 if (any_cm_dirty )
2454- cm_bg_tex = capture_bg_to_tex1 (output , ctx , true, NULL , NULL );
2455- if (any_cm_dirty )
2456- rebuild_corner_masks (output , cm_bg_tex );
2435+ rebuild_corner_masks (output );
24572436 push_corner_masks_to_toplevels (output , any_cm_dirty );
24582437 }
24592438cm_done :
24602439
2461- if (mica_dirty )
2462- rebuild_mica (output , cm_bg_tex );
2463-
24642440 if (mica_enabled && ctx -> mica_buf )
24652441 push_mica_to_toplevels (output );
24662442
@@ -2526,7 +2502,6 @@ void effects_output_frame(output_t *output, struct wlr_scene_output *scene_outpu
25262502 effects_backend -> frame_begin ();
25272503
25282504 // apply corner masks and layer blur if needed
2529- uint64_t cm_bg_tex_lo = 0 ;
25302505 if (has_layer_blur ) {
25312506 bool any_layer_needs_blur = blur_enabled && layer_blur_needs_rebuild (output ,
25322507 & scene_output -> damage_ring .current );
@@ -2548,10 +2523,8 @@ void effects_output_frame(output_t *output, struct wlr_scene_output *scene_outpu
25482523 goto cm_bg_tex_lo_cap ;
25492524 } else if (any_cm ) {
25502525 cm_bg_tex_lo_cap :
2551- if (any_cm_dirty ) {
2552- cm_bg_tex_lo = capture_bg_to_tex1 (output , ctx , true, NULL , NULL );
2553- rebuild_corner_masks (output , cm_bg_tex_lo );
2554- }
2526+ if (any_cm_dirty )
2527+ rebuild_corner_masks (output );
25552528 push_corner_masks_to_toplevels (output , any_cm_dirty );
25562529 }
25572530
0 commit comments