Subject: [PATCH 07/24] wip: bind tiled output bridge shadow

From: Justin Youens <[email-masked]>
Date: Sat, 15 Aug 2026 08:37:21 -0500

---
 src/backend/drm/TiledDRMIntegration.cpp | 151 +++++++++++++++++-------
 src/backend/drm/TiledDRMIntegration.hpp |  11 ++
 src/backend/drm/TiledOutputBridge.cpp   |   8 +-
 src/backend/drm/TiledOutputBridge.hpp   |   1 +
 tests/TiledDRMIntegration.cpp           |  66 ++++++++++-
 5 files changed, 191 insertions(+), 46 deletions(-)

diff --git a/src/backend/drm/TiledDRMIntegration.cpp b/src/backend/drm/TiledDRMIntegration.cpp
index 20cfec1da1181b6cd24acfcdd70cd341caaf8964..82505f5a46f5ffad663b48e348db77f3ea07a813 100644
--- a/src/backend/drm/TiledDRMIntegration.cpp
+++ b/src/backend/drm/TiledDRMIntegration.cpp
@@ -16,6 +16,7 @@ using namespace Aquamarine;
 using namespace Aquamarine::NDRM::NTiledDRMIntegration;
 using namespace Aquamarine::NDRM::NTiledIncarnations;
 using namespace Aquamarine::NDRM::NTiledCrtcAllocator;
+using namespace Aquamarine::NDRM::NTiledOutputBridge;
 using namespace Aquamarine::NDRM::NTiledScan;
 
 namespace {
@@ -64,15 +65,16 @@ namespace {
 class CTiledDRMIntegrationRegistry::CImpl {
   public:
     struct SEntry {
-        PBackendLifetime    lifetime;
-        PDeviceIncarnation  device;
-        PSessionIncarnation session;
-        uint64_t            resourceEpoch   = 0;
-        uint64_t            allocationEpoch = 0;
-        PAllocationShadow   allocationShadow;
-        bool                allocationGateActive = false;
-        bool                detachBegun          = false;
-        eDetachReason       detachReason         = eDetachReason::BACKEND_SHUTDOWN;
+        PBackendLifetime                   lifetime;
+        PDeviceIncarnation                 device;
+        PSessionIncarnation                session;
+        uint64_t                           resourceEpoch   = 0;
+        uint64_t                           allocationEpoch = 0;
+        PAllocationShadow                  allocationShadow;
+        CSharedPointer<COutputBridgeState> outputBridge;
+        bool                               allocationGateActive = false;
+        bool                               detachBegun          = false;
+        eDetachReason                      detachReason         = eDetachReason::BACKEND_SHUTDOWN;
     };
 
     explicit CImpl(std::thread::id thread) : eventThread(thread), scanRegistry(thread) {}
@@ -101,6 +103,12 @@ class CTiledDRMIntegrationRegistry::CImpl {
         return std::this_thread::get_id() == eventThread;
     }
 
+    void invalidateOutputBridge(SEntry& entry) noexcept {
+        entry.allocationShadow.reset();
+        if (!entry.outputBridge || !entry.outputBridge->clear())
+            std::terminate();
+    }
+
     std::thread::id                        eventThread;
     CTiledBackendStateRegistry             scanRegistry;
     std::map<const void*, SEntry>          entries;
@@ -161,7 +169,7 @@ SBeginConnectorScanResult CTiledDRMIntegrationRegistry::beginAttached(const void
         return {.result = eScanBeginResult::BUSY};
 
     setLastScan(key, false);
-    ENTRY->second.allocationShadow.reset();
+    m_impl->invalidateOutputBridge(ENTRY->second);
     if (ENTRY->second.resourceEpoch == std::numeric_limits<uint64_t>::max())
         return {.result = eScanBeginResult::EXHAUSTED};
 
@@ -263,9 +271,10 @@ SBeginConnectorScanResult CTiledDRMIntegrationRegistry::beginConnectorScan(const
     try {
         const auto [ITERATOR, INSERTED] = m_impl->entries.emplace(KEY,
                                                                   CImpl::SEntry{
-                                                                      .lifetime = lifetime,
-                                                                      .device   = device,
-                                                                      .session  = session,
+                                                                      .lifetime     = lifetime,
+                                                                      .device       = device,
+                                                                      .session      = session,
+                                                                      .outputBridge = CSharedPointer<COutputBridgeState>{new COutputBridgeState{m_impl->eventThread}},
                                                                   });
         inserted                        = INSERTED;
         if (!INSERTED) {
@@ -350,9 +359,10 @@ SBeginConnectorScanResult CTiledDRMIntegrationRegistry::beginTestConnectorScan(c
     try {
         const auto [ITERATOR, INSERTED] = m_impl->entries.emplace(KEY,
                                                                   CImpl::SEntry{
-                                                                      .lifetime = lifetime,
-                                                                      .device   = device,
-                                                                      .session  = session,
+                                                                      .lifetime     = lifetime,
+                                                                      .device       = device,
+                                                                      .session      = session,
+                                                                      .outputBridge = CSharedPointer<COutputBridgeState>{new COutputBridgeState{m_impl->eventThread}},
                                                                   });
         inserted                        = INSERTED;
         if (!INSERTED) {
@@ -530,19 +540,24 @@ eAllocationCaptureResult CTiledDRMIntegrationRegistry::captureAllocationKey(cons
 
     // A failed replacement never leaves an older shadow looking current.
     ENTRY->second.allocationShadow.reset();
-
-    auto* const STATE = m_impl->scanRegistry.find(ENTRY->second.lifetime);
-    if (!STATE)
-        return eAllocationCaptureResult::NO_CURRENT_SCAN;
-    const auto SCAN = STATE->currentComplete();
-    if (!SCAN)
-        return eAllocationCaptureResult::NO_CURRENT_SCAN;
-    if (ENTRY->second.allocationEpoch == std::numeric_limits<uint64_t>::max())
-        return eAllocationCaptureResult::EXHAUSTED;
-    if (!capture.leasesKnownClear)
-        return eAllocationCaptureResult::INVALID_CAPTURE;
-
+    bool captureInstalled = false;
     try {
+        Hyprutils::Utils::CScopeGuard bridgeGuard([&] {
+            if (!captureInstalled)
+                m_impl->invalidateOutputBridge(ENTRY->second);
+        });
+
+        auto* const                   STATE = m_impl->scanRegistry.find(ENTRY->second.lifetime);
+        if (!STATE)
+            return eAllocationCaptureResult::NO_CURRENT_SCAN;
+        const auto SCAN = STATE->currentComplete();
+        if (!SCAN)
+            return eAllocationCaptureResult::NO_CURRENT_SCAN;
+        if (ENTRY->second.allocationEpoch == std::numeric_limits<uint64_t>::max())
+            return eAllocationCaptureResult::EXHAUSTED;
+        if (!capture.leasesKnownClear)
+            return eAllocationCaptureResult::INVALID_CAPTURE;
+
         const auto ALLOCATION_EPOCH = ENTRY->second.allocationEpoch + 1;
         if (capture.resourceCRTCOrder.size() > std::numeric_limits<uint32_t>::digits || capture.resourceCRTCOrder.size() != capture.crtcs.size())
             return eAllocationCaptureResult::INVALID_CAPTURE;
@@ -763,25 +778,27 @@ eAllocationCaptureResult CTiledDRMIntegrationRegistry::captureAllocationKey(cons
         if (!PLAN || PLAN->status() != ePlanStatus::READY)
             return eAllocationCaptureResult::NO_READY_PLAN;
 
-        SCurrentState current = {
-            .backendLifetime = ENTRY->second.lifetime,
-            .device          = ENTRY->second.device,
-            .session         = ENTRY->second.session,
-            .scan            = SCAN,
-            .scanObservation = SCAN->observation(),
-            .snapshot        = SNAPSHOT,
-            .observation     = OBSERVATION,
-            .epoch           = EPOCH,
-        };
-        if (!withCurrentPlan(PLAN, current, [](const CPlan&) {}))
-            return eAllocationCaptureResult::NO_READY_PLAN;
         PAllocationShadow shadow{new CAllocationShadow{PLAN}};
 
         ENTRY->second.allocationEpoch  = ALLOCATION_EPOCH;
-        ENTRY->second.allocationShadow = std::move(shadow);
+        ENTRY->second.allocationShadow = shadow;
+
+        bool       bridgeInstalled = false;
+        const auto CURRENT         = withCurrentAllocationKey(key, shadow, [&](const CPlan& currentPlan, const SCurrentState& current) {
+            if (&currentPlan != PLAN.get())
+                return;
+            const auto PREPARED = ENTRY->second.outputBridge->prepare(PLAN);
+            if (!PREPARED)
+                return;
+            bridgeInstalled = ENTRY->second.outputBridge->install(PREPARED.prepared, current) == eInstallResult::INSTALLED;
+        });
+        if (!CURRENT || !bridgeInstalled)
+            return eAllocationCaptureResult::INVALID_CAPTURE;
+
+        captureInstalled = true;
         return eAllocationCaptureResult::INSTALLED;
     } catch (...) {
-        ENTRY->second.allocationShadow.reset();
+        m_impl->invalidateOutputBridge(ENTRY->second);
         return eAllocationCaptureResult::INVALID_CAPTURE;
     }
 }
@@ -810,6 +827,16 @@ PAllocationShadow CTiledDRMIntegrationRegistry::testCurrentAllocationShadow(cons
     return currentAllocationKey(lifetime.impl_);
 }
 
+POutputBridgeObservation CTiledDRMIntegrationRegistry::testCurrentOutputBridge(const PBackendLifetime& lifetime) noexcept {
+    const auto THREAD = m_impl->registeredThread(lifetime.impl_);
+    if (!THREAD || *THREAD != std::this_thread::get_id())
+        return {};
+    const auto ENTRY = m_impl->entries.find(lifetime.impl_);
+    if (ENTRY == m_impl->entries.end() || !ENTRY->second.outputBridge)
+        return {};
+    return ENTRY->second.outputBridge->diagnosticInstalled();
+}
+
 bool CTiledDRMIntegrationRegistry::withCurrentAllocationKey(const void* key, const PAllocationShadow& expected,
                                                             const std::function<void(const CPlan&, const SCurrentState&)>& callback) noexcept {
     const auto THREAD = m_impl->registeredThread(key);
@@ -858,11 +885,41 @@ bool CTiledDRMIntegrationRegistry::withCurrentAllocationShadow(const CWeakPointe
     return withCurrentAllocationKey(backend.impl_, expected, callback);
 }
 
+bool CTiledDRMIntegrationRegistry::withCurrentOutputBridgeKey(const void* key, const PAllocationShadow& expected,
+                                                              const std::function<void(const POutputBridgeObservation&)>& callback) noexcept {
+    if (!callback)
+        return false;
+    bool bridgeCurrent = false;
+    bool invoked       = false;
+    try {
+        const auto ALLOCATION_CURRENT = withCurrentAllocationKey(key, expected, [&](const CPlan&, const SCurrentState& current) {
+            const auto ENTRY = m_impl->entries.find(key);
+            if (ENTRY == m_impl->entries.end() || !ENTRY->second.outputBridge)
+                return;
+            bridgeCurrent = ENTRY->second.outputBridge->withCurrentOwner(current, [&](const POutputBridgeObservation& observation) {
+                callback(observation);
+                invoked = true;
+            });
+        });
+        return ALLOCATION_CURRENT && bridgeCurrent && invoked;
+    } catch (...) { return false; }
+}
+
+bool CTiledDRMIntegrationRegistry::withCurrentOutputBridge(const CWeakPointer<CDRMBackend>& backend, const PAllocationShadow& expected,
+                                                           const std::function<void(const POutputBridgeObservation&)>& callback) noexcept {
+    return withCurrentOutputBridgeKey(backend.impl_, expected, callback);
+}
+
 bool CTiledDRMIntegrationRegistry::withCurrentTestAllocationShadow(const PBackendLifetime& lifetime, const PAllocationShadow& expected,
                                                                    const std::function<void(const CPlan&, const SCurrentState&)>& callback) noexcept {
     return withCurrentAllocationKey(lifetime.impl_, expected, callback);
 }
 
+bool CTiledDRMIntegrationRegistry::withCurrentTestOutputBridge(const PBackendLifetime& lifetime, const PAllocationShadow& expected,
+                                                               const std::function<void(const POutputBridgeObservation&)>& callback) noexcept {
+    return withCurrentOutputBridgeKey(lifetime.impl_, expected, callback);
+}
+
 eSessionResult CTiledDRMIntegrationRegistry::rotateSessionKey(const void* key) noexcept {
     const auto THREAD = m_impl->registeredThread(key);
     if (!THREAD)
@@ -877,7 +934,7 @@ eSessionResult CTiledDRMIntegrationRegistry::rotateSessionKey(const void* key) n
         return eSessionResult::BUSY;
 
     setLastScan(key, false);
-    ENTRY->second.allocationShadow.reset();
+    m_impl->invalidateOutputBridge(ENTRY->second);
     auto* const STATE = m_impl->scanRegistry.find(ENTRY->second.lifetime);
     if (!STATE)
         return eSessionResult::INVALID_STATE;
@@ -928,7 +985,7 @@ eDetachResult CTiledDRMIntegrationRegistry::beginDetachKey(const void* key, eDet
         return eDetachResult::BUSY;
 
     setLastScan(key, false);
-    ENTRY->second.allocationShadow.reset();
+    m_impl->invalidateOutputBridge(ENTRY->second);
 
     const auto RESULT = m_impl->scanRegistry.beginTeardown(ENTRY->second.lifetime);
     if (RESULT == eRegistryResult::BUSY)
@@ -1099,6 +1156,12 @@ bool Aquamarine::NDRM::NTiledDRMIntegration::withCurrentAllocationShadow(const C
     return REGISTRY && REGISTRY->withCurrentAllocationShadow(backend, expected, callback);
 }
 
+bool Aquamarine::NDRM::NTiledDRMIntegration::withCurrentOutputBridge(const CWeakPointer<CDRMBackend>& backend, const PAllocationShadow& expected,
+                                                                     const std::function<void(const POutputBridgeObservation&)>& callback) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY && REGISTRY->withCurrentOutputBridge(backend, expected, callback);
+}
+
 eSessionResult Aquamarine::NDRM::NTiledDRMIntegration::rotateSession(const CWeakPointer<CDRMBackend>& backend) noexcept {
     auto* const REGISTRY = productionRegistryIfCreated();
     return REGISTRY ? REGISTRY->rotateSession(backend) : eSessionResult::NOT_ATTACHED;
diff --git a/src/backend/drm/TiledDRMIntegration.hpp b/src/backend/drm/TiledDRMIntegration.hpp
index 6ef88e29bcfac3fd38125f0c970097757e21cc13..4acf8437fd777041d8bb71237f036560e59b374a 100644
--- a/src/backend/drm/TiledDRMIntegration.hpp
+++ b/src/backend/drm/TiledDRMIntegration.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "TiledCrtcAllocator.hpp"
+#include "TiledOutputBridge.hpp"
 
 #include <aquamarine/backend/DRM.hpp>
 
@@ -27,6 +28,7 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
     using NTiledIncarnations::PBackendLifetime;
     using NTiledCrtcAllocator::CPlan;
     using NTiledCrtcAllocator::SCurrentState;
+    using NTiledOutputBridge::POutputBridgeObservation;
     using NTiledScan::PCommittedScan;
     using NTiledScan::PPreparedScan;
     using NTiledScan::PScanAttemptTicket;
@@ -214,6 +216,8 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
         [[nodiscard]] PAllocationShadow         currentAllocationShadow(const CWeakPointer<CDRMBackend>& backend) noexcept;
         [[nodiscard]] bool                      withCurrentAllocationShadow(const CWeakPointer<CDRMBackend>& backend, const PAllocationShadow& expected,
                                                                             const std::function<void(const CPlan&, const SCurrentState&)>& callback) noexcept;
+        [[nodiscard]] bool                      withCurrentOutputBridge(const CWeakPointer<CDRMBackend>& backend, const PAllocationShadow& expected,
+                                                                        const std::function<void(const POutputBridgeObservation&)>& callback) noexcept;
 
         [[nodiscard]] eSessionResult            rotateSession(const CWeakPointer<CDRMBackend>& backend) noexcept;
         [[nodiscard]] eDetachResult             beginDetach(const CWeakPointer<CDRMBackend>& backend, eDetachReason reason) noexcept;
@@ -240,6 +244,8 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
         [[nodiscard]] PAllocationShadow         currentAllocationKey(const void* key) noexcept;
         [[nodiscard]] bool                      withCurrentAllocationKey(const void* key, const PAllocationShadow& expected,
                                                                          const std::function<void(const CPlan&, const SCurrentState&)>& callback) noexcept;
+        [[nodiscard]] bool                      withCurrentOutputBridgeKey(const void* key, const PAllocationShadow& expected,
+                                                                           const std::function<void(const POutputBridgeObservation&)>& callback) noexcept;
         void                                    abortConnectorScan(CConnectorScan& scan) noexcept;
 
         [[nodiscard]] SBeginConnectorScanResult beginTestConnectorScan(const PBackendLifetime& lifetime);
@@ -252,8 +258,11 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
         [[nodiscard]] SScanOutcome              testOutcome(const PBackendLifetime& lifetime) noexcept;
         [[nodiscard]] eAllocationCaptureResult  captureTestAllocationShadow(const PBackendLifetime& lifetime, SAllocationCapture capture) noexcept;
         [[nodiscard]] PAllocationShadow         testCurrentAllocationShadow(const PBackendLifetime& lifetime) noexcept;
+        [[nodiscard]] POutputBridgeObservation  testCurrentOutputBridge(const PBackendLifetime& lifetime) noexcept;
         [[nodiscard]] bool                      withCurrentTestAllocationShadow(const PBackendLifetime& lifetime, const PAllocationShadow& expected,
                                                                                 const std::function<void(const CPlan&, const SCurrentState&)>& callback) noexcept;
+        [[nodiscard]] bool                      withCurrentTestOutputBridge(const PBackendLifetime& lifetime, const PAllocationShadow& expected,
+                                                                            const std::function<void(const POutputBridgeObservation&)>& callback) noexcept;
         [[nodiscard]] bool                      exhaustTestResourceEpoch(const PBackendLifetime& lifetime) noexcept;
 
         class CImpl;
@@ -272,6 +281,8 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
     [[nodiscard]] AQ_TILED_DRM_PRIVATE PAllocationShadow         currentAllocationShadow(const CWeakPointer<CDRMBackend>& backend) noexcept;
     [[nodiscard]] AQ_TILED_DRM_PRIVATE bool                      withCurrentAllocationShadow(const CWeakPointer<CDRMBackend>& backend, const PAllocationShadow& expected,
                                                                                              const std::function<void(const CPlan&, const SCurrentState&)>& callback) noexcept;
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE bool                      withCurrentOutputBridge(const CWeakPointer<CDRMBackend>& backend, const PAllocationShadow& expected,
+                                                                                         const std::function<void(const POutputBridgeObservation&)>& callback) noexcept;
     [[nodiscard]] AQ_TILED_DRM_PRIVATE eSessionResult            rotateSession(const CWeakPointer<CDRMBackend>& backend) noexcept;
     [[nodiscard]] AQ_TILED_DRM_PRIVATE eDetachResult             beginDetach(const CWeakPointer<CDRMBackend>& backend, eDetachReason reason) noexcept;
     [[nodiscard]] AQ_TILED_DRM_PRIVATE eDetachResult             eraseDetached(const CWeakPointer<CDRMBackend>& backend) noexcept;
diff --git a/src/backend/drm/TiledOutputBridge.cpp b/src/backend/drm/TiledOutputBridge.cpp
index 8b0b3f8c1c7eeacb953f65223ab712168c59e3e5..f014822b0ca8c9e7feaa5b85d0f3e70815a6752e 100644
--- a/src/backend/drm/TiledOutputBridge.cpp
+++ b/src/backend/drm/TiledOutputBridge.cpp
@@ -579,10 +579,16 @@ namespace Aquamarine::NDRM::NTiledOutputBridge { // NOLINT(readability-identifie
     }
 
     bool COutputBridgeState::withCurrent(const SCurrentState& current, const std::function<void(const COutputBridgeObservation&)>& callback) const {
+        if (!callback)
+            return false;
+        return withCurrentOwner(current, [&](const POutputBridgeObservation& installed) { callback(*installed); });
+    }
+
+    bool COutputBridgeState::withCurrentOwner(const SCurrentState& current, const std::function<void(const POutputBridgeObservation&)>& callback) const {
         if (!onEventThread() || !callback || !m_installed)
             return false;
         const auto INSTALLED = m_installed;
-        return NTiledCrtcAllocator::withCurrentPlan(INSTALLED->capturedPlan(), current, [&](const CPlan&) { callback(*INSTALLED); });
+        return NTiledCrtcAllocator::withCurrentPlan(INSTALLED->capturedPlan(), current, [&](const CPlan&) { callback(INSTALLED); });
     }
 
     CSharedPointer<const COutputBridgeObservation> COutputBridgeState::diagnosticInstalled() const {
diff --git a/src/backend/drm/TiledOutputBridge.hpp b/src/backend/drm/TiledOutputBridge.hpp
index ef99fc44cfa8f15f98b4113b9c5b1559f643e192..caa521e296f0c000d5552653fcd00e8ba638924b 100644
--- a/src/backend/drm/TiledOutputBridge.hpp
+++ b/src/backend/drm/TiledOutputBridge.hpp
@@ -259,6 +259,7 @@ namespace Aquamarine::NDRM::NTiledOutputBridge { // NOLINT(readability-identifie
         // The callback is synchronous and executes only while the allocator's
         // exact current-plan gate holds the production backend alive.
         [[nodiscard]] bool withCurrent(const SCurrentState& current, const std::function<void(const COutputBridgeObservation&)>& callback) const;
+        [[nodiscard]] bool withCurrentOwner(const SCurrentState& current, const std::function<void(const POutputBridgeObservation&)>& callback) const;
 
         // Diagnostics/tests only. This owner may be stale immediately after
         // it is returned and must never authorize output or KMS behavior.
diff --git a/tests/TiledDRMIntegration.cpp b/tests/TiledDRMIntegration.cpp
index af54d041c8f02f566ea241d9a64bdb424294e2c6..ecd0678b24c60969f0dbe9f58ee9beca17488954 100644
--- a/tests/TiledDRMIntegration.cpp
+++ b/tests/TiledDRMIntegration.cpp
@@ -14,6 +14,7 @@
 using namespace Aquamarine::NDRM::NTiledDRMIntegration;
 using namespace Aquamarine::NDRM::NTiledIncarnations;
 using namespace Aquamarine::NDRM::NTiledCrtcAllocator;
+using namespace Aquamarine::NDRM::NTiledOutputBridge;
 using namespace Aquamarine::NDRM::NTiledScan;
 using namespace Hyprutils::Memory;
 
@@ -62,11 +63,20 @@ namespace Aquamarine::NDRM::NTiledDRMIntegrationTest {
             return registry.testCurrentAllocationShadow(lifetime);
         }
 
+        static POutputBridgeObservation outputBridge(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime) {
+            return registry.testCurrentOutputBridge(lifetime);
+        }
+
         static bool withCurrent(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime, const PAllocationShadow& expected,
                                 const std::function<void(const CPlan&, const SCurrentState&)>& callback) {
             return registry.withCurrentTestAllocationShadow(lifetime, expected, callback);
         }
 
+        static bool withCurrentOutputBridge(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime, const PAllocationShadow& expected,
+                                            const std::function<void(const POutputBridgeObservation&)>& callback) {
+            return registry.withCurrentTestOutputBridge(lifetime, expected, callback);
+        }
+
         static bool exhaustResourceEpoch(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime) {
             return registry.exhaustTestResourceEpoch(lifetime);
         }
@@ -188,6 +198,25 @@ namespace {
             .leasesKnownClear = true,
         };
     }
+
+    SAllocationCapture noMatchAllocationCapture() {
+        auto capture = allocationCapture();
+        capture.resourceCRTCOrder.resize(1);
+        capture.connectors.at(1).possibleCRTCMask = 0b01;
+        capture.connectors.at(1).assignedCRTCID   = 0;
+        capture.connectors.at(1).kernelCRTCID     = 0;
+        capture.crtcs.resize(1);
+        capture.primaryPlanes.resize(1);
+        return capture;
+    }
+
+    const CGroupProjection* multiStreamGroup(const POutputBridgeObservation& observation) {
+        if (!observation)
+            return nullptr;
+        const auto GROUP = std::ranges::find_if(
+            observation->groups(), [](const auto& candidate) { return candidate.scanDefinition()->group().kind == Aquamarine::NTiling::eTileGroupKind::MULTI_STREAM; });
+        return GROUP == observation->groups().end() ? nullptr : &*GROUP;
+    }
 }
 
 int main() {
@@ -312,6 +341,17 @@ int main() {
         EXPECT(SHADOW ? SHADOW->plan()->groups().size() : 0U, 1U);
         EXPECT(SHADOW && SHADOW->plan()->groups().front().status() == eGroupStatus::ALLOCATED, true);
         EXPECT(SHADOW ? SHADOW->plan()->groups().front().bindings().at(1).primaryPlane()->id : 0U, 101U);
+        const auto  BRIDGE          = CFixtureAuthority::outputBridge(registry, LIFETIME);
+        const auto* ALLOCATED_GROUP = multiStreamGroup(BRIDGE);
+        EXPECT(!!BRIDGE, true);
+        EXPECT(ALLOCATED_GROUP && ALLOCATED_GROUP->projection() == eGroupProjection::MULTI_STREAM_ALLOCATED, true);
+        EXPECT(ALLOCATED_GROUP && ALLOCATED_GROUP->definitionIdentity(), true);
+        EXPECT(ALLOCATED_GROUP && ALLOCATED_GROUP->modeSet(), true);
+        const auto DEFINITION_IDENTITY = ALLOCATED_GROUP ? ALLOCATED_GROUP->definitionIdentity() : POutputDefinitionIdentity{};
+        const auto OUTPUT_MODE = ALLOCATED_GROUP && ALLOCATED_GROUP->modeSet() ? ALLOCATED_GROUP->modeSet()->modes().front().outputMode : CSharedPointer<Aquamarine::SOutputMode>{};
+        POutputBridgeObservation gatedBridge;
+        EXPECT(CFixtureAuthority::withCurrentOutputBridge(registry, LIFETIME, SHADOW, [&](const auto& current) { gatedBridge = current; }), true);
+        EXPECT(gatedBridge == BRIDGE, true);
         size_t                    callbacks     = 0;
         bool                      exactScan     = false;
         bool                      nestedCurrent = true;
@@ -344,10 +384,23 @@ int main() {
         EXPECT(CFixtureAuthority::allocation(registry, LIFETIME) == SHADOW, true);
         EXPECT(CFixtureAuthority::lastComplete(registry, LIFETIME), true);
 
+        EXPECT(value(CFixtureAuthority::capture(registry, LIFETIME, noMatchAllocationCapture())), value(eAllocationCaptureResult::INSTALLED));
+        const auto  FALLBACK_SHADOW = CFixtureAuthority::allocation(registry, LIFETIME);
+        const auto  FALLBACK_BRIDGE = CFixtureAuthority::outputBridge(registry, LIFETIME);
+        const auto* FALLBACK_GROUP  = multiStreamGroup(FALLBACK_BRIDGE);
+        EXPECT(FALLBACK_SHADOW && FALLBACK_SHADOW->plan()->groups().front().status() == eGroupStatus::NO_MATCH, true);
+        EXPECT(FALLBACK_GROUP && FALLBACK_GROUP->projection() == eGroupProjection::MULTI_STREAM_FALLBACK, true);
+        EXPECT(FALLBACK_GROUP && FALLBACK_GROUP->definitionIdentity() == DEFINITION_IDENTITY, true);
+        EXPECT(FALLBACK_GROUP && FALLBACK_GROUP->modeSet() && FALLBACK_GROUP->modeSet()->modes().front().outputMode == OUTPUT_MODE, true);
+        EXPECT(CFixtureAuthority::withCurrent(registry, LIFETIME, SHADOW, [&](const CPlan&, const SCurrentState&) { ++callbacks; }), false);
+        EXPECT(CFixtureAuthority::withCurrentOutputBridge(registry, LIFETIME, SHADOW, [&](const auto&) { ++callbacks; }), false);
+        EXPECT(callbacks, 1U);
+
         auto pending                = allocationCapture();
         pending.crtcs.at(0).pending = true;
         EXPECT(value(CFixtureAuthority::capture(registry, LIFETIME, std::move(pending))), value(eAllocationCaptureResult::INVALID_CAPTURE));
         EXPECT(!!CFixtureAuthority::allocation(registry, LIFETIME), false);
+        EXPECT(!!CFixtureAuthority::outputBridge(registry, LIFETIME), false);
         EXPECT(CFixtureAuthority::withCurrent(registry, LIFETIME, SHADOW, [&](const CPlan&, const SCurrentState&) { ++callbacks; }), false);
         EXPECT(callbacks, 1U);
 
@@ -355,16 +408,22 @@ int main() {
         ambiguous.leasesKnownClear = false;
         EXPECT(value(CFixtureAuthority::capture(registry, LIFETIME, std::move(ambiguous))), value(eAllocationCaptureResult::INVALID_CAPTURE));
         EXPECT(!!CFixtureAuthority::allocation(registry, LIFETIME), false);
+        EXPECT(!!CFixtureAuthority::outputBridge(registry, LIFETIME), false);
 
         EXPECT(value(CFixtureAuthority::capture(registry, LIFETIME, allocationCapture())), value(eAllocationCaptureResult::INSTALLED));
-        const auto REPLACEMENT = CFixtureAuthority::allocation(registry, LIFETIME);
+        const auto  REPLACEMENT        = CFixtureAuthority::allocation(registry, LIFETIME);
+        const auto  REPLACEMENT_BRIDGE = CFixtureAuthority::outputBridge(registry, LIFETIME);
+        const auto* REPLACEMENT_GROUP  = multiStreamGroup(REPLACEMENT_BRIDGE);
         EXPECT(!!REPLACEMENT, true);
         EXPECT(REPLACEMENT != SHADOW, true);
+        EXPECT(REPLACEMENT_GROUP && REPLACEMENT_GROUP->projection() == eGroupProjection::MULTI_STREAM_ALLOCATED, true);
+        EXPECT(REPLACEMENT_GROUP && REPLACEMENT_GROUP->definitionIdentity() != DEFINITION_IDENTITY, true);
         EXPECT(CFixtureAuthority::withCurrent(registry, LIFETIME, SHADOW, [&](const CPlan&, const SCurrentState&) { ++callbacks; }), false);
         EXPECT(callbacks, 1U);
         auto begun = CFixtureAuthority::begin(registry, LIFETIME);
         EXPECT(value(begun.result), value(eScanBeginResult::STARTED));
         EXPECT(!!CFixtureAuthority::allocation(registry, LIFETIME), false);
+        EXPECT(!!CFixtureAuthority::outputBridge(registry, LIFETIME), false);
         EXPECT(CFixtureAuthority::withCurrent(registry, LIFETIME, REPLACEMENT, [&](const CPlan&, const SCurrentState&) { ++callbacks; }), false);
         EXPECT(callbacks, 1U);
         registry.abortConnectorScan(begun.scan);
@@ -379,6 +438,7 @@ int main() {
         EXPECT(value(CFixtureAuthority::capture(registry, LIFETIME, allocationCapture())), value(eAllocationCaptureResult::INSTALLED));
         const auto BEFORE_ROTATE = CFixtureAuthority::allocation(registry, LIFETIME);
         EXPECT(value(CFixtureAuthority::rotate(registry, LIFETIME)), value(eSessionResult::ROTATED));
+        EXPECT(!!CFixtureAuthority::outputBridge(registry, LIFETIME), false);
         EXPECT(CFixtureAuthority::withCurrent(registry, LIFETIME, BEFORE_ROTATE, [&](const CPlan&, const SCurrentState&) { ++callbacks; }), false);
         EXPECT(callbacks, 1U);
 
@@ -396,11 +456,15 @@ int main() {
         EXPECT(value(EXHAUSTED.result), value(eScanBeginResult::EXHAUSTED));
         EXPECT(!!EXHAUSTED.scan, false);
         EXPECT(!!CFixtureAuthority::allocation(registry, LIFETIME), false);
+        EXPECT(!!CFixtureAuthority::outputBridge(registry, LIFETIME), false);
         EXPECT(CFixtureAuthority::lastComplete(registry, LIFETIME), false);
         EXPECT(CFixtureAuthority::withCurrent(registry, LIFETIME, BEFORE_EXHAUSTION, [&](const CPlan&, const SCurrentState&) { ++callbacks; }), false);
         EXPECT(callbacks, 1U);
 
+        EXPECT(value(CFixtureAuthority::capture(registry, LIFETIME, allocationCapture())), value(eAllocationCaptureResult::INSTALLED));
+        EXPECT(!!CFixtureAuthority::outputBridge(registry, LIFETIME), true);
         EXPECT(value(CFixtureAuthority::beginDetach(registry, LIFETIME, eDetachReason::BACKEND_SHUTDOWN)), value(eDetachResult::BEGUN));
+        EXPECT(!!CFixtureAuthority::outputBridge(registry, LIFETIME), false);
         EXPECT(value(CFixtureAuthority::erase(registry, LIFETIME)), value(eDetachResult::DETACHED));
     }