monitor: avoid dangling references to old monitors being undestroyed

ref #7414
This commit is contained in:
Vaxry 2024-08-19 18:44:22 +02:00
parent 272d904870
commit c86db7bbb0
5 changed files with 19 additions and 33 deletions

View file

@ -2935,7 +2935,7 @@ PHLWINDOW CCompositor::windowForCPointer(CWindow* pWindow) {
void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) { void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
// add it to real // add it to real
auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared<CMonitor>()); auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared<CMonitor>(output));
if (std::string("HEADLESS-1") == output->name) { if (std::string("HEADLESS-1") == output->name) {
g_pCompositor->m_pUnsafeOutput = PNEWMONITOR.get(); g_pCompositor->m_pUnsafeOutput = PNEWMONITOR.get();
output->name = "FALLBACK"; // we are allowed to do this :) output->name = "FALLBACK"; // we are allowed to do this :)
@ -2944,7 +2944,6 @@ void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
Debug::log(LOG, "New output with name {}", output->name); Debug::log(LOG, "New output with name {}", output->name);
PNEWMONITOR->szName = output->name; PNEWMONITOR->szName = output->name;
PNEWMONITOR->output = output;
PNEWMONITOR->self = PNEWMONITOR; PNEWMONITOR->self = PNEWMONITOR;
const bool FALLBACK = g_pCompositor->m_pUnsafeOutput ? output == g_pCompositor->m_pUnsafeOutput->output : false; const bool FALLBACK = g_pCompositor->m_pUnsafeOutput ? output == g_pCompositor->m_pUnsafeOutput->output : false;
PNEWMONITOR->ID = FALLBACK ? MONITOR_INVALID : g_pCompositor->getNextAvailableMonitorID(output->name); PNEWMONITOR->ID = FALLBACK ? MONITOR_INVALID : g_pCompositor->getNextAvailableMonitorID(output->name);

View file

@ -27,7 +27,6 @@ namespace Events {
// Monitor part 2 the sequel // Monitor part 2 the sequel
DYNLISTENFUNC(monitorFrame); DYNLISTENFUNC(monitorFrame);
DYNLISTENFUNC(monitorDestroy);
DYNLISTENFUNC(monitorStateRequest); DYNLISTENFUNC(monitorStateRequest);
DYNLISTENFUNC(monitorDamage); DYNLISTENFUNC(monitorDamage);
DYNLISTENFUNC(monitorNeedsFrame); DYNLISTENFUNC(monitorNeedsFrame);

View file

@ -85,31 +85,6 @@ void Events::listener_monitorFrame(void* owner, void* data) {
} }
} }
void Events::listener_monitorDestroy(void* owner, void* data) {
CMonitor* pMonitor = (CMonitor*)owner;
for (auto& m : g_pCompositor->m_vRealMonitors) {
if (m->output == pMonitor->output) {
pMonitor = m.get();
break;
}
}
if (!pMonitor)
return;
Debug::log(LOG, "Destroy called for monitor {}", pMonitor->szName);
pMonitor->onDisconnect(true);
pMonitor->output = nullptr;
pMonitor->m_bRenderingInitPassed = false;
Debug::log(LOG, "Removing monitor {} from realMonitors", pMonitor->szName);
std::erase_if(g_pCompositor->m_vRealMonitors, [&](SP<CMonitor>& el) { return el.get() == pMonitor; });
}
void Events::listener_monitorNeedsFrame(void* owner, void* data) { void Events::listener_monitorNeedsFrame(void* owner, void* data) {
const auto PMONITOR = (CMonitor*)owner; const auto PMONITOR = (CMonitor*)owner;

View file

@ -25,7 +25,7 @@ int ratHandler(void* data) {
return 1; return 1;
} }
CMonitor::CMonitor() : state(this) { CMonitor::CMonitor(SP<Aquamarine::IOutput> output_) : state(this), output(output_) {
; ;
} }
@ -40,16 +40,29 @@ void CMonitor::onConnect(bool noRule) {
outTimeline = CSyncTimeline::create(output->getBackend()->drmFD()); outTimeline = CSyncTimeline::create(output->getBackend()->drmFD());
} }
listeners.frame = output->events.frame.registerListener([this](std::any d) { Events::listener_monitorFrame(this, nullptr); }); listeners.frame = output->events.frame.registerListener([this](std::any d) { Events::listener_monitorFrame(this, nullptr); });
listeners.destroy = output->events.destroy.registerListener([this](std::any d) { Events::listener_monitorDestroy(this, nullptr); }); listeners.commit = output->events.commit.registerListener([this](std::any d) { Events::listener_monitorCommit(this, nullptr); });
listeners.commit = output->events.commit.registerListener([this](std::any d) { Events::listener_monitorCommit(this, nullptr); });
listeners.needsFrame = listeners.needsFrame =
output->events.needsFrame.registerListener([this](std::any d) { g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); }); output->events.needsFrame.registerListener([this](std::any d) { g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); });
listeners.presented = output->events.present.registerListener([this](std::any d) { listeners.presented = output->events.present.registerListener([this](std::any d) {
auto E = std::any_cast<Aquamarine::IOutput::SPresentEvent>(d); auto E = std::any_cast<Aquamarine::IOutput::SPresentEvent>(d);
PROTO::presentation->onPresented(this, E.when, E.refresh, E.seq, E.flags); PROTO::presentation->onPresented(this, E.when, E.refresh, E.seq, E.flags);
}); });
listeners.destroy = output->events.destroy.registerListener([this](std::any d) {
Debug::log(LOG, "Destroy called for monitor {}", szName);
onDisconnect(true);
output = nullptr;
m_bRenderingInitPassed = false;
Debug::log(LOG, "Removing monitor {} from realMonitors", szName);
std::erase_if(g_pCompositor->m_vRealMonitors, [&](SP<CMonitor>& el) { return el.get() == this; });
});
listeners.state = output->events.state.registerListener([this](std::any d) { listeners.state = output->events.state.registerListener([this](std::any d) {
auto E = std::any_cast<Aquamarine::IOutput::SStateEvent>(d); auto E = std::any_cast<Aquamarine::IOutput::SStateEvent>(d);

View file

@ -59,7 +59,7 @@ class CMonitorState {
class CMonitor { class CMonitor {
public: public:
CMonitor(); CMonitor(SP<Aquamarine::IOutput> output);
~CMonitor(); ~CMonitor();
Vector2D vecPosition = Vector2D(-1, -1); // means unset Vector2D vecPosition = Vector2D(-1, -1); // means unset