swayfx-mosaic/tooling/probes/step20c-core-recovery/oom/C-scene.c.patch

68 lines
3 KiB
Diff

--- a/scene.c
+++ b/scene.c
@@ -57,0 +58 @@
+ bool active; // Private sidecar only: no installed tree/node ABI change.
@@ -62 +63 @@
-static struct scene_tree_clip *scene_tree_clip_find(struct wlr_scene_tree *tree) {
+static struct scene_tree_clip *scene_tree_clip_storage(struct wlr_scene_tree *tree) {
@@ -66,0 +68,8 @@
+}
+
+// WHY: reservation must survive clip removal to make later admission allocation-free.
+// CONTRACT: inactive reservations are absent to render/hit/get callers.
+// INVARIANT: lookup never exposes an uninitialized clip rectangle.
+static struct scene_tree_clip *scene_tree_clip_find(struct wlr_scene_tree *tree) {
+ struct scene_tree_clip *entry = scene_tree_clip_storage(tree);
+ return entry && entry->active ? entry : NULL;
@@ -286,0 +296,5 @@
+ // WHY: failure must occur before tree publication to parent scene children.
+ // CONTRACT: both tree and reservation are acquired before scene_tree_init.
+ // INVARIANT: failed reservation frees unpublished tree, no listener attached.
+ struct scene_tree_clip *entry = calloc(1, sizeof(*entry));
+ if (!entry) { free(tree); return NULL; }
@@ -287,0 +302,5 @@
+ entry->tree = tree;
+ entry->destroy.notify = scene_tree_clip_destroy;
+ wl_signal_add(&tree->node.events.destroy, &entry->destroy);
+ entry->next = scene_tree_clips;
+ scene_tree_clips = entry;
@@ -984,29 +1003,10 @@
- // CONTRACT: tree is required; a supplied box is copied and must have
- // nonnegative dimensions. NULL removes the entry, while a zero box masks.
- assert(tree);
- assert(!clip || (clip->width >= 0 && clip->height >= 0));
- struct scene_tree_clip *entry = scene_tree_clip_find(tree);
- if (!clip && !entry) return;
- if (clip && entry && memcmp(&entry->box, clip, sizeof(*clip)) == 0) return;
- wlr_log(WLR_INFO, "SPIKE_CLIP tree=%p rect=%d,%d %dx%d",
- (void *)tree, clip ? clip->x : 0, clip ? clip->y : 0,
- clip ? clip->width : 0, clip ? clip->height : 0);
- if (clip && !entry) {
- entry = calloc(1, sizeof(*entry));
- // WHY: this void API cannot report an uninstalled mandatory clip.
- // CONTRACT/INVARIANT: allocation failure must never expose unclipped content.
- if (!entry) {
- wlr_log(WLR_ERROR, "Failed to allocate mandatory scene tree clip");
- abort();
- }
- entry->tree = tree;
- entry->destroy.notify = scene_tree_clip_destroy;
- wl_signal_add(&tree->node.events.destroy, &entry->destroy);
- entry->next = scene_tree_clips;
- scene_tree_clips = entry;
- }
- if (clip) {
- entry->box = *clip;
- } else {
- scene_tree_clip_remove(entry);
- }
+ // WHY: no heap allocation may occur when exposing an existing tree.
+ // CONTRACT: trees must come from the private reservation-aware create path.
+ // INVARIANT: NULL deactivates but never releases the reservation.
+ assert(tree && (!clip || (clip->width >= 0 && clip->height >= 0)));
+ struct scene_tree_clip *entry = scene_tree_clip_storage(tree);
+ assert(entry);
+ if (!clip && !entry->active) return;
+ if (clip && entry->active && memcmp(&entry->box, clip, sizeof(*clip)) == 0) return;
+ entry->active = clip != NULL;
+ if (clip) entry->box = *clip;