|
24 | 24 | #include "scenefx/types/fx/blur_data.h" |
25 | 25 | #include "scenefx/types/fx/clipped_region.h" |
26 | 26 | #include "scenefx/types/fx/corner_location.h" |
| 27 | +#include "types/linked_nodes.h" |
27 | 28 | #include "types/wlr_output.h" |
28 | 29 | #include "types/wlr_scene.h" |
29 | 30 | #include "util/array.h" |
|
48 | 49 | scene_rect->color[3] < 1.0f) |
49 | 50 | #define SCENE_SHADOW_IS_DROP(scene_shadow) \ |
50 | 51 | (scene_shadow->type == WLR_SCENE_SHADOW_TYPE_DROP \ |
51 | | - && scene_shadow->reference_buffer \ |
| 52 | + && scene_shadow->buffer_link.link != NULL \ |
52 | 53 | && scene_shadow->blur_sigma >= 0) |
53 | 54 |
|
54 | 55 | struct wlr_scene_tree *wlr_scene_tree_from_node(struct wlr_scene_node *node) { |
@@ -193,10 +194,7 @@ void wlr_scene_node_destroy(struct wlr_scene_node *node) { |
193 | 194 | } else if (node->type == WLR_SCENE_NODE_SHADOW) { |
194 | 195 | // Remove the drop-shadows referenced buffers link to this node |
195 | 196 | struct wlr_scene_shadow *scene_shadow = wlr_scene_shadow_from_node(node); |
196 | | - if (scene_shadow->reference_buffer |
197 | | - && scene_shadow->reference_buffer->linked_drop_shadow == scene_shadow) { |
198 | | - scene_shadow->reference_buffer->linked_drop_shadow = NULL; |
199 | | - } |
| 197 | + linked_node_destroy(&scene_shadow->buffer_link); |
200 | 198 | } |
201 | 199 |
|
202 | 200 | assert(wl_list_empty(&node->events.destroy.listener_list)); |
@@ -999,7 +997,7 @@ struct wlr_scene_shadow *wlr_scene_shadow_create(struct wlr_scene_tree *parent, |
999 | 997 |
|
1000 | 998 | scene_node_update(&scene_shadow->node, NULL); |
1001 | 999 |
|
1002 | | - scene_shadow->reference_buffer = NULL; |
| 1000 | + scene_shadow->buffer_link = linked_node_init(); |
1003 | 1001 | scene_shadow->type = WLR_SCENE_SHADOW_TYPE_BOX; |
1004 | 1002 |
|
1005 | 1003 | return scene_shadow; |
@@ -1051,19 +1049,8 @@ void wlr_scene_shadow_set_reference_buffer(struct wlr_scene_shadow *shadow, |
1051 | 1049 | return; |
1052 | 1050 | } |
1053 | 1051 |
|
1054 | | - // Unlink the other drop shadow from the reference buffer if it exists |
1055 | | - if (shadow->reference_buffer) { |
1056 | | - shadow->reference_buffer->linked_drop_shadow = NULL; |
1057 | | - } |
1058 | | - if (ref_buffer) { |
1059 | | - ref_buffer->linked_drop_shadow = shadow; |
1060 | | - } |
| 1052 | + linked_node_init_link(&shadow->buffer_link, &ref_buffer->drop_shadow_link); |
1061 | 1053 |
|
1062 | | - if (ref_buffer == shadow->reference_buffer) { |
1063 | | - return; |
1064 | | - } |
1065 | | - |
1066 | | - shadow->reference_buffer = ref_buffer; |
1067 | 1054 | scene_node_update(&shadow->node, NULL); |
1068 | 1055 | } |
1069 | 1056 |
|
@@ -1264,7 +1251,7 @@ struct wlr_scene_buffer *wlr_scene_buffer_create(struct wlr_scene_tree *parent, |
1264 | 1251 | scene_buffer->backdrop_blur_optimized = false; |
1265 | 1252 | scene_buffer->backdrop_blur_ignore_transparent = true; |
1266 | 1253 | scene_buffer->corners = CORNER_LOCATION_NONE; |
1267 | | - scene_buffer->linked_drop_shadow = NULL; |
| 1254 | + scene_buffer->drop_shadow_link = linked_node_init(); |
1268 | 1255 |
|
1269 | 1256 | scene_buffer_set_buffer(scene_buffer, buffer); |
1270 | 1257 | scene_node_update(&scene_buffer->node, NULL); |
@@ -1414,24 +1401,27 @@ void wlr_scene_buffer_set_buffer_with_options(struct wlr_scene_buffer *scene_buf |
1414 | 1401 | pixman_region32_fini(&cull_region); |
1415 | 1402 |
|
1416 | 1403 | // Also damage the linked drop-shadow |
1417 | | - struct wlr_scene_shadow *scene_shadow = scene_buffer->linked_drop_shadow; |
1418 | | - if (scene_shadow && SCENE_SHADOW_IS_DROP(scene_shadow)) { |
1419 | | - int shadow_lx, shadow_ly; |
1420 | | - if (wlr_scene_node_coords(&scene_shadow->node, &shadow_lx, &shadow_ly)) { |
1421 | | - const int shadow_size = drop_shadow_calc_size(scene_shadow->blur_sigma); |
1422 | | - |
1423 | | - // Copy the damaged region, translate it to the shadow nodes |
1424 | | - // position, and add it to the original damage |
1425 | | - pixman_region32_t shadow_damage; |
1426 | | - pixman_region32_init(&shadow_damage); |
1427 | | - pixman_region32_copy(&shadow_damage, &output_damage); |
1428 | | - pixman_region32_translate(&shadow_damage, |
1429 | | - ((shadow_lx + shadow_size) - lx) * output_scale, |
1430 | | - ((shadow_ly + shadow_size) - ly) * output_scale); |
1431 | | - wlr_region_expand(&shadow_damage, &shadow_damage, |
1432 | | - drop_shadow_calc_size(scene_shadow->blur_sigma)); |
1433 | | - |
1434 | | - pixman_region32_union(&output_damage, &output_damage, &shadow_damage); |
| 1404 | + struct linked_node *shadow_link = linked_nodes_get_sibling(&scene_buffer->drop_shadow_link); |
| 1405 | + if (shadow_link != NULL) { |
| 1406 | + struct wlr_scene_shadow *scene_shadow = wl_container_of(shadow_link, scene_shadow, buffer_link); |
| 1407 | + if (scene_shadow && SCENE_SHADOW_IS_DROP(scene_shadow)) { |
| 1408 | + int shadow_lx, shadow_ly; |
| 1409 | + if (wlr_scene_node_coords(&scene_shadow->node, &shadow_lx, &shadow_ly)) { |
| 1410 | + const int shadow_size = drop_shadow_calc_size(scene_shadow->blur_sigma); |
| 1411 | + |
| 1412 | + // Copy the damaged region, translate it to the shadow nodes |
| 1413 | + // position, and add it to the original damage |
| 1414 | + pixman_region32_t shadow_damage; |
| 1415 | + pixman_region32_init(&shadow_damage); |
| 1416 | + pixman_region32_copy(&shadow_damage, &output_damage); |
| 1417 | + pixman_region32_translate(&shadow_damage, |
| 1418 | + ((shadow_lx + shadow_size) - lx) * output_scale, |
| 1419 | + ((shadow_ly + shadow_size) - ly) * output_scale); |
| 1420 | + wlr_region_expand(&shadow_damage, &shadow_damage, |
| 1421 | + drop_shadow_calc_size(scene_shadow->blur_sigma)); |
| 1422 | + |
| 1423 | + pixman_region32_union(&output_damage, &output_damage, &shadow_damage); |
| 1424 | + } |
1435 | 1425 | } |
1436 | 1426 | } |
1437 | 1427 |
|
@@ -2044,7 +2034,12 @@ static void scene_entry_render(struct render_list_entry *entry, const struct ren |
2044 | 2034 |
|
2045 | 2035 | // Drop Shadow |
2046 | 2036 | if (scene_shadow->type == WLR_SCENE_SHADOW_TYPE_DROP) { |
2047 | | - struct wlr_scene_buffer *scene_buffer = scene_shadow->reference_buffer; |
| 2037 | + struct linked_node *buffer_link = linked_nodes_get_sibling(&scene_shadow->buffer_link); |
| 2038 | + struct wlr_scene_buffer *scene_buffer = NULL; |
| 2039 | + if (buffer_link != NULL) { |
| 2040 | + scene_buffer = wl_container_of(buffer_link, scene_buffer, drop_shadow_link); |
| 2041 | + } |
| 2042 | + |
2048 | 2043 | if (!scene_buffer) { |
2049 | 2044 | wlr_log(WLR_ERROR, "Trying to render drop-shadow with NULL reference_buffer." |
2050 | 2045 | " Please set the buffer before rendering. Rendering as a box-shadow..."); |
|
0 commit comments