Subject: [PATCH 03/21] wip: add transactional tiled DRM integration

From: Justin Youens <[email-masked]>
Date: Sat, 15 Aug 2026 07:30:42 -0500

---
 CMakeLists.txt                          |   4 +-
 src/backend/Backend.cpp                 |  58 +-
 src/backend/drm/DRM.cpp                 | 506 ++++++++++++++---
 src/backend/drm/DRMIncarnations.hpp     |   5 +
 src/backend/drm/TiledDRMIntegration.cpp | 724 ++++++++++++++++++++++++
 src/backend/drm/TiledDRMIntegration.hpp | 197 +++++++
 tests/ConnectorScan.cpp                 |  53 ++
 tests/TiledDRMIntegration.cpp           | 201 +++++++
 tests/TiledVisibility.cmake             |   2 +-
 9 files changed, 1669 insertions(+), 81 deletions(-)
 create mode 100644 src/backend/drm/TiledDRMIntegration.cpp
 create mode 100644 src/backend/drm/TiledDRMIntegration.hpp
 create mode 100644 tests/TiledDRMIntegration.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index cc5cce4b61fc93494e736db88c82df01448e1376..7ab0b83cfa7d00c76dc86d70cbac169dfa2f6df6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,7 +67,8 @@ set(AQUAMARINE_TILED_PRIVATE_SOURCES
     "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/Tile.cpp"
     "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TileModes.cpp"
     "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TiledBackendState.cpp"
-    "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TiledCrtcAllocator.cpp")
+    "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TiledCrtcAllocator.cpp"
+    "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TiledDRMIntegration.cpp")
 list(REMOVE_ITEM SRCFILES ${AQUAMARINE_TILED_PRIVATE_SOURCES})
 
 add_library(aquamarine_tiled_private STATIC ${AQUAMARINE_TILED_PRIVATE_SOURCES})
@@ -202,6 +203,7 @@ addTiledPrivateTest(connectorScan "tests/ConnectorScan.cpp")
 addTiledPrivateTest(tileTopology "tests/TileTopology.cpp")
 addTiledPrivateTest(tileModes "tests/TileModes.cpp")
 addTiledPrivateTest(tiledBackendState "tests/TiledBackendState.cpp")
+addTiledPrivateTest(tiledDRMIntegration "tests/TiledDRMIntegration.cpp")
 addTiledPrivateTest(planeFormats "tests/PlaneFormats.cpp")
 addTiledPrivateTest(planeViewport "tests/PlaneViewport.cpp")
 addTiledPrivateTest(tiledCrtcAllocator "tests/TiledCrtcAllocator.cpp")
diff --git a/src/backend/Backend.cpp b/src/backend/Backend.cpp
index dbd714757e4ad24be760fed39c16265559fabba4..ceee7131334aa34ae04de427602f5295f773f2fc 100644
--- a/src/backend/Backend.cpp
+++ b/src/backend/Backend.cpp
@@ -9,11 +9,13 @@
 #include <sys/timerfd.h>
 #include <ctime>
 #include <cstring>
+#include <exception>
 #include <xf86drm.h>
 #include <fcntl.h>
 #include <unistd.h>
 
 #include "Logger.hpp"
+#include "drm/TiledDRMIntegration.hpp"
 
 using namespace Hyprutils::Memory;
 using namespace Hyprutils::OS;
@@ -115,6 +117,25 @@ Aquamarine::CBackend::~CBackend() {
 
     // Tear down implementations before the logger is destroyed,
     // as backends may log during teardown (e.g. SDRMConnector::disconnect).
+    for (const auto& implementation : implementations) {
+        const auto DRM = dynamicPointerCast<CDRMBackend>(implementation);
+        if (!DRM)
+            continue;
+
+        const auto DETACH = NDRM::NTiledDRMIntegration::beginDetach(DRM, NDRM::NTiledDRMIntegration::eDetachReason::BACKEND_SHUTDOWN);
+        if (DETACH != NDRM::NTiledDRMIntegration::eDetachResult::NOT_ATTACHED && DETACH != NDRM::NTiledDRMIntegration::eDetachResult::BEGUN &&
+            DETACH != NDRM::NTiledDRMIntegration::eDetachResult::ALREADY_BEGUN)
+            std::terminate();
+
+        DRM->listeners.sessionActivate.reset();
+        DRM->listeners.gpuChange.reset();
+        DRM->listeners.gpuRemove.reset();
+        for (auto& connector : DRM->connectors) {
+            connector->disconnect();
+            connector.reset();
+        }
+        DRM->connectors.clear();
+    }
     implementations.clear();
 }
 
@@ -131,6 +152,30 @@ bool Aquamarine::CBackend::start() {
         return SBackendImplementationOptions{};
     };
 
+    const auto PREPARE_DRM_DROP = [](const SP<IBackendImplementation>& implementation) {
+        const auto DRM = dynamicPointerCast<CDRMBackend>(implementation);
+        if (!DRM)
+            return;
+
+        const auto DETACH = NDRM::NTiledDRMIntegration::beginDetach(DRM, NDRM::NTiledDRMIntegration::eDetachReason::INITIALIZATION_ABORTED);
+        if (DETACH != NDRM::NTiledDRMIntegration::eDetachResult::NOT_ATTACHED && DETACH != NDRM::NTiledDRMIntegration::eDetachResult::BEGUN &&
+            DETACH != NDRM::NTiledDRMIntegration::eDetachResult::ALREADY_BEGUN)
+            std::terminate();
+
+        DRM->listeners.sessionActivate.reset();
+        DRM->listeners.gpuChange.reset();
+        DRM->listeners.gpuRemove.reset();
+        for (auto& connector : DRM->connectors) {
+            connector->disconnect();
+            connector.reset();
+        }
+        DRM->connectors.clear();
+    };
+    const auto PREPARE_ALL_DRM_DROPS = [&] {
+        for (const auto& implementation : implementations)
+            PREPARE_DRM_DROP(implementation);
+    };
+
     for (size_t i = 0; i < implementations.size(); ++i) {
         const auto& impl = implementations.at(i);
         const bool  ok   = impl->start();
@@ -139,6 +184,7 @@ bool Aquamarine::CBackend::start() {
             log(AQ_LOG_ERROR, std::format("Requested backend ({}) could not start, enabling fallbacks", backendTypeToName(impl->type())));
             if (optionsForType(impl->type()).backendRequestMode == AQ_BACKEND_REQUEST_MANDATORY) {
                 log(AQ_LOG_CRITICAL, std::format("Requested backend ({}) could not start and it's mandatory, cannot continue!", backendTypeToName(impl->type())));
+                PREPARE_ALL_DRM_DROPS();
                 implementations.clear();
                 return false;
             }
@@ -148,14 +194,18 @@ bool Aquamarine::CBackend::start() {
 
     if (implementations.empty() || started <= 0) {
         log(AQ_LOG_CRITICAL, "No backend could be opened. Make sure there was a correct backend passed to CBackend, and that your environment supports at least one of them.");
+        PREPARE_ALL_DRM_DROPS();
+        implementations.clear();
         return false;
     }
 
     // erase failed impls
-    std::erase_if(implementations, [this](const auto& i) {
+    std::erase_if(implementations, [this, &PREPARE_DRM_DROP](const auto& i) {
         bool failed = i->pollFDs().empty() && i->type() != AQ_BACKEND_NULL;
-        if (failed)
+        if (failed) {
             log(AQ_LOG_ERROR, std::format("Implementation {} failed, erasing.", backendTypeToName(i->type())));
+            PREPARE_DRM_DROP(i);
+        }
         return failed;
     });
 
@@ -166,6 +216,8 @@ bool Aquamarine::CBackend::start() {
             if (fd < 0) {
                 // this is critical, we cannot create an allocator properly
                 log(AQ_LOG_CRITICAL, "Failed to create an allocator (reopenDRMNode failed)");
+                PREPARE_ALL_DRM_DROPS();
+                implementations.clear();
                 return false;
             }
             primaryAllocator = CGBMAllocator::create(fd, self);
@@ -175,6 +227,8 @@ bool Aquamarine::CBackend::start() {
 
     if (!primaryAllocator && (implementations.empty() || implementations.at(0)->type() != AQ_BACKEND_NULL)) {
         log(AQ_LOG_CRITICAL, "Cannot open backend: no allocator available");
+        PREPARE_ALL_DRM_DROPS();
+        implementations.clear();
         return false;
     }
 
diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp
index df61beedbaf63c679e2f09ca2c35241003cf3b4c..8ca69fd0505688f6af08692aab29d5360e48dec1 100644
--- a/src/backend/drm/DRM.cpp
+++ b/src/backend/drm/DRM.cpp
@@ -10,10 +10,12 @@
 #include <hyprutils/math/Mat3x3.hpp>
 #include <hyprutils/string/VarList.hpp>
 #include <chrono>
+#include <cstdio>
 #include <thread>
 #include <deque>
 #include <unordered_map>
 #include <cstring>
+#include <exception>
 #include <filesystem>
 #include <system_error>
 #include <sys/mman.h>
@@ -33,6 +35,9 @@ extern "C" {
 #include "Props.hpp"
 #include "FormatUtils.hpp"
 #include "Shared.hpp"
+#include "ConnectorScan.hpp"
+#include "Tile.hpp"
+#include "TiledDRMIntegration.hpp"
 #include "hwdata.hpp"
 #include "Renderer.hpp"
 
@@ -44,6 +49,117 @@ using namespace Hyprutils::Memory;
 using namespace Hyprutils::Math;
 #define SP CSharedPointer
 
+namespace {
+    using Aquamarine::NDRM::NTiledDRMIntegration::eDetachReason;
+    using Aquamarine::NDRM::NTiledDRMIntegration::eDetachResult;
+    using Aquamarine::NDRM::NTiledDRMIntegration::eScanCommitResult;
+    using Aquamarine::NDRM::NTiledDRMIntegration::eScanStageResult;
+    using Aquamarine::NDRM::NTiledScan::SConnectorView;
+    using Aquamarine::NDRM::NTiledScan::eScanCompleteness;
+
+    thread_local const void* LAST_LEGACY_SCAN_KEY      = nullptr;
+    thread_local bool        LAST_LEGACY_SCAN_COMPLETE = false;
+
+    void                     setLastLegacyScan(const void* key, bool complete) noexcept {
+        LAST_LEGACY_SCAN_KEY      = key;
+        LAST_LEGACY_SCAN_COMPLETE = complete;
+    }
+
+    bool lastLegacyScanComplete(const void* key) noexcept {
+        return LAST_LEGACY_SCAN_KEY == key && LAST_LEGACY_SCAN_COMPLETE;
+    }
+
+    struct SDRMResourcesSnapshot {
+        uint32_t              minWidth  = 0;
+        uint32_t              maxWidth  = 0;
+        uint32_t              minHeight = 0;
+        uint32_t              maxHeight = 0;
+        std::vector<uint32_t> crtcs;
+        std::vector<uint32_t> connectors;
+        std::vector<uint32_t> encoders;
+
+        bool                  operator==(const SDRMResourcesSnapshot&) const = default;
+    };
+
+    struct SStagedDRMConnector {
+        SP<SDRMConnector>        connector;
+        drmModeConnection        status = DRM_MODE_UNKNOWNCONNECTION;
+        Vector2D                 maxMode;
+        SDRMConnector::STileInfo tileInfo;
+        SConnectorView           view;
+        bool                     newlyInitialized = false;
+    };
+
+    std::optional<SDRMResourcesSnapshot> copyResourcesSnapshot(const drmModeRes* resources) {
+        if (!resources || resources->count_crtcs < 0 || resources->count_connectors < 0 || resources->count_encoders < 0 || (resources->count_crtcs > 0 && !resources->crtcs) ||
+            (resources->count_connectors > 0 && !resources->connectors) || (resources->count_encoders > 0 && !resources->encoders))
+            return std::nullopt;
+
+        const auto COPY_IDS = [](const uint32_t* ids, int count) { return count == 0 ? std::vector<uint32_t>{} : std::vector<uint32_t>{ids, ids + count}; };
+
+        return SDRMResourcesSnapshot{
+            .minWidth   = resources->min_width,
+            .maxWidth   = resources->max_width,
+            .minHeight  = resources->min_height,
+            .maxHeight  = resources->max_height,
+            .crtcs      = COPY_IDS(resources->crtcs, resources->count_crtcs),
+            .connectors = COPY_IDS(resources->connectors, resources->count_connectors),
+            .encoders   = COPY_IDS(resources->encoders, resources->count_encoders),
+        };
+    }
+
+    std::optional<uint64_t> rawConnectorProperty(const drmModeConnector* connector, uint32_t propertyId) {
+        if (!connector || propertyId == 0 || connector->count_props < 0 || (connector->count_props > 0 && (!connector->props || !connector->prop_values)))
+            return std::nullopt;
+
+        for (int i = 0; i < connector->count_props; ++i) {
+            if (connector->props[i] == propertyId)
+                return connector->prop_values[i];
+        }
+
+        return std::nullopt;
+    }
+
+    SDRMConnector::STileInfo legacyTileInfo(const std::optional<std::string>& tileProperty) {
+        SDRMConnector::STileInfo result;
+        if (!tileProperty)
+            return result;
+
+        // Preserve the legacy live-output parser byte-for-byte in spirit. The
+        // strict NTiling parser independently consumes the exact same blob in
+        // SConnectorView, but must not change existing redundancy behavior.
+        uint32_t groupId         = 0;
+        int      isSingleMonitor = 0;
+        int      numH            = 0;
+        int      numV            = 0;
+        int      hLoc            = 0;
+        int      vLoc            = 0;
+        int      hSize           = 0;
+        int      vSize           = 0;
+        if (std::sscanf(tileProperty->c_str(), "%u:%d:%d:%d:%d:%d:%d:%d", &groupId, &isSingleMonitor, &numH, &numV, &hLoc, &vLoc, &hSize, &vSize) != 8 || groupId == 0)
+            return result;
+
+        result.groupId         = groupId;
+        result.isSingleMonitor = isSingleMonitor != 0;
+        result.numHTile        = numH;
+        result.numVTile        = numV;
+        result.tileHLoc        = hLoc;
+        result.tileVLoc        = vLoc;
+        result.tileHSize       = hSize;
+        result.tileVSize       = vSize;
+        return result;
+    }
+
+    bool detachBegan(eDetachResult result) {
+        return result == eDetachResult::BEGUN || result == eDetachResult::ALREADY_BEGUN;
+    }
+
+    bool validSessionResult(Aquamarine::NDRM::NTiledDRMIntegration::eSessionResult result) {
+        using Aquamarine::NDRM::NTiledDRMIntegration::eSessionResult;
+        return result == eSessionResult::ROTATED || result == eSessionResult::NOT_ATTACHED;
+    }
+}
+
 static bool shouldSubmitCTM(SP<SDRMConnector> connector, const COutputState::SInternalState& state, bool modeset) {
     if (state.committed & COutputState::AQ_OUTPUT_STATE_CTM)
         return true;
@@ -59,10 +175,19 @@ static bool shouldSubmitCTM(SP<SDRMConnector> connector, const COutputState::SIn
 
 Aquamarine::CDRMBackend::CDRMBackend(SP<CBackend> backend_) : backend(backend_) {
     listeners.sessionActivate = backend->session->events.changeActive.listen([this] {
-        if (backend->session->active) {
-            // session got activated, we need to restore
-            restoreAfterVT();
-        }
+        const auto SELF   = self.lock();
+        const auto PARENT = backend.lock();
+        if (!SELF || !PARENT)
+            std::terminate();
+
+        // Both loss and reacquisition of the DRM session are distinct
+        // incarnations. In particular, currentComplete must be invalid while
+        // inactive and until the restore scan commits on activation.
+        if (!validSessionResult(Aquamarine::NDRM::NTiledDRMIntegration::rotateSession(SELF)))
+            std::terminate();
+
+        if (PARENT->session->active)
+            SELF->restoreAfterVT();
     });
 }
 
@@ -371,10 +496,22 @@ std::vector<SP<CDRMBackend>> Aquamarine::CDRMBackend::attempt(SP<CBackend> backe
 }
 
 Aquamarine::CDRMBackend::~CDRMBackend() {
+    const auto DETACH = NDRM::NTiledDRMIntegration::beginDetach(self, eDetachReason::DESTRUCTOR_FALLBACK);
+    if (DETACH != eDetachResult::NOT_ATTACHED && !detachBegan(DETACH))
+        std::terminate();
+
+    listeners.sessionActivate.reset();
+    listeners.gpuChange.reset();
+    listeners.gpuRemove.reset();
+
     for (auto& conn : connectors) {
         conn->disconnect();
         conn.reset();
     }
+    connectors.clear();
+
+    if (detachBegan(DETACH) && NDRM::NTiledDRMIntegration::eraseDetached(self) != eDetachResult::DETACHED)
+        std::terminate();
 
     if (rendererState.allocator)
         rendererState.allocator->destroyBuffers();
@@ -392,6 +529,11 @@ bool Aquamarine::CDRMBackend::sessionActive() {
 }
 
 void Aquamarine::CDRMBackend::restoreAfterVT() {
+    const auto SELF   = self.lock();
+    const auto PARENT = backend.lock();
+    if (!SELF || !PARENT)
+        std::terminate();
+
     backend->log(AQ_LOG_DEBUG, "drm: Restoring after VT switch");
 
     // Clear stale page-flip bookkeeping for all connectors.
@@ -911,18 +1053,41 @@ bool Aquamarine::CDRMBackend::registerGPU(SP<CSessionDevice> gpu_, SP<CDRMBacken
     if (drmVer)
         drmFreeVersion(drmVer);
     listeners.gpuChange = gpu->events.change.listen([this](const CSessionDevice::SChangeEvent& E) {
+        const auto SELF   = self.lock();
+        const auto PARENT = backend.lock();
+        if (!SELF || !PARENT)
+            std::terminate();
+
         if (E.type == CSessionDevice::AQ_SESSION_EVENT_CHANGE_HOTPLUG) {
-            backend->log(AQ_LOG_DEBUG, std::format("drm: Got a hotplug event for {}", gpuName));
-            recheckOutputs();
+            PARENT->log(AQ_LOG_DEBUG, std::format("drm: Got a hotplug event for {}", SELF->gpuName));
+            SELF->recheckOutputs();
         } else if (E.type == CSessionDevice::AQ_SESSION_EVENT_CHANGE_LEASE) {
-            backend->log(AQ_LOG_DEBUG, std::format("drm: Got a lease event for {}", gpuName));
-            scanLeases();
+            PARENT->log(AQ_LOG_DEBUG, std::format("drm: Got a lease event for {}", SELF->gpuName));
+            SELF->scanLeases();
         }
     });
 
     listeners.gpuRemove = gpu->events.remove.listen([this] {
-        std::erase_if(backend->implementations, [this](const auto& impl) { return impl->drmFD() == this->drmFD(); });
-        backend->events.pollFDsChanged.emit();
+        const auto SELF   = self.lock();
+        const auto PARENT = backend.lock();
+        if (!SELF || !PARENT)
+            std::terminate();
+
+        const auto DETACH = NDRM::NTiledDRMIntegration::beginDetach(SELF, eDetachReason::GPU_REMOVED);
+        if (DETACH != eDetachResult::NOT_ATTACHED && !detachBegan(DETACH))
+            std::terminate();
+
+        SELF->listeners.sessionActivate.reset();
+        SELF->listeners.gpuChange.reset();
+        SELF->listeners.gpuRemove.reset();
+        for (auto& connector : SELF->connectors) {
+            connector->disconnect();
+            connector.reset();
+        }
+        SELF->connectors.clear();
+
+        std::erase_if(PARENT->implementations, [&SELF](const auto& implementation) { return dynamicPointerCast<CDRMBackend>(implementation) == SELF; });
+        PARENT->events.pollFDsChanged.emit();
     });
 
     return true;
@@ -933,10 +1098,8 @@ eBackendType Aquamarine::CDRMBackend::type() {
 }
 
 void Aquamarine::CDRMBackend::markRedundantTiles() {
-    for (const auto& conn : connectors) {
-        conn->parseTileInfo();
+    for (const auto& conn : connectors)
         conn->tilingRedundant = false;
-    }
 
     std::unordered_map<uint32_t, std::vector<SP<SDRMConnector>>> tileGroups;
     for (const auto& conn : connectors) {
@@ -949,9 +1112,11 @@ void Aquamarine::CDRMBackend::markRedundantTiles() {
         if (members.size() <= 1)
             continue;
 
-        const auto& ti         = members.at(0)->tileInfo;
-        int         fullWidth  = ti.numHTile * ti.tileHSize;
-        int         fullHeight = ti.numVTile * ti.tileVSize;
+        const auto& ti = members.at(0)->tileInfo;
+        if (ti.numHTile <= 0 || ti.numVTile <= 0 || ti.tileHSize <= 0 || ti.tileVSize <= 0)
+            continue;
+        const auto fullWidth  = static_cast<uint64_t>(ti.numHTile) * static_cast<uint64_t>(ti.tileHSize);
+        const auto fullHeight = static_cast<uint64_t>(ti.numVTile) * static_cast<uint64_t>(ti.tileVSize);
 
         backend->log(AQ_LOG_DEBUG, std::format("drm: Tile group {} has {} members, full tiled resolution {}x{}", groupId, members.size(), fullWidth, fullHeight));
 
@@ -980,7 +1145,15 @@ void Aquamarine::CDRMBackend::markRedundantTiles() {
 }
 
 void Aquamarine::CDRMBackend::recheckOutputs() {
+    const auto SELF   = self.lock();
+    const auto PARENT = backend.lock();
+    if (!SELF || !PARENT)
+        std::terminate();
+
     scanConnectors();
+    if (!lastLegacyScanComplete(SELF.impl_))
+        return;
+
     markRedundantTiles();
 
     // disconnect now to possibly free up crtcs
@@ -1029,70 +1202,242 @@ void Aquamarine::CDRMBackend::recheckOutputs() {
 void Aquamarine::CDRMBackend::scanConnectors() {
     backend->log(AQ_LOG_DEBUG, std::format("drm: Scanning connectors for {}", gpu->path));
 
-    auto resources = drmModeGetResources(gpu->fd);
-    if (!resources) {
-        backend->log(AQ_LOG_ERROR, std::format("drm: Scanning connectors for {} failed", gpu->path));
-        return;
-    }
+    const auto SELF = self.lock();
+    if (!SELF)
+        std::terminate();
 
-    for (int i = 0; i < resources->count_connectors; ++i) {
-        uint32_t          connectorID = resources->connectors[i];
+    setLastLegacyScan(SELF.impl_, false);
 
-        SP<SDRMConnector> conn;
-        auto              drmConn = drmModeGetConnector(gpu->fd, connectorID);
-
-        backend->log(AQ_LOG_DEBUG, std::format("drm: Scanning connector id {}", connectorID));
-
-        if (!drmConn) {
-            backend->log(AQ_LOG_ERROR, std::format("drm: Failed to get connector id {}", connectorID));
-            continue;
-        }
-
-        auto it = std::ranges::find_if(connectors, [connectorID](const auto& e) { return e->id == connectorID; });
-        if (it == connectors.end()) {
-            backend->log(AQ_LOG_DEBUG, std::format("drm: Initializing connector id {}", connectorID));
-            conn          = connectors.emplace_back(SP<SDRMConnector>(new SDRMConnector()));
-            conn->self    = conn;
-            conn->backend = self;
-            conn->id      = connectorID;
-            if (!conn->init(drmConn)) {
-                backend->log(AQ_LOG_ERROR, std::format("drm: Connector id {} failed initializing", connectorID));
-                connectors.pop_back();
-                drmModeFreeConnector(drmConn);
-                continue;
-            }
-        } else {
-            backend->log(AQ_LOG_DEBUG, std::format("drm: Connector id {} already initialized", connectorID));
-            conn = *it;
-        }
-
-        conn->status = drmConn->connection;
-
-        conn->maxMode = {};
-        for (int i = 0; i < drmConn->count_modes; ++i) {
-            conn->maxMode.x = std::max<double>(conn->maxMode.x, drmConn->modes[i].hdisplay);
-            conn->maxMode.y = std::max<double>(conn->maxMode.y, drmConn->modes[i].vdisplay);
-        }
-
-        if (conn->crtc)
-            conn->recheckCRTCProps();
-
-        backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} connection state: {}", connectorID, (int)drmConn->connection));
-
-        drmModeFreeConnector(drmConn);
-    }
-
-    // cleanup hot unplugged connectors
-    std::erase_if(connectors, [resources](auto& conn) {
-        for (int i = 0; i < resources->count_connectors; ++i) {
-            if (resources->connectors[i] == conn->id)
-                return false;
-        }
-        conn->disconnect();
-        return true;
+    auto        SCAN         = NDRM::NTiledDRMIntegration::beginConnectorScan(SELF);
+    bool        scanResolved = !SCAN.scan;
+    CScopeGuard scanGuard([&] {
+        if (!scanResolved && SCAN.scan)
+            NDRM::NTiledDRMIntegration::abortConnectorScan(SCAN.scan);
     });
 
-    drmModeFreeResources(resources);
+    // An existing entry with no ticket is either tearing down or violates the
+    // one-attempt invariant. Do not let a queued recheck mutate legacy state.
+    // A first-attach allocation failure has no entry and remains ordinary-only.
+    if (!SCAN.scan && NDRM::NTiledDRMIntegration::attached(SELF))
+        return;
+
+    std::vector<SConnectorView> incompleteViews;
+    const auto                  FINISH_INCOMPLETE = [&]() noexcept {
+        if (!SCAN.scan)
+            return;
+        const auto RESULT = NDRM::NTiledDRMIntegration::stageConnectorScan(SCAN.scan, eScanCompleteness::INCOMPLETE, std::move(incompleteViews));
+        if (RESULT != eScanStageResult::INCOMPLETE)
+            NDRM::NTiledDRMIntegration::abortConnectorScan(SCAN.scan);
+        scanResolved = true;
+    };
+
+    bool legacyInstallStarted = false;
+    try {
+        auto* const resources = drmModeGetResources(gpu->fd);
+        if (!resources) {
+            backend->log(AQ_LOG_ERROR, std::format("drm: Scanning connectors for {} failed", gpu->path));
+            FINISH_INCOMPLETE();
+            return;
+        }
+        CScopeGuard resourcesGuard([resources] { drmModeFreeResources(resources); });
+
+        const auto  FIRST_RESOURCES = copyResourcesSnapshot(resources);
+        if (!FIRST_RESOURCES) {
+            backend->log(AQ_LOG_ERROR, std::format("drm: Invalid connector resource snapshot for {}", gpu->path));
+            FINISH_INCOMPLETE();
+            return;
+        }
+
+        std::vector<SStagedDRMConnector> staged;
+        const auto                       TRANSACTION = NDRM::connectorScanTransaction<SStagedDRMConnector>(
+            FIRST_RESOURCES->connectors,
+            [&](uint32_t connectorId) -> std::optional<SStagedDRMConnector> {
+                backend->log(AQ_LOG_DEBUG, std::format("drm: Scanning connector id {}", connectorId));
+
+                auto* const drmConnector = drmModeGetConnector(gpu->fd, connectorId);
+                if (!drmConnector) {
+                    backend->log(AQ_LOG_ERROR, std::format("drm: Failed to get connector id {}", connectorId));
+                    return std::nullopt;
+                }
+                CScopeGuard connectorGuard([drmConnector] { drmModeFreeConnector(drmConnector); });
+
+                if (drmConnector->count_modes < 0 || (drmConnector->count_modes > 0 && !drmConnector->modes) || drmConnector->count_props < 0 ||
+                    (drmConnector->count_props > 0 && (!drmConnector->props || !drmConnector->prop_values))) {
+                    backend->log(AQ_LOG_ERROR, std::format("drm: Connector id {} returned an invalid snapshot", connectorId));
+                    return std::nullopt;
+                }
+
+                const auto EXISTING  = std::ranges::find(connectors, connectorId, &SDRMConnector::id);
+                auto       connector = EXISTING == connectors.end() ? SP<SDRMConnector>{new SDRMConnector{}} : *EXISTING;
+                const bool NEW       = EXISTING == connectors.end();
+                if (NEW) {
+                    backend->log(AQ_LOG_DEBUG, std::format("drm: Initializing connector id {}", connectorId));
+                    connector->self    = connector;
+                    connector->backend = self;
+                    connector->id      = connectorId;
+                    if (!connector->init(drmConnector)) {
+                        backend->log(AQ_LOG_ERROR, std::format("drm: Connector id {} failed initializing", connectorId));
+                        return std::nullopt;
+                    }
+                } else
+                    backend->log(AQ_LOG_DEBUG, std::format("drm: Connector id {} already initialized", connectorId));
+
+                bool nonDesktop = false;
+                if (connector->props.values.non_desktop) {
+                    const auto VALUE = rawConnectorProperty(drmConnector, connector->props.values.non_desktop);
+                    if (!VALUE) {
+                        backend->log(AQ_LOG_ERROR, std::format("drm: Connector id {} omitted its cached non-desktop property", connectorId));
+                        return std::nullopt;
+                    }
+                    nonDesktop = *VALUE != 0;
+                }
+
+                std::optional<std::string> tileProperty;
+                if (connector->props.values.tile) {
+                    const auto BLOB_ID = rawConnectorProperty(drmConnector, connector->props.values.tile);
+                    if (!BLOB_ID) {
+                        backend->log(AQ_LOG_ERROR, std::format("drm: Connector id {} omitted its cached TILE property", connectorId));
+                        return std::nullopt;
+                    }
+                    if (*BLOB_ID != 0) {
+                        auto* const BLOB = drmModeGetPropertyBlob(gpu->fd, *BLOB_ID);
+                        if (!BLOB) {
+                            backend->log(AQ_LOG_ERROR, std::format("drm: Connector id {} TILE blob {} could not be acquired", connectorId, *BLOB_ID));
+                            return std::nullopt;
+                        }
+                        CScopeGuard blobGuard([BLOB] { drmModeFreePropertyBlob(BLOB); });
+                        if (BLOB->length > 0 && !BLOB->data) {
+                            backend->log(AQ_LOG_ERROR, std::format("drm: Connector id {} TILE blob {} is invalid", connectorId, *BLOB_ID));
+                            return std::nullopt;
+                        }
+                        if (BLOB->length == 0)
+                            tileProperty.emplace();
+                        else
+                            tileProperty.emplace(static_cast<const char*>(BLOB->data), BLOB->length);
+                    }
+                }
+
+                std::vector<drmModeModeInfo> modes;
+                if (drmConnector->count_modes > 0)
+                    modes.assign(drmConnector->modes, drmConnector->modes + drmConnector->count_modes);
+
+                Vector2D maxMode;
+                for (const auto& MODE : modes) {
+                    maxMode.x = std::max<double>(maxMode.x, MODE.hdisplay);
+                    maxMode.y = std::max<double>(maxMode.y, MODE.vdisplay);
+                }
+
+                auto view = SConnectorView{
+                    .connectorId  = connectorId,
+                    .connected    = drmConnector->connection == DRM_MODE_CONNECTED,
+                    .isMonitor    = drmConnector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK,
+                    .nonDesktop   = nonDesktop,
+                    .tileProperty = std::move(tileProperty),
+                    .modes        = std::move(modes),
+                };
+                return SStagedDRMConnector{
+                    .connector        = std::move(connector),
+                    .status           = drmConnector->connection,
+                    .maxMode          = maxMode,
+                    .tileInfo         = legacyTileInfo(view.tileProperty),
+                    .view             = std::move(view),
+                    .newlyInitialized = NEW,
+                };
+            },
+            [&staged](std::span<SStagedDRMConnector> complete) {
+                staged.reserve(complete.size());
+                for (auto& connector : complete)
+                    staged.emplace_back(std::move(connector));
+            });
+
+        if (TRANSACTION != NDRM::eConnectorScanResult::COMMITTED) {
+            backend->log(AQ_LOG_ERROR, std::format("drm: Connector transaction for {} was incomplete", gpu->path));
+            FINISH_INCOMPLETE();
+            return;
+        }
+
+        auto* const verifyResources = drmModeGetResources(gpu->fd);
+        if (!verifyResources) {
+            backend->log(AQ_LOG_ERROR, std::format("drm: Could not verify connector resources for {}", gpu->path));
+            FINISH_INCOMPLETE();
+            return;
+        }
+        CScopeGuard verifyGuard([verifyResources] { drmModeFreeResources(verifyResources); });
+
+        const auto  SECOND_RESOURCES = copyResourcesSnapshot(verifyResources);
+        if (!SECOND_RESOURCES || *SECOND_RESOURCES != *FIRST_RESOURCES) {
+            backend->log(AQ_LOG_ERROR, std::format("drm: Connector resources for {} changed during acquisition", gpu->path));
+            FINISH_INCOMPLETE();
+            return;
+        }
+
+        std::vector<SP<SDRMConnector>> replacement;
+        std::vector<SP<SDRMConnector>> removed;
+        std::vector<SConnectorView>    views;
+        replacement.reserve(staged.size());
+        removed.reserve(connectors.size());
+        views.reserve(staged.size());
+
+        for (const auto& live : connectors) {
+            const auto STAGED = std::ranges::find(staged, live->id, [](const auto& connector) { return connector.view.connectorId; });
+            if (STAGED == staged.end())
+                removed.emplace_back(live);
+            else
+                replacement.emplace_back(live);
+        }
+        for (const auto& connector : staged) {
+            if (connector.newlyInitialized)
+                replacement.emplace_back(connector.connector);
+        }
+        for (auto& connector : staged)
+            views.emplace_back(std::move(connector.view));
+
+        bool shadowPrepared = false;
+        if (SCAN.scan) {
+            const auto STAGED = NDRM::NTiledDRMIntegration::stageConnectorScan(SCAN.scan, eScanCompleteness::COMPLETE, std::move(views));
+            shadowPrepared    = STAGED == eScanStageResult::PREPARED || STAGED == eScanStageResult::SHADOW_DISABLED;
+            if (!shadowPrepared) {
+                // Shadow preparation is deliberately non-authoritative in this
+                // phase. Resolve it and commit the fully staged legacy scan.
+                NDRM::NTiledDRMIntegration::abortConnectorScan(SCAN.scan);
+                scanResolved = true;
+            }
+        }
+
+        legacyInstallStarted = true;
+        for (const auto& connector : staged) {
+            connector.connector->status   = connector.status;
+            connector.connector->maxMode  = connector.maxMode;
+            connector.connector->tileInfo = connector.tileInfo;
+        }
+        connectors = std::move(replacement);
+
+        if (shadowPrepared) {
+            const auto COMMITTED = NDRM::NTiledDRMIntegration::commitConnectorScan(SCAN.scan);
+            if (COMMITTED != eScanCommitResult::COMMITTED && COMMITTED != eScanCommitResult::SHADOW_DISABLED)
+                NDRM::NTiledDRMIntegration::abortConnectorScan(SCAN.scan);
+            scanResolved = true;
+        }
+
+        // Removed connector owners survive the live-vector replacement and
+        // shadow install, so disconnect callbacks cannot re-enter a split view.
+        for (auto& connector : removed) {
+            connector->disconnect();
+            connector.reset();
+        }
+
+        for (const auto& connector : connectors) {
+            if (connector->crtc)
+                connector->recheckCRTCProps();
+            backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} connection state: {}", connector->id, static_cast<int>(connector->status)));
+        }
+
+        setLastLegacyScan(SELF.impl_, true);
+    } catch (...) {
+        if (legacyInstallStarted)
+            std::terminate();
+        FINISH_INCOMPLETE();
+    }
 }
 
 void Aquamarine::CDRMBackend::scanLeases() {
@@ -1142,7 +1487,14 @@ bool Aquamarine::CDRMBackend::start() {
 }
 
 std::vector<Hyprutils::Memory::CSharedPointer<SPollFD>> Aquamarine::CDRMBackend::pollFDs() {
-    return {makeShared<SPollFD>(gpu->fd, [this]() { dispatchEvents(); })};
+    const auto SELF   = self.lock();
+    const auto PARENT = backend.lock();
+    if (!SELF || !PARENT)
+        return {};
+    return {makeShared<SPollFD>(gpu->fd, [SELF, PARENT]() {
+        (void)PARENT;
+        SELF->dispatchEvents();
+    })};
 }
 
 int Aquamarine::CDRMBackend::drmFD() {
diff --git a/src/backend/drm/DRMIncarnations.hpp b/src/backend/drm/DRMIncarnations.hpp
index a9c79995bc9e1ae93a956c5903a4d9803b087061..ef18f4716144c64e30cc607e28a32d26b05b2e5b 100644
--- a/src/backend/drm/DRMIncarnations.hpp
+++ b/src/backend/drm/DRMIncarnations.hpp
@@ -14,6 +14,10 @@ namespace Aquamarine::NDRM::NTiledScan {
     class CScanFixtureAuthority;
 }
 
+namespace Aquamarine::NDRM::NTiledDRMIntegration {
+    class CTiledDRMIntegrationRegistry;
+}
+
 namespace Aquamarine::NDRM::NTiledIncarnations { // NOLINT(readability-identifier-naming): established Aquamarine DRM namespace
     using Hyprutils::Memory::CSharedPointer;
     using Hyprutils::Memory::CWeakPointer;
@@ -65,6 +69,7 @@ namespace Aquamarine::NDRM::NTiledIncarnations { // NOLINT(readability-identifie
 
         friend class ::Aquamarine::CDRMBackend;
         friend class ::Aquamarine::NDRM::NTiledScan::CScanFixtureAuthority;
+        friend class ::Aquamarine::NDRM::NTiledDRMIntegration::CTiledDRMIntegrationRegistry;
     };
 
     class CDeviceIncarnation final {
diff --git a/src/backend/drm/TiledDRMIntegration.cpp b/src/backend/drm/TiledDRMIntegration.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1cd308d302bce764244f9fc7463c6cabd736ca4c
--- /dev/null
+++ b/src/backend/drm/TiledDRMIntegration.cpp
@@ -0,0 +1,724 @@
+#include "TiledDRMIntegration.hpp"
+
+#include <algorithm>
+#include <atomic>
+#include <exception>
+#include <limits>
+#include <map>
+#include <mutex>
+#include <optional>
+#include <utility>
+
+using namespace Aquamarine;
+using namespace Aquamarine::NDRM::NTiledDRMIntegration;
+using namespace Aquamarine::NDRM::NTiledIncarnations;
+using namespace Aquamarine::NDRM::NTiledScan;
+
+namespace {
+    thread_local const void*                   LAST_SCAN_KEY      = nullptr;
+    thread_local bool                          LAST_SCAN_COMPLETE = false;
+
+    std::atomic<CTiledDRMIntegrationRegistry*> PRODUCTION_REGISTRY = nullptr;
+
+    void                                       setLastScan(const void* key, bool complete) noexcept {
+        LAST_SCAN_KEY      = key;
+        LAST_SCAN_COMPLETE = complete;
+    }
+
+    CTiledDRMIntegrationRegistry* productionRegistryIfCreated() noexcept {
+        return PRODUCTION_REGISTRY.load(std::memory_order_acquire);
+    }
+
+    CTiledDRMIntegrationRegistry* createProductionRegistry() {
+        if (auto* const EXISTING = productionRegistryIfCreated())
+            return EXISTING;
+
+        // Deliberately process-lifetime: CDRMBackend's exact destructor
+        // fallback owns fail-fast teardown. A destructing function-local
+        // registry would race static shutdown order with external backend
+        // aliases and their poll sources.
+        auto* candidate = new CTiledDRMIntegrationRegistry{};
+        auto* expected  = static_cast<CTiledDRMIntegrationRegistry*>(nullptr);
+        if (PRODUCTION_REGISTRY.compare_exchange_strong(expected, candidate, std::memory_order_release, std::memory_order_acquire))
+            return candidate;
+
+        delete candidate;
+        return expected;
+    }
+
+    eScanBeginResult beginFailure(eBeginAttemptResult result) noexcept {
+        switch (result) {
+            case eBeginAttemptResult::WRONG_THREAD: return eScanBeginResult::WRONG_THREAD;
+            case eBeginAttemptResult::BUSY: return eScanBeginResult::BUSY;
+            case eBeginAttemptResult::SERIAL_EXHAUSTED:
+            case eBeginAttemptResult::RESOURCE_EPOCH_EXHAUSTED: return eScanBeginResult::EXHAUSTED;
+            default: return eScanBeginResult::INVALID_STATE;
+        }
+    }
+}
+
+class CTiledDRMIntegrationRegistry::CImpl {
+  public:
+    struct SEntry {
+        PBackendLifetime    lifetime;
+        PDeviceIncarnation  device;
+        PSessionIncarnation session;
+        uint64_t            resourceEpoch = 0;
+        bool                detachBegun   = false;
+        eDetachReason       detachReason  = eDetachReason::BACKEND_SHUTDOWN;
+    };
+
+    explicit CImpl(std::thread::id thread) : eventThread(thread), scanRegistry(thread) {}
+
+    [[nodiscard]] std::optional<std::thread::id> registeredThread(const void* key) const {
+        if (!key)
+            return std::nullopt;
+        std::scoped_lock lock(indexMutex);
+        const auto       iterator = threadIndex.find(key);
+        if (iterator == threadIndex.end())
+            return std::nullopt;
+        return iterator->second;
+    }
+
+    [[nodiscard]] bool registerThread(const void* key) {
+        std::scoped_lock lock(indexMutex);
+        return threadIndex.emplace(key, eventThread).second;
+    }
+
+    void unregisterThread(const void* key) noexcept {
+        std::scoped_lock lock(indexMutex);
+        threadIndex.erase(key);
+    }
+
+    [[nodiscard]] bool onEventThread() const noexcept {
+        return std::this_thread::get_id() == eventThread;
+    }
+
+    std::thread::id                        eventThread;
+    CTiledBackendStateRegistry             scanRegistry;
+    std::map<const void*, SEntry>          entries;
+    mutable std::mutex                     indexMutex;
+    std::map<const void*, std::thread::id> threadIndex;
+    uint64_t                               nextIdentity       = 1;
+    bool                                   failNextAttachment = false;
+};
+
+CConnectorScan::CConnectorScan(CTiledDRMIntegrationRegistry* registry, const void* key, PBackendLifetime lifetime, PScanAttemptTicket ticket, std::thread::id eventThread,
+                               bool shadowEnabled) :
+    m_registry(registry), m_key(key), m_lifetime(std::move(lifetime)), m_ticket(std::move(ticket)), m_eventThread(eventThread), m_shadowEnabled(shadowEnabled) {}
+
+CConnectorScan::~CConnectorScan() noexcept {
+    if (!m_active)
+        return;
+    if (!m_shadowEnabled) {
+        setLastScan(m_key, false);
+        m_active = false;
+        return;
+    }
+    if (!m_registry)
+        std::terminate();
+    m_registry->abortConnectorScan(*this);
+}
+
+bool CConnectorScan::shadowEnabled() const {
+    return m_shadowEnabled;
+}
+
+SBeginConnectorScanResult::operator bool() const {
+    return static_cast<bool>(scan);
+}
+
+CTiledDRMIntegrationRegistry::CTiledDRMIntegrationRegistry(std::thread::id eventThread) : m_impl(Hyprutils::Memory::makeUnique<CImpl>(eventThread)) {}
+
+CTiledDRMIntegrationRegistry::~CTiledDRMIntegrationRegistry() noexcept {
+    if (!readyForDestruction())
+        std::terminate();
+}
+
+SBeginConnectorScanResult CTiledDRMIntegrationRegistry::beginAttached(const void* key) {
+    if (!key)
+        return {.result = eScanBeginResult::INVALID_STATE};
+    if (!m_impl->onEventThread())
+        return {.result = eScanBeginResult::WRONG_THREAD};
+
+    const auto ENTRY = m_impl->entries.find(key);
+    if (ENTRY == m_impl->entries.end() || ENTRY->second.detachBegun)
+        return {.result = eScanBeginResult::INVALID_STATE};
+    if (ENTRY->second.resourceEpoch == std::numeric_limits<uint64_t>::max())
+        return {.result = eScanBeginResult::EXHAUSTED};
+
+    auto* const STATE = m_impl->scanRegistry.find(ENTRY->second.lifetime);
+    if (!STATE)
+        return {.result = eScanBeginResult::INVALID_STATE};
+
+    const auto SHADOW_DISABLED = [this, key]() -> SBeginConnectorScanResult {
+        try {
+            return {
+                .scan   = PConnectorScan{new CConnectorScan{nullptr, key, {}, {}, m_impl->eventThread, false}},
+                .result = eScanBeginResult::SHADOW_DISABLED,
+            };
+        } catch (...) { return {.result = eScanBeginResult::INVALID_STATE}; }
+    };
+
+    ++ENTRY->second.resourceEpoch;
+    auto STARTED = STATE->beginAttempt(ENTRY->second.resourceEpoch);
+    if (!STARTED) {
+        if (STARTED.result == eBeginAttemptResult::PREPARATION_FAILED)
+            return SHADOW_DISABLED();
+        return {.result = beginFailure(STARTED.result)};
+    }
+
+    const auto TICKET = STARTED.ticket;
+    try {
+        return {
+            .scan   = PConnectorScan{new CConnectorScan{this, key, ENTRY->second.lifetime, std::move(STARTED.ticket), m_impl->eventThread, true}},
+            .result = eScanBeginResult::STARTED,
+        };
+    } catch (...) {
+        const auto RESOLVED = STATE->fail(TICKET, eAttemptFailure::PREPARATION_FAILED);
+        if (RESOLVED != eResolveAttemptResult::RESOLVED)
+            std::terminate();
+        return SHADOW_DISABLED();
+    }
+}
+
+SBeginConnectorScanResult CTiledDRMIntegrationRegistry::beginConnectorScan(const CSharedPointer<CDRMBackend>& backend) {
+    const auto* const KEY = backend.impl_;
+    if (!KEY)
+        return {.result = eScanBeginResult::INVALID_STATE};
+
+    setLastScan(KEY, false);
+
+    // This raw-key/thread-index gate must precede weak-owner construction,
+    // locking, comparison, or any other Hypr owner operation.
+    if (!m_impl->onEventThread()) {
+        if (m_impl->registeredThread(KEY))
+            return {.result = eScanBeginResult::WRONG_THREAD};
+        try {
+            return {
+                .scan   = PConnectorScan{new CConnectorScan{nullptr, KEY, {}, {}, std::this_thread::get_id(), false}},
+                .result = eScanBeginResult::SHADOW_DISABLED,
+            };
+        } catch (...) { return {.result = eScanBeginResult::INVALID_STATE}; }
+    }
+
+    auto ENTRY = m_impl->entries.find(KEY);
+    if (ENTRY != m_impl->entries.end()) {
+        if (!ENTRY->second.lifetime || ENTRY->second.lifetime->binding() != eBackendBinding::PRODUCTION_BACKEND || ENTRY->second.lifetime->drmBackend().impl_ != KEY)
+            return {.result = eScanBeginResult::INVALID_STATE};
+        return beginAttached(KEY);
+    }
+
+    auto shadowDisabled = [this, KEY]() -> SBeginConnectorScanResult {
+        try {
+            return {
+                .scan   = PConnectorScan{new CConnectorScan{nullptr, KEY, {}, {}, m_impl->eventThread, false}},
+                .result = eScanBeginResult::SHADOW_DISABLED,
+            };
+        } catch (...) { return {.result = eScanBeginResult::INVALID_STATE}; }
+    };
+
+    if (m_impl->failNextAttachment) {
+        m_impl->failNextAttachment = false;
+        return shadowDisabled();
+    }
+    if (m_impl->nextIdentity == 0 || m_impl->nextIdentity == std::numeric_limits<uint64_t>::max())
+        return shadowDisabled();
+
+    const auto IDENTITY = m_impl->nextIdentity++;
+    auto       lifetime = CBackendLifetime::createProduction(IDENTITY, backend);
+    auto       device   = CDeviceIncarnation::create(lifetime, IDENTITY, IDENTITY, IDENTITY, IDENTITY);
+    auto       session  = CSessionIncarnation::create(lifetime, device, m_impl->eventThread, IDENTITY, IDENTITY, IDENTITY);
+    if (!lifetime || !device || !session)
+        return shadowDisabled();
+
+    const auto CREATED = m_impl->scanRegistry.create(lifetime, device, session);
+    if (!CREATED)
+        return shadowDisabled();
+
+    auto discardState = [this, &lifetime]() noexcept {
+        if (m_impl->scanRegistry.beginTeardown(lifetime) != eRegistryResult::OK || m_impl->scanRegistry.erase(lifetime) != eRegistryResult::OK)
+            std::terminate();
+    };
+
+    bool inserted = false;
+    try {
+        const auto [ITERATOR, INSERTED] = m_impl->entries.emplace(KEY,
+                                                                  CImpl::SEntry{
+                                                                      .lifetime = lifetime,
+                                                                      .device   = device,
+                                                                      .session  = session,
+                                                                  });
+        inserted                        = INSERTED;
+        if (!INSERTED) {
+            discardState();
+            return {.result = eScanBeginResult::INVALID_STATE};
+        }
+        if (!m_impl->registerThread(KEY)) {
+            discardState();
+            m_impl->entries.erase(ITERATOR);
+            return {.result = eScanBeginResult::INVALID_STATE};
+        }
+    } catch (...) {
+        discardState();
+        if (inserted)
+            m_impl->entries.erase(KEY);
+        return shadowDisabled();
+    }
+
+    return beginAttached(KEY);
+}
+
+SBeginConnectorScanResult CTiledDRMIntegrationRegistry::beginTestConnectorScan(const PBackendLifetime& lifetime) {
+    const auto* const KEY = lifetime.impl_;
+    if (!KEY)
+        return {.result = eScanBeginResult::INVALID_STATE};
+
+    setLastScan(KEY, false);
+    if (!m_impl->onEventThread()) {
+        if (m_impl->registeredThread(KEY))
+            return {.result = eScanBeginResult::WRONG_THREAD};
+        try {
+            return {
+                .scan   = PConnectorScan{new CConnectorScan{nullptr, KEY, {}, {}, std::this_thread::get_id(), false}},
+                .result = eScanBeginResult::SHADOW_DISABLED,
+            };
+        } catch (...) { return {.result = eScanBeginResult::INVALID_STATE}; }
+    }
+
+    if (!lifetime || !lifetime->valid() || lifetime->binding() != eBackendBinding::TEST_TOKEN)
+        return {.result = eScanBeginResult::INVALID_STATE};
+
+    auto ENTRY = m_impl->entries.find(KEY);
+    if (ENTRY != m_impl->entries.end()) {
+        if (ENTRY->second.lifetime != lifetime)
+            return {.result = eScanBeginResult::INVALID_STATE};
+        return beginAttached(KEY);
+    }
+
+    auto shadowDisabled = [this, KEY]() -> SBeginConnectorScanResult {
+        try {
+            return {
+                .scan   = PConnectorScan{new CConnectorScan{nullptr, KEY, {}, {}, m_impl->eventThread, false}},
+                .result = eScanBeginResult::SHADOW_DISABLED,
+            };
+        } catch (...) { return {.result = eScanBeginResult::INVALID_STATE}; }
+    };
+
+    if (m_impl->failNextAttachment) {
+        m_impl->failNextAttachment = false;
+        return shadowDisabled();
+    }
+    if (m_impl->nextIdentity == 0 || m_impl->nextIdentity == std::numeric_limits<uint64_t>::max())
+        return shadowDisabled();
+
+    const auto IDENTITY = m_impl->nextIdentity++;
+    auto       device   = CDeviceIncarnation::create(lifetime, IDENTITY, IDENTITY, IDENTITY, IDENTITY);
+    auto       session  = CSessionIncarnation::create(lifetime, device, m_impl->eventThread, IDENTITY, IDENTITY, IDENTITY);
+    if (!device || !session)
+        return shadowDisabled();
+
+    const auto CREATED = m_impl->scanRegistry.create(lifetime, device, session);
+    if (!CREATED)
+        return shadowDisabled();
+
+    auto discardState = [this, &lifetime]() noexcept {
+        if (m_impl->scanRegistry.beginTeardown(lifetime) != eRegistryResult::OK || m_impl->scanRegistry.erase(lifetime) != eRegistryResult::OK)
+            std::terminate();
+    };
+
+    bool inserted = false;
+    try {
+        const auto [ITERATOR, INSERTED] = m_impl->entries.emplace(KEY,
+                                                                  CImpl::SEntry{
+                                                                      .lifetime = lifetime,
+                                                                      .device   = device,
+                                                                      .session  = session,
+                                                                  });
+        inserted                        = INSERTED;
+        if (!INSERTED) {
+            discardState();
+            return {.result = eScanBeginResult::INVALID_STATE};
+        }
+        if (!m_impl->registerThread(KEY)) {
+            discardState();
+            m_impl->entries.erase(ITERATOR);
+            return {.result = eScanBeginResult::INVALID_STATE};
+        }
+    } catch (...) {
+        discardState();
+        if (inserted)
+            m_impl->entries.erase(KEY);
+        return shadowDisabled();
+    }
+
+    return beginAttached(KEY);
+}
+
+eScanStageResult CTiledDRMIntegrationRegistry::stageConnectorScan(const PConnectorScan& scan, eScanCompleteness completeness, std::vector<SConnectorView> connectors) noexcept {
+    if (!scan)
+        return eScanStageResult::STALE;
+    if (scan->m_eventThread != std::this_thread::get_id())
+        return eScanStageResult::WRONG_THREAD;
+    if (!scan->m_active || scan->m_staged)
+        return eScanStageResult::STALE;
+
+    setLastScan(scan->m_key, false);
+    if (!scan->m_shadowEnabled) {
+        scan->m_staged = true;
+        if (completeness == eScanCompleteness::INCOMPLETE) {
+            scan->m_active = false;
+            return eScanStageResult::INCOMPLETE;
+        }
+        return eScanStageResult::SHADOW_DISABLED;
+    }
+
+    if (scan->m_registry != this)
+        return eScanStageResult::STALE;
+
+    if (!m_impl->onEventThread())
+        return eScanStageResult::WRONG_THREAD;
+
+    const auto ENTRY = m_impl->entries.find(scan->m_key);
+    if (ENTRY == m_impl->entries.end() || ENTRY->second.detachBegun || ENTRY->second.lifetime != scan->m_lifetime)
+        return eScanStageResult::STALE;
+    auto* const STATE = m_impl->scanRegistry.find(ENTRY->second.lifetime);
+    if (!STATE)
+        return eScanStageResult::STALE;
+
+    const auto PREPARED = STATE->prepare(scan->m_ticket, completeness, std::move(connectors));
+    switch (PREPARED.result) {
+        case ePrepareScanResult::PREPARED:
+            if (!PREPARED.prepared)
+                return eScanStageResult::FAILED;
+            scan->m_prepared = PREPARED.prepared;
+            scan->m_staged   = true;
+            return eScanStageResult::PREPARED;
+        case ePrepareScanResult::INCOMPLETE:
+            scan->m_staged = true;
+            scan->m_active = false;
+            return eScanStageResult::INCOMPLETE;
+        case ePrepareScanResult::WRONG_THREAD: return eScanStageResult::WRONG_THREAD;
+        case ePrepareScanResult::STALE_TICKET: scan->m_active = false; return eScanStageResult::STALE;
+        case ePrepareScanResult::BACKEND_EXPIRED:
+        case ePrepareScanResult::PREPARATION_FAILED: scan->m_active = false; return eScanStageResult::FAILED;
+        case ePrepareScanResult::FOREIGN_TICKET: return eScanStageResult::STALE;
+        case ePrepareScanResult::TEARING_DOWN:
+        case ePrepareScanResult::BUSY: return eScanStageResult::FAILED;
+    }
+
+    return eScanStageResult::FAILED;
+}
+
+eScanCommitResult CTiledDRMIntegrationRegistry::commitConnectorScan(const PConnectorScan& scan) noexcept {
+    if (!scan)
+        return eScanCommitResult::STALE;
+    if (scan->m_eventThread != std::this_thread::get_id())
+        return eScanCommitResult::WRONG_THREAD;
+    if (!scan->m_active || !scan->m_staged)
+        return eScanCommitResult::STALE;
+
+    if (!scan->m_shadowEnabled) {
+        scan->m_active = false;
+        setLastScan(scan->m_key, true);
+        return eScanCommitResult::SHADOW_DISABLED;
+    }
+
+    if (scan->m_registry != this)
+        return eScanCommitResult::STALE;
+
+    if (!m_impl->onEventThread())
+        return eScanCommitResult::WRONG_THREAD;
+
+    const auto ENTRY = m_impl->entries.find(scan->m_key);
+    if (ENTRY == m_impl->entries.end() || ENTRY->second.detachBegun || ENTRY->second.lifetime != scan->m_lifetime)
+        return eScanCommitResult::STALE;
+    auto* const STATE = m_impl->scanRegistry.find(ENTRY->second.lifetime);
+    if (!STATE)
+        return eScanCommitResult::STALE;
+
+    const auto RESULT = STATE->install(scan->m_prepared, eValidationDecision::ACCEPTED);
+    if (RESULT == eScanInstallResult::COMMITTED) {
+        scan->m_active = false;
+        setLastScan(scan->m_key, true);
+        return eScanCommitResult::COMMITTED;
+    }
+
+    setLastScan(scan->m_key, false);
+    switch (RESULT) {
+        case eScanInstallResult::WRONG_THREAD: return eScanCommitResult::WRONG_THREAD;
+        case eScanInstallResult::STALE_PREPARED:
+        case eScanInstallResult::BACKEND_EXPIRED:
+        case eScanInstallResult::BASE_CHANGED: scan->m_active = false; return eScanCommitResult::STALE;
+        default: return eScanCommitResult::FAILED;
+    }
+}
+
+void CTiledDRMIntegrationRegistry::abortConnectorScan(const PConnectorScan& scan) noexcept {
+    if (!scan)
+        return;
+    if (!scan->m_shadowEnabled) {
+        if (scan->m_eventThread != std::this_thread::get_id())
+            std::terminate();
+        setLastScan(scan->m_key, false);
+        scan->m_active = false;
+        return;
+    }
+    if (scan->m_registry != this)
+        return;
+    abortConnectorScan(*scan);
+}
+
+void CTiledDRMIntegrationRegistry::abortConnectorScan(CConnectorScan& scan) noexcept {
+    if (!scan.m_active)
+        return;
+    if (scan.m_registry != this || scan.m_eventThread != std::this_thread::get_id())
+        std::terminate();
+
+    setLastScan(scan.m_key, false);
+    if (!scan.m_shadowEnabled) {
+        scan.m_active = false;
+        return;
+    }
+
+    if (!m_impl->onEventThread())
+        std::terminate();
+
+    const auto ENTRY = m_impl->entries.find(scan.m_key);
+    if (ENTRY == m_impl->entries.end() || ENTRY->second.detachBegun || ENTRY->second.lifetime != scan.m_lifetime)
+        std::terminate();
+    auto* const STATE = m_impl->scanRegistry.find(ENTRY->second.lifetime);
+    if (!STATE)
+        std::terminate();
+    const auto RESULT = STATE->fail(scan.m_ticket, eAttemptFailure::ACQUISITION_FAILED);
+    if (RESULT != eResolveAttemptResult::RESOLVED && RESULT != eResolveAttemptResult::STALE_TICKET)
+        std::terminate();
+    scan.m_active = false;
+}
+
+eSessionResult CTiledDRMIntegrationRegistry::rotateSessionKey(const void* key) noexcept {
+    const auto THREAD = m_impl->registeredThread(key);
+    if (!THREAD)
+        return eSessionResult::NOT_ATTACHED;
+    if (*THREAD != std::this_thread::get_id())
+        return eSessionResult::WRONG_THREAD;
+
+    const auto ENTRY = m_impl->entries.find(key);
+    if (ENTRY == m_impl->entries.end() || ENTRY->second.detachBegun)
+        return eSessionResult::INVALID_STATE;
+    auto* const STATE = m_impl->scanRegistry.find(ENTRY->second.lifetime);
+    if (!STATE)
+        return eSessionResult::INVALID_STATE;
+
+    const auto OUTCOME = STATE->outcome();
+    const auto SERIAL  = std::max(OUTCOME.serial, ENTRY->second.session->serial());
+    if (SERIAL == std::numeric_limits<uint64_t>::max() || ENTRY->second.session->sessionEpoch() == std::numeric_limits<uint64_t>::max() ||
+        ENTRY->second.session->eventThreadEpoch() == std::numeric_limits<uint64_t>::max())
+        return eSessionResult::EXHAUSTED;
+
+    auto session = CSessionIncarnation::create(ENTRY->second.lifetime, ENTRY->second.device, m_impl->eventThread, ENTRY->second.session->sessionEpoch() + 1,
+                                               ENTRY->second.session->eventThreadEpoch() + 1, SERIAL + 1);
+    if (!session)
+        return eSessionResult::INVALID_STATE;
+    const auto RESULT = STATE->rotateSession(session);
+    if (RESULT == eSessionRotationResult::BUSY)
+        return eSessionResult::BUSY;
+    if (RESULT != eSessionRotationResult::ROTATED)
+        return RESULT == eSessionRotationResult::WRONG_THREAD ? eSessionResult::WRONG_THREAD : eSessionResult::INVALID_STATE;
+
+    ENTRY->second.session = std::move(session);
+    setLastScan(key, false);
+    return eSessionResult::ROTATED;
+}
+
+eSessionResult CTiledDRMIntegrationRegistry::rotateSession(const CWeakPointer<CDRMBackend>& backend) noexcept {
+    return rotateSessionKey(backend.impl_);
+}
+
+eSessionResult CTiledDRMIntegrationRegistry::rotateTestSession(const PBackendLifetime& lifetime) noexcept {
+    return rotateSessionKey(lifetime.impl_);
+}
+
+eDetachResult CTiledDRMIntegrationRegistry::beginDetachKey(const void* key, eDetachReason reason) noexcept {
+    setLastScan(key, false);
+    const auto THREAD = m_impl->registeredThread(key);
+    if (!THREAD)
+        return eDetachResult::NOT_ATTACHED;
+    if (*THREAD != std::this_thread::get_id())
+        return eDetachResult::WRONG_THREAD;
+
+    const auto ENTRY = m_impl->entries.find(key);
+    if (ENTRY == m_impl->entries.end())
+        return eDetachResult::INVALID_STATE;
+    if (ENTRY->second.detachBegun)
+        return eDetachResult::ALREADY_BEGUN;
+
+    const auto RESULT = m_impl->scanRegistry.beginTeardown(ENTRY->second.lifetime);
+    if (RESULT == eRegistryResult::BUSY)
+        return eDetachResult::BUSY;
+    if (RESULT != eRegistryResult::OK)
+        return RESULT == eRegistryResult::WRONG_THREAD ? eDetachResult::WRONG_THREAD : eDetachResult::INVALID_STATE;
+
+    ENTRY->second.detachBegun  = true;
+    ENTRY->second.detachReason = reason;
+    setLastScan(key, false);
+    return eDetachResult::BEGUN;
+}
+
+eDetachResult CTiledDRMIntegrationRegistry::beginDetach(const CWeakPointer<CDRMBackend>& backend, eDetachReason reason) noexcept {
+    return beginDetachKey(backend.impl_, reason);
+}
+
+eDetachResult CTiledDRMIntegrationRegistry::beginTestDetach(const PBackendLifetime& lifetime, eDetachReason reason) noexcept {
+    return beginDetachKey(lifetime.impl_, reason);
+}
+
+eDetachResult CTiledDRMIntegrationRegistry::eraseDetachedKey(const void* key) noexcept {
+    const auto THREAD = m_impl->registeredThread(key);
+    if (!THREAD)
+        return eDetachResult::NOT_ATTACHED;
+    if (*THREAD != std::this_thread::get_id())
+        return eDetachResult::WRONG_THREAD;
+
+    const auto ENTRY = m_impl->entries.find(key);
+    if (ENTRY == m_impl->entries.end() || !ENTRY->second.detachBegun)
+        return eDetachResult::INVALID_STATE;
+    if (m_impl->scanRegistry.erase(ENTRY->second.lifetime) != eRegistryResult::OK)
+        return eDetachResult::INVALID_STATE;
+
+    m_impl->entries.erase(ENTRY);
+    m_impl->unregisterThread(key);
+    setLastScan(key, false);
+    return eDetachResult::DETACHED;
+}
+
+eDetachResult CTiledDRMIntegrationRegistry::eraseDetached(const CWeakPointer<CDRMBackend>& backend) noexcept {
+    return eraseDetachedKey(backend.impl_);
+}
+
+eDetachResult CTiledDRMIntegrationRegistry::eraseTestDetached(const PBackendLifetime& lifetime) noexcept {
+    return eraseDetachedKey(lifetime.impl_);
+}
+
+bool CTiledDRMIntegrationRegistry::attachedKey(const void* key) const noexcept {
+    return m_impl->registeredThread(key).has_value();
+}
+
+bool CTiledDRMIntegrationRegistry::attached(const CWeakPointer<CDRMBackend>& backend) const noexcept {
+    return attachedKey(backend.impl_);
+}
+
+bool CTiledDRMIntegrationRegistry::testAttached(const PBackendLifetime& lifetime) const noexcept {
+    return attachedKey(lifetime.impl_);
+}
+
+bool CTiledDRMIntegrationRegistry::lastConnectorScanComplete(const CWeakPointer<CDRMBackend>& backend) const noexcept {
+    return LAST_SCAN_KEY == backend.impl_ && LAST_SCAN_COMPLETE;
+}
+
+bool CTiledDRMIntegrationRegistry::testLastConnectorScanComplete(const PBackendLifetime& lifetime) const noexcept {
+    return LAST_SCAN_KEY == lifetime.impl_ && LAST_SCAN_COMPLETE;
+}
+
+PCommittedScan CTiledDRMIntegrationRegistry::currentCompleteKey(const void* key) noexcept {
+    const auto THREAD = m_impl->registeredThread(key);
+    if (!THREAD || *THREAD != std::this_thread::get_id())
+        return {};
+    const auto ENTRY = m_impl->entries.find(key);
+    if (ENTRY == m_impl->entries.end())
+        return {};
+    auto* const STATE = m_impl->scanRegistry.find(ENTRY->second.lifetime);
+    return STATE ? STATE->currentComplete() : PCommittedScan{};
+}
+
+PCommittedScan CTiledDRMIntegrationRegistry::currentComplete(const CWeakPointer<CDRMBackend>& backend) noexcept {
+    return currentCompleteKey(backend.impl_);
+}
+
+PCommittedScan CTiledDRMIntegrationRegistry::testCurrentComplete(const PBackendLifetime& lifetime) noexcept {
+    return currentCompleteKey(lifetime.impl_);
+}
+
+SScanOutcome CTiledDRMIntegrationRegistry::outcomeKey(const void* key) noexcept {
+    const auto THREAD = m_impl->registeredThread(key);
+    if (!THREAD || *THREAD != std::this_thread::get_id())
+        return {};
+    const auto ENTRY = m_impl->entries.find(key);
+    if (ENTRY == m_impl->entries.end())
+        return {};
+    auto* const STATE = m_impl->scanRegistry.find(ENTRY->second.lifetime);
+    return STATE ? STATE->outcome() : SScanOutcome{};
+}
+
+SScanOutcome CTiledDRMIntegrationRegistry::outcome(const CWeakPointer<CDRMBackend>& backend) noexcept {
+    return outcomeKey(backend.impl_);
+}
+
+SScanOutcome CTiledDRMIntegrationRegistry::testOutcome(const PBackendLifetime& lifetime) noexcept {
+    return outcomeKey(lifetime.impl_);
+}
+
+bool CTiledDRMIntegrationRegistry::readyForDestruction() const noexcept {
+    return m_impl->entries.empty() && m_impl->scanRegistry.readyForDestruction();
+}
+
+void CTiledDRMIntegrationRegistry::failNextAttachmentForTest() noexcept {
+    if (!m_impl->onEventThread())
+        std::terminate();
+    m_impl->failNextAttachment = true;
+}
+
+SBeginConnectorScanResult Aquamarine::NDRM::NTiledDRMIntegration::beginConnectorScan(const CSharedPointer<CDRMBackend>& backend) {
+    if (!backend.impl_)
+        return {.result = eScanBeginResult::INVALID_STATE};
+    try {
+        return createProductionRegistry()->beginConnectorScan(backend);
+    } catch (...) { return {.result = eScanBeginResult::INVALID_STATE}; }
+}
+
+eScanStageResult Aquamarine::NDRM::NTiledDRMIntegration::stageConnectorScan(const PConnectorScan& scan, eScanCompleteness completeness,
+                                                                            std::vector<SConnectorView> connectors) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY ? REGISTRY->stageConnectorScan(scan, completeness, std::move(connectors)) : eScanStageResult::STALE;
+}
+
+eScanCommitResult Aquamarine::NDRM::NTiledDRMIntegration::commitConnectorScan(const PConnectorScan& scan) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY ? REGISTRY->commitConnectorScan(scan) : eScanCommitResult::STALE;
+}
+
+void Aquamarine::NDRM::NTiledDRMIntegration::abortConnectorScan(const PConnectorScan& scan) noexcept {
+    if (auto* const REGISTRY = productionRegistryIfCreated())
+        REGISTRY->abortConnectorScan(scan);
+}
+
+eSessionResult Aquamarine::NDRM::NTiledDRMIntegration::rotateSession(const CWeakPointer<CDRMBackend>& backend) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY ? REGISTRY->rotateSession(backend) : eSessionResult::NOT_ATTACHED;
+}
+
+eDetachResult Aquamarine::NDRM::NTiledDRMIntegration::beginDetach(const CWeakPointer<CDRMBackend>& backend, eDetachReason reason) noexcept {
+    setLastScan(backend.impl_, false);
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY ? REGISTRY->beginDetach(backend, reason) : eDetachResult::NOT_ATTACHED;
+}
+
+eDetachResult Aquamarine::NDRM::NTiledDRMIntegration::eraseDetached(const CWeakPointer<CDRMBackend>& backend) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY ? REGISTRY->eraseDetached(backend) : eDetachResult::NOT_ATTACHED;
+}
+
+bool Aquamarine::NDRM::NTiledDRMIntegration::attached(const CWeakPointer<CDRMBackend>& backend) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY && REGISTRY->attached(backend);
+}
+
+bool Aquamarine::NDRM::NTiledDRMIntegration::lastConnectorScanComplete(const CWeakPointer<CDRMBackend>& backend) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY && REGISTRY->lastConnectorScanComplete(backend);
+}
+
+PCommittedScan Aquamarine::NDRM::NTiledDRMIntegration::currentComplete(const CWeakPointer<CDRMBackend>& backend) noexcept {
+    auto* const REGISTRY = productionRegistryIfCreated();
+    return REGISTRY ? REGISTRY->currentComplete(backend) : PCommittedScan{};
+}
diff --git a/src/backend/drm/TiledDRMIntegration.hpp b/src/backend/drm/TiledDRMIntegration.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..20b22b0ee3bcea388b26c533bfca38fcf076d7df
--- /dev/null
+++ b/src/backend/drm/TiledDRMIntegration.hpp
@@ -0,0 +1,197 @@
+#pragma once
+
+#include "TiledBackendState.hpp"
+
+#include <aquamarine/backend/DRM.hpp>
+
+#include <cstdint>
+#include <thread>
+#include <vector>
+
+#include <hyprutils/memory/UniquePtr.hpp>
+
+#ifdef __GNUC__
+#define AQ_TILED_DRM_PRIVATE __attribute__((visibility("hidden")))
+#else
+#define AQ_TILED_DRM_PRIVATE
+#endif
+
+namespace Aquamarine::NDRM::NTiledDRMIntegrationTest {
+    class CFixtureAuthority;
+}
+
+namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identifier-naming): established Aquamarine DRM namespace
+    using Hyprutils::Memory::CSharedPointer;
+    using Hyprutils::Memory::CWeakPointer;
+    using NTiledIncarnations::PBackendLifetime;
+    using NTiledScan::PCommittedScan;
+    using NTiledScan::PPreparedScan;
+    using NTiledScan::PScanAttemptTicket;
+    using NTiledScan::SConnectorView;
+    using NTiledScan::SScanOutcome;
+    using NTiledScan::eScanCompleteness;
+
+    enum class eScanBeginResult : uint8_t {
+        STARTED = 0,
+        SHADOW_DISABLED,
+        WRONG_THREAD,
+        BUSY,
+        EXHAUSTED,
+        INVALID_STATE,
+    };
+
+    enum class eScanStageResult : uint8_t {
+        PREPARED = 0,
+        INCOMPLETE,
+        SHADOW_DISABLED,
+        WRONG_THREAD,
+        STALE,
+        FAILED,
+    };
+
+    enum class eScanCommitResult : uint8_t {
+        COMMITTED = 0,
+        SHADOW_DISABLED,
+        WRONG_THREAD,
+        STALE,
+        FAILED,
+    };
+
+    enum class eSessionResult : uint8_t {
+        ROTATED = 0,
+        NOT_ATTACHED,
+        WRONG_THREAD,
+        EXHAUSTED,
+        BUSY,
+        INVALID_STATE,
+    };
+
+    enum class eDetachReason : uint8_t {
+        INITIALIZATION_ABORTED = 0,
+        GPU_REMOVED,
+        BACKEND_SHUTDOWN,
+        DESTRUCTOR_FALLBACK,
+    };
+
+    enum class eDetachResult : uint8_t {
+        BEGUN = 0,
+        ALREADY_BEGUN,
+        DETACHED,
+        NOT_ATTACHED,
+        WRONG_THREAD,
+        BUSY,
+        INVALID_STATE,
+    };
+
+    class CTiledDRMIntegrationRegistry;
+
+    class AQ_TILED_DRM_PRIVATE CConnectorScan final {
+      public:
+        ~CConnectorScan() noexcept;
+
+        CConnectorScan(const CConnectorScan&)               = delete;
+        CConnectorScan(CConnectorScan&&)                    = delete;
+        CConnectorScan&    operator=(const CConnectorScan&) = delete;
+        CConnectorScan&    operator=(CConnectorScan&&)      = delete;
+
+        [[nodiscard]] bool shadowEnabled() const;
+
+      private:
+        CConnectorScan(CTiledDRMIntegrationRegistry* registry, const void* key, PBackendLifetime lifetime, PScanAttemptTicket ticket, std::thread::id eventThread,
+                       bool shadowEnabled);
+
+        // Non-owning only for a shadow-enabled ticket. No-shadow handles keep
+        // this null and self-resolve without registry state.
+        CTiledDRMIntegrationRegistry* m_registry = nullptr;
+        const void*                   m_key      = nullptr;
+        PBackendLifetime              m_lifetime;
+        PScanAttemptTicket            m_ticket;
+        PPreparedScan                 m_prepared;
+        std::thread::id               m_eventThread;
+        bool                          m_shadowEnabled = false;
+        bool                          m_active        = true;
+        bool                          m_staged        = false;
+
+        friend class CTiledDRMIntegrationRegistry;
+    };
+
+    using PConnectorScan = CSharedPointer<CConnectorScan>;
+
+    struct AQ_TILED_DRM_PRIVATE SBeginConnectorScanResult {
+        PConnectorScan   scan;
+        eScanBeginResult result = eScanBeginResult::INVALID_STATE;
+
+        explicit         operator bool() const;
+    };
+
+    // Source-private exact-owner sidecar. It never publishes outputs or
+    // changes CRTC/KMS routing; currentComplete() is shadow state only.
+    class AQ_TILED_DRM_PRIVATE CTiledDRMIntegrationRegistry final {
+      public:
+        explicit CTiledDRMIntegrationRegistry(std::thread::id eventThread = std::this_thread::get_id());
+        ~CTiledDRMIntegrationRegistry() noexcept;
+
+        CTiledDRMIntegrationRegistry(const CTiledDRMIntegrationRegistry&)                      = delete;
+        CTiledDRMIntegrationRegistry(CTiledDRMIntegrationRegistry&&)                           = delete;
+        CTiledDRMIntegrationRegistry&           operator=(const CTiledDRMIntegrationRegistry&) = delete;
+        CTiledDRMIntegrationRegistry&           operator=(CTiledDRMIntegrationRegistry&&)      = delete;
+
+        [[nodiscard]] SBeginConnectorScanResult beginConnectorScan(const CSharedPointer<CDRMBackend>& backend);
+        [[nodiscard]] eScanStageResult          stageConnectorScan(const PConnectorScan& scan, eScanCompleteness completeness, std::vector<SConnectorView> connectors) noexcept;
+        [[nodiscard]] eScanCommitResult         commitConnectorScan(const PConnectorScan& scan) noexcept;
+        void                                    abortConnectorScan(const PConnectorScan& scan) noexcept;
+
+        [[nodiscard]] eSessionResult            rotateSession(const CWeakPointer<CDRMBackend>& backend) noexcept;
+        [[nodiscard]] eDetachResult             beginDetach(const CWeakPointer<CDRMBackend>& backend, eDetachReason reason) noexcept;
+        [[nodiscard]] eDetachResult             eraseDetached(const CWeakPointer<CDRMBackend>& backend) noexcept;
+
+        [[nodiscard]] bool                      attached(const CWeakPointer<CDRMBackend>& backend) const noexcept;
+        [[nodiscard]] bool                      lastConnectorScanComplete(const CWeakPointer<CDRMBackend>& backend) const noexcept;
+        [[nodiscard]] PCommittedScan            currentComplete(const CWeakPointer<CDRMBackend>& backend) noexcept;
+        [[nodiscard]] SScanOutcome              outcome(const CWeakPointer<CDRMBackend>& backend) noexcept;
+        [[nodiscard]] bool                      readyForDestruction() const noexcept;
+
+        // Narrow source-private failure injection for lifecycle tests.
+        void failNextAttachmentForTest() noexcept;
+
+      private:
+        [[nodiscard]] SBeginConnectorScanResult beginAttached(const void* key);
+        [[nodiscard]] eSessionResult            rotateSessionKey(const void* key) noexcept;
+        [[nodiscard]] eDetachResult             beginDetachKey(const void* key, eDetachReason reason) noexcept;
+        [[nodiscard]] eDetachResult             eraseDetachedKey(const void* key) noexcept;
+        [[nodiscard]] bool                      attachedKey(const void* key) const noexcept;
+        [[nodiscard]] PCommittedScan            currentCompleteKey(const void* key) noexcept;
+        [[nodiscard]] SScanOutcome              outcomeKey(const void* key) noexcept;
+        void                                    abortConnectorScan(CConnectorScan& scan) noexcept;
+
+        [[nodiscard]] SBeginConnectorScanResult beginTestConnectorScan(const PBackendLifetime& lifetime);
+        [[nodiscard]] eSessionResult            rotateTestSession(const PBackendLifetime& lifetime) noexcept;
+        [[nodiscard]] eDetachResult             beginTestDetach(const PBackendLifetime& lifetime, eDetachReason reason) noexcept;
+        [[nodiscard]] eDetachResult             eraseTestDetached(const PBackendLifetime& lifetime) noexcept;
+        [[nodiscard]] bool                      testAttached(const PBackendLifetime& lifetime) const noexcept;
+        [[nodiscard]] bool                      testLastConnectorScanComplete(const PBackendLifetime& lifetime) const noexcept;
+        [[nodiscard]] PCommittedScan            testCurrentComplete(const PBackendLifetime& lifetime) noexcept;
+        [[nodiscard]] SScanOutcome              testOutcome(const PBackendLifetime& lifetime) noexcept;
+
+        class CImpl;
+        Hyprutils::Memory::CUniquePointer<CImpl> m_impl;
+
+        friend class CConnectorScan;
+        friend class ::Aquamarine::NDRM::NTiledDRMIntegrationTest::CFixtureAuthority;
+    };
+
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE SBeginConnectorScanResult beginConnectorScan(const CSharedPointer<CDRMBackend>& backend);
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE eScanStageResult          stageConnectorScan(const PConnectorScan& scan, eScanCompleteness completeness,
+                                                                                    std::vector<SConnectorView> connectors) noexcept;
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE eScanCommitResult         commitConnectorScan(const PConnectorScan& scan) noexcept;
+    AQ_TILED_DRM_PRIVATE void                                    abortConnectorScan(const PConnectorScan& scan) 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;
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE bool                      attached(const CWeakPointer<CDRMBackend>& backend) noexcept;
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE bool                      lastConnectorScanComplete(const CWeakPointer<CDRMBackend>& backend) noexcept;
+    [[nodiscard]] AQ_TILED_DRM_PRIVATE PCommittedScan            currentComplete(const CWeakPointer<CDRMBackend>& backend) noexcept;
+
+}
+
+#undef AQ_TILED_DRM_PRIVATE
diff --git a/tests/ConnectorScan.cpp b/tests/ConnectorScan.cpp
index b09ffc7c896f30f729bf76ae6e2f92d218983bfc..2cf2cce1f611e6a6aefedab1f53f89d5a6b4746c 100644
--- a/tests/ConnectorScan.cpp
+++ b/tests/ConnectorScan.cpp
@@ -33,6 +33,7 @@ namespace {
         };
         std::optional<uint32_t>         acquisitionFailure;
         std::optional<uint32_t>         initializationFailure;
+        std::optional<uint32_t>         propertyBlobFailure;
         int                             acquisitionCount    = 0;
         int                             initializationCount = 0;
         int                             commitCount         = 0;
@@ -51,6 +52,8 @@ namespace {
                 if (initializationFailure == id)
                     return std::nullopt;
             }
+            if (propertyBlobFailure == id)
+                return std::nullopt;
 
             return SStagedConnector{.id = id, .status = static_cast<int>(id * 10), .modes = {static_cast<int>(id * 100), static_cast<int>((id * 100) + 1)}};
         }
@@ -127,6 +130,43 @@ int main() {
         EXPECT(harness.initializationCount, 1);
     }
 
+    {
+        SScanHarness harness;
+        const auto   before         = harness.live;
+        harness.propertyBlobFailure = 3;
+
+        const auto result = connectorScanTransaction<SStagedConnector>(
+            CHANGED_SNAPSHOT, [&](uint32_t id) { return harness.stage(id); }, [&](std::span<SStagedConnector> staged) { harness.commit(staged); });
+
+        EXPECT(resultOf(result), resultOf(eConnectorScanResult::STAGING_FAILED));
+        EXPECT(harness.live == before, true);
+        EXPECT(harness.commitCount, 0);
+        EXPECT(harness.disconnectCount, 0);
+    }
+
+    {
+        SScanHarness                  harness;
+        const auto                    before = harness.live;
+        std::vector<SStagedConnector> staged;
+
+        // Production verifies a second resource snapshot before invoking the
+        // live commit. A mismatch therefore discards this fully acquired
+        // staging vector without touching the prior live state.
+        const auto result = connectorScanTransaction<SStagedConnector>(
+            CHANGED_SNAPSHOT, [&](uint32_t id) { return harness.stage(id); },
+            [&](std::span<SStagedConnector> complete) {
+                staged.reserve(complete.size());
+                for (auto& connector : complete)
+                    staged.emplace_back(std::move(connector));
+            });
+
+        EXPECT(resultOf(result), resultOf(eConnectorScanResult::COMMITTED));
+        EXPECT(staged.size(), CHANGED_SNAPSHOT.size());
+        EXPECT(harness.live == before, true);
+        EXPECT(harness.commitCount, 0);
+        EXPECT(harness.disconnectCount, 0);
+    }
+
     {
         SScanHarness                      harness;
         const auto                        before = harness.live;
@@ -188,5 +228,18 @@ int main() {
         EXPECT(harness.initializationCount, 0);
     }
 
+    {
+        SScanHarness                      harness;
+        constexpr std::array<uint32_t, 2> REORDERED_WITH_NEW{3, 2};
+
+        const auto                        result = connectorScanTransaction<SStagedConnector>(
+            REORDERED_WITH_NEW, [&](uint32_t id) { return harness.stage(id); }, [&](std::span<SStagedConnector> staged) { harness.commit(staged); });
+
+        EXPECT(resultOf(result), resultOf(eConnectorScanResult::COMMITTED));
+        EXPECT(harness.live.size(), 2U);
+        EXPECT(harness.live.at(0).id, 2U);
+        EXPECT(harness.live.at(1).id, 3U);
+    }
+
     return ret;
 }
diff --git a/tests/TiledDRMIntegration.cpp b/tests/TiledDRMIntegration.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..970b236515f76a537cd3ba56750d559c117980bc
--- /dev/null
+++ b/tests/TiledDRMIntegration.cpp
@@ -0,0 +1,201 @@
+#include "backend/drm/TiledDRMIntegration.hpp"
+#include "shared.hpp"
+
+#include <atomic>
+#include <cstdint>
+#include <thread>
+#include <utility>
+#include <vector>
+
+#include <hyprutils/memory/UniquePtr.hpp>
+
+using namespace Aquamarine::NDRM::NTiledDRMIntegration;
+using namespace Aquamarine::NDRM::NTiledIncarnations;
+using namespace Aquamarine::NDRM::NTiledScan;
+using namespace Hyprutils::Memory;
+
+namespace Aquamarine::NDRM::NTiledDRMIntegrationTest {
+    // This authority exists only in this test translation unit. Production
+    // keeps observation/attempt/commit construction private to the state.
+    class CFixtureAuthority {
+      public:
+        static SBeginConnectorScanResult begin(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime) {
+            return registry.beginTestConnectorScan(lifetime);
+        }
+
+        static eSessionResult rotate(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime) {
+            return registry.rotateTestSession(lifetime);
+        }
+
+        static eDetachResult beginDetach(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime, eDetachReason reason) {
+            return registry.beginTestDetach(lifetime, reason);
+        }
+
+        static eDetachResult erase(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime) {
+            return registry.eraseTestDetached(lifetime);
+        }
+
+        static bool attached(const CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime) {
+            return registry.testAttached(lifetime);
+        }
+
+        static bool lastComplete(const CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime) {
+            return registry.testLastConnectorScanComplete(lifetime);
+        }
+
+        static PCommittedScan current(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime) {
+            return registry.testCurrentComplete(lifetime);
+        }
+
+        static SScanOutcome outcome(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime) {
+            return registry.testOutcome(lifetime);
+        }
+    };
+}
+
+using Aquamarine::NDRM::NTiledDRMIntegrationTest::CFixtureAuthority;
+
+namespace {
+    int value(eScanBeginResult result) {
+        return static_cast<int>(result);
+    }
+
+    int value(eScanStageResult result) {
+        return static_cast<int>(result);
+    }
+
+    int value(eScanCommitResult result) {
+        return static_cast<int>(result);
+    }
+
+    int value(eSessionResult result) {
+        return static_cast<int>(result);
+    }
+
+    int value(eDetachResult result) {
+        return static_cast<int>(result);
+    }
+
+    int value(eScanOutcome result) {
+        return static_cast<int>(result);
+    }
+
+    SConnectorView connector(uint32_t id) {
+        return {.connectorId = id};
+    }
+
+    PCommittedScan commitComplete(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime, uint32_t connectorId, int& ret) {
+        auto begun = CFixtureAuthority::begin(registry, lifetime);
+        EXPECT(value(begun.result), value(eScanBeginResult::STARTED));
+        EXPECT(!!begun.scan, true);
+        EXPECT(value(registry.stageConnectorScan(begun.scan, eScanCompleteness::COMPLETE, {connector(connectorId)})), value(eScanStageResult::PREPARED));
+        EXPECT(value(registry.commitConnectorScan(begun.scan)), value(eScanCommitResult::COMMITTED));
+        return CFixtureAuthority::current(registry, lifetime);
+    }
+}
+
+int main() {
+    int ret = 0;
+
+    {
+        CTiledDRMIntegrationRegistry registry;
+        const auto                   LIFETIME = CBackendLifetime::createTestToken(11);
+
+        const auto                   FIRST = commitComplete(registry, LIFETIME, 41, ret);
+        EXPECT(!!FIRST, true);
+        EXPECT(CFixtureAuthority::attached(registry, LIFETIME), true);
+        EXPECT(CFixtureAuthority::lastComplete(registry, LIFETIME), true);
+        EXPECT(FIRST && FIRST->findConnector(41), true);
+        EXPECT(FIRST && FIRST->observation()->session()->backend().lock() == LIFETIME, true);
+
+        auto incomplete = CFixtureAuthority::begin(registry, LIFETIME);
+        EXPECT(value(incomplete.result), value(eScanBeginResult::STARTED));
+        EXPECT(value(registry.stageConnectorScan(incomplete.scan, eScanCompleteness::INCOMPLETE, {})), value(eScanStageResult::INCOMPLETE));
+        EXPECT(CFixtureAuthority::lastComplete(registry, LIFETIME), false);
+        EXPECT(!!CFixtureAuthority::current(registry, LIFETIME), false);
+        EXPECT(value(CFixtureAuthority::outcome(registry, LIFETIME).result), value(eScanOutcome::INCOMPLETE));
+
+        EXPECT(value(CFixtureAuthority::rotate(registry, LIFETIME)), value(eSessionResult::ROTATED));
+        EXPECT(!!CFixtureAuthority::current(registry, LIFETIME), false);
+        const auto SECOND = commitComplete(registry, LIFETIME, 42, ret);
+        EXPECT(!!SECOND, true);
+        EXPECT(SECOND != FIRST, true);
+
+        EXPECT(value(CFixtureAuthority::beginDetach(registry, LIFETIME, eDetachReason::BACKEND_SHUTDOWN)), value(eDetachResult::BEGUN));
+        EXPECT(CFixtureAuthority::attached(registry, LIFETIME), true);
+        EXPECT(!!CFixtureAuthority::current(registry, LIFETIME), false);
+        EXPECT(value(CFixtureAuthority::outcome(registry, LIFETIME).result), value(eScanOutcome::TEARING_DOWN));
+
+        // A queued recheck cannot revive a detached exact backend while an
+        // external owner keeps it alive.
+        const auto QUEUED = CFixtureAuthority::begin(registry, LIFETIME);
+        EXPECT(!!QUEUED.scan, false);
+        EXPECT(value(QUEUED.result), value(eScanBeginResult::INVALID_STATE));
+        EXPECT(value(CFixtureAuthority::erase(registry, LIFETIME)), value(eDetachResult::DETACHED));
+        EXPECT(CFixtureAuthority::attached(registry, LIFETIME), false);
+        EXPECT(registry.readyForDestruction(), true);
+    }
+
+    {
+        CTiledDRMIntegrationRegistry registry;
+        const auto                   LIFETIME = CBackendLifetime::createTestToken(21);
+        auto                         begun    = CFixtureAuthority::begin(registry, LIFETIME);
+        EXPECT(value(begun.result), value(eScanBeginResult::STARTED));
+        begun.scan.reset();
+        EXPECT(value(CFixtureAuthority::outcome(registry, LIFETIME).result), value(eScanOutcome::ACQUISITION_FAILED));
+
+        const auto RECOVERED = commitComplete(registry, LIFETIME, 51, ret);
+        EXPECT(!!RECOVERED, true);
+        EXPECT(value(CFixtureAuthority::beginDetach(registry, LIFETIME, eDetachReason::INITIALIZATION_ABORTED)), value(eDetachResult::BEGUN));
+        EXPECT(value(CFixtureAuthority::erase(registry, LIFETIME)), value(eDetachResult::DETACHED));
+    }
+
+    {
+        CTiledDRMIntegrationRegistry registry;
+        const auto                   LIFETIME = CBackendLifetime::createTestToken(31);
+        EXPECT(!!commitComplete(registry, LIFETIME, 61, ret), true);
+
+        std::atomic<int> wrongThreadResult = -1;
+        std::thread      wrongThread([&] { wrongThreadResult = value(CFixtureAuthority::beginDetach(registry, LIFETIME, eDetachReason::GPU_REMOVED)); });
+        wrongThread.join();
+        EXPECT(wrongThreadResult.load(), value(eDetachResult::WRONG_THREAD));
+        EXPECT(CFixtureAuthority::attached(registry, LIFETIME), true);
+        EXPECT(!!CFixtureAuthority::current(registry, LIFETIME), true);
+
+        EXPECT(value(CFixtureAuthority::beginDetach(registry, LIFETIME, eDetachReason::GPU_REMOVED)), value(eDetachResult::BEGUN));
+        EXPECT(value(CFixtureAuthority::erase(registry, LIFETIME)), value(eDetachResult::DETACHED));
+    }
+
+    {
+        const auto LIFETIME = CBackendLifetime::createTestToken(41);
+        auto       registry = makeUnique<CTiledDRMIntegrationRegistry>();
+        registry->failNextAttachmentForTest();
+        auto begun = CFixtureAuthority::begin(*registry, LIFETIME);
+        EXPECT(value(begun.result), value(eScanBeginResult::SHADOW_DISABLED));
+        EXPECT(!!begun.scan, true);
+        EXPECT(begun.scan->shadowEnabled(), false);
+        EXPECT(registry->readyForDestruction(), true);
+
+        // Dropping a no-shadow handle after its explicit registry has gone is
+        // safe: the handle owns no registry state and self-resolves.
+        auto scan = begun.scan;
+        registry.reset();
+        begun.scan.reset();
+        scan.reset();
+    }
+
+    {
+        CTiledDRMIntegrationRegistry registry;
+        const auto                   LIFETIME = CBackendLifetime::createTestToken(51);
+        registry.failNextAttachmentForTest();
+        auto begun = CFixtureAuthority::begin(registry, LIFETIME);
+        EXPECT(value(registry.stageConnectorScan(begun.scan, eScanCompleteness::COMPLETE, {connector(71)})), value(eScanStageResult::SHADOW_DISABLED));
+        EXPECT(value(registry.commitConnectorScan(begun.scan)), value(eScanCommitResult::SHADOW_DISABLED));
+        EXPECT(CFixtureAuthority::lastComplete(registry, LIFETIME), true);
+        EXPECT(value(CFixtureAuthority::beginDetach(registry, LIFETIME, eDetachReason::DESTRUCTOR_FALLBACK)), value(eDetachResult::NOT_ATTACHED));
+        EXPECT(CFixtureAuthority::lastComplete(registry, LIFETIME), false);
+        EXPECT(registry.readyForDestruction(), true);
+    }
+
+    return ret;
+}
diff --git a/tests/TiledVisibility.cmake b/tests/TiledVisibility.cmake
index a59ce36465699a6df2422fee868c56ecaa5112b4..eca8280dc7f5718fc7f1fa60ff0e72c257307c0d 100644
--- a/tests/TiledVisibility.cmake
+++ b/tests/TiledVisibility.cmake
@@ -74,6 +74,6 @@ if(NOT demangle_result EQUAL 0)
 endif()
 
 if(demangled_output MATCHES
-   "Aquamarine::(NTiling|TiledCrtcAllocator)::|Aquamarine::NDRM::NTiled(CrtcAllocator|Incarnations|Scan)::|Aquamarine::NDRM::.*(Tile|tile|PlaneViewport|PlaneFormats|intersectPlaneFormats|encodePlaneViewport)")
+   "Aquamarine::(NTiling|TiledCrtcAllocator)::|Aquamarine::NDRM::NTiled(CrtcAllocator|Incarnations|Scan|DRMIntegration)::|Aquamarine::NDRM::.*(Tile|tile|PlaneViewport|PlaneFormats|intersectPlaneFormats|encodePlaneViewport)")
   message(FATAL_ERROR "source-private TILE symbol family is dynamically exported")
 endif()