mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-15 09:25:59 +01:00
monitor: modernize/refactor last legacy-handled events
This commit is contained in:
parent
48bf32c5de
commit
62ee5cc273
5 changed files with 74 additions and 116 deletions
|
@ -3057,5 +3057,5 @@ void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pHyprRenderer->damageMonitor(PNEWMONITOR.get());
|
g_pHyprRenderer->damageMonitor(PNEWMONITOR.get());
|
||||||
Events::listener_monitorFrame(PNEWMONITOR.get(), nullptr);
|
PNEWMONITOR->onMonitorFrame();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,12 +24,4 @@ namespace Events {
|
||||||
DYNLISTENFUNC(requestMaximize);
|
DYNLISTENFUNC(requestMaximize);
|
||||||
DYNLISTENFUNC(setOverrideRedirect);
|
DYNLISTENFUNC(setOverrideRedirect);
|
||||||
DYNLISTENFUNC(ackConfigure);
|
DYNLISTENFUNC(ackConfigure);
|
||||||
|
|
||||||
// Monitor part 2 the sequel
|
|
||||||
DYNLISTENFUNC(monitorFrame);
|
|
||||||
DYNLISTENFUNC(monitorStateRequest);
|
|
||||||
DYNLISTENFUNC(monitorDamage);
|
|
||||||
DYNLISTENFUNC(monitorNeedsFrame);
|
|
||||||
DYNLISTENFUNC(monitorCommit);
|
|
||||||
DYNLISTENFUNC(monitorBind);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
#include "../Compositor.hpp"
|
|
||||||
#include "../helpers/WLClasses.hpp"
|
|
||||||
#include "../managers/input/InputManager.hpp"
|
|
||||||
#include "../render/Renderer.hpp"
|
|
||||||
#include "Events.hpp"
|
|
||||||
#include "../debug/HyprCtl.hpp"
|
|
||||||
#include "../config/ConfigValue.hpp"
|
|
||||||
#include "../protocols/Screencopy.hpp"
|
|
||||||
#include "../protocols/ToplevelExport.hpp"
|
|
||||||
#include <aquamarine/output/Output.hpp>
|
|
||||||
|
|
||||||
// --------------------------------------------------------- //
|
|
||||||
// __ __ ____ _ _ _____ _______ ____ _____ _____ //
|
|
||||||
// | \/ |/ __ \| \ | |_ _|__ __/ __ \| __ \ / ____| //
|
|
||||||
// | \ / | | | | \| | | | | | | | | | |__) | (___ //
|
|
||||||
// | |\/| | | | | . ` | | | | | | | | | _ / \___ \ //
|
|
||||||
// | | | | |__| | |\ |_| |_ | | | |__| | | \ \ ____) | //
|
|
||||||
// |_| |_|\____/|_| \_|_____| |_| \____/|_| \_\_____/ //
|
|
||||||
// //
|
|
||||||
// --------------------------------------------------------- //
|
|
||||||
|
|
||||||
void Events::listener_monitorFrame(void* owner, void* data) {
|
|
||||||
CMonitor* const PMONITOR = (CMonitor*)owner;
|
|
||||||
|
|
||||||
if ((g_pCompositor->m_pAqBackend->hasSession() && !g_pCompositor->m_pAqBackend->session->active) || !g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
|
|
||||||
Debug::log(WARN, "Attempted to render frame on inactive session!");
|
|
||||||
|
|
||||||
if (g_pCompositor->m_bUnsafeState && std::ranges::any_of(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& m) {
|
|
||||||
return m->output != g_pCompositor->m_pUnsafeOutput->output;
|
|
||||||
})) {
|
|
||||||
// restore from unsafe state
|
|
||||||
g_pCompositor->leaveUnsafeState();
|
|
||||||
}
|
|
||||||
|
|
||||||
return; // cannot draw on session inactive (different tty)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PMONITOR->m_bEnabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_pHyprRenderer->recheckSolitaryForMonitor(PMONITOR);
|
|
||||||
|
|
||||||
PMONITOR->tearingState.busy = false;
|
|
||||||
|
|
||||||
if (PMONITOR->tearingState.activelyTearing && PMONITOR->solitaryClient.lock() /* can be invalidated by a recheck */) {
|
|
||||||
|
|
||||||
if (!PMONITOR->tearingState.frameScheduledWhileBusy)
|
|
||||||
return; // we did not schedule a frame yet to be displayed, but we are tearing. Why render?
|
|
||||||
|
|
||||||
PMONITOR->tearingState.nextRenderTorn = true;
|
|
||||||
PMONITOR->tearingState.frameScheduledWhileBusy = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto PENABLERAT = CConfigValue<Hyprlang::INT>("misc:render_ahead_of_time");
|
|
||||||
static auto PRATSAFE = CConfigValue<Hyprlang::INT>("misc:render_ahead_safezone");
|
|
||||||
|
|
||||||
PMONITOR->lastPresentationTimer.reset();
|
|
||||||
|
|
||||||
if (*PENABLERAT && !PMONITOR->tearingState.nextRenderTorn) {
|
|
||||||
if (!PMONITOR->RATScheduled) {
|
|
||||||
// render
|
|
||||||
g_pHyprRenderer->renderMonitor(PMONITOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
PMONITOR->RATScheduled = false;
|
|
||||||
|
|
||||||
const auto& [avg, max, min] = g_pHyprRenderer->getRenderTimes(PMONITOR);
|
|
||||||
|
|
||||||
if (max + *PRATSAFE > 1000.0 / PMONITOR->refreshRate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto MSLEFT = 1000.0 / PMONITOR->refreshRate - PMONITOR->lastPresentationTimer.getMillis();
|
|
||||||
|
|
||||||
PMONITOR->RATScheduled = true;
|
|
||||||
|
|
||||||
const auto ESTRENDERTIME = std::ceil(avg + *PRATSAFE);
|
|
||||||
const auto TIMETOSLEEP = std::floor(MSLEFT - ESTRENDERTIME);
|
|
||||||
|
|
||||||
if (MSLEFT < 1 || MSLEFT < ESTRENDERTIME || TIMETOSLEEP < 1)
|
|
||||||
g_pHyprRenderer->renderMonitor(PMONITOR);
|
|
||||||
else
|
|
||||||
wl_event_source_timer_update(PMONITOR->renderTimer, TIMETOSLEEP);
|
|
||||||
} else {
|
|
||||||
g_pHyprRenderer->renderMonitor(PMONITOR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::listener_monitorNeedsFrame(void* owner, void* data) {
|
|
||||||
const auto PMONITOR = (CMonitor*)owner;
|
|
||||||
|
|
||||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::listener_monitorCommit(void* owner, void* data) {
|
|
||||||
const auto PMONITOR = (CMonitor*)owner;
|
|
||||||
|
|
||||||
if (true) { // FIXME: E->state->committed & WLR_OUTPUT_STATE_BUFFER
|
|
||||||
PROTO::screencopy->onOutputCommit(PMONITOR);
|
|
||||||
PROTO::toplevelExport->onOutputCommit(PMONITOR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::listener_monitorBind(void* owner, void* data) {
|
|
||||||
;
|
|
||||||
}
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include "../protocols/DRMLease.hpp"
|
#include "../protocols/DRMLease.hpp"
|
||||||
#include "../protocols/DRMSyncobj.hpp"
|
#include "../protocols/DRMSyncobj.hpp"
|
||||||
#include "../protocols/core/Output.hpp"
|
#include "../protocols/core/Output.hpp"
|
||||||
|
#include "../protocols/Screencopy.hpp"
|
||||||
|
#include "../protocols/ToplevelExport.hpp"
|
||||||
#include "../managers/PointerManager.hpp"
|
#include "../managers/PointerManager.hpp"
|
||||||
#include "../managers/eventLoop/EventLoopManager.hpp"
|
#include "../managers/eventLoop/EventLoopManager.hpp"
|
||||||
#include "../protocols/core/Compositor.hpp"
|
#include "../protocols/core/Compositor.hpp"
|
||||||
|
@ -44,8 +46,13 @@ 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) { onMonitorFrame(); });
|
||||||
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) {
|
||||||
|
if (true) { // FIXME: E->state->committed & WLR_OUTPUT_STATE_BUFFER
|
||||||
|
PROTO::screencopy->onOutputCommit(this);
|
||||||
|
PROTO::toplevelExport->onOutputCommit(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
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); });
|
||||||
|
|
||||||
|
@ -939,6 +946,69 @@ void CMonitor::debugLastPresentation(const std::string& message) {
|
||||||
lastPresentationTimer.getMillis() > 0 ? 1000.0f / lastPresentationTimer.getMillis() : 0.0f);
|
lastPresentationTimer.getMillis() > 0 ? 1000.0f / lastPresentationTimer.getMillis() : 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMonitor::onMonitorFrame() {
|
||||||
|
if ((g_pCompositor->m_pAqBackend->hasSession() && !g_pCompositor->m_pAqBackend->session->active) || !g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
|
||||||
|
Debug::log(WARN, "Attempted to render frame on inactive session!");
|
||||||
|
|
||||||
|
if (g_pCompositor->m_bUnsafeState && std::ranges::any_of(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& m) {
|
||||||
|
return m->output != g_pCompositor->m_pUnsafeOutput->output;
|
||||||
|
})) {
|
||||||
|
// restore from unsafe state
|
||||||
|
g_pCompositor->leaveUnsafeState();
|
||||||
|
}
|
||||||
|
|
||||||
|
return; // cannot draw on session inactive (different tty)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_bEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_pHyprRenderer->recheckSolitaryForMonitor(this);
|
||||||
|
|
||||||
|
tearingState.busy = false;
|
||||||
|
|
||||||
|
if (tearingState.activelyTearing && solitaryClient.lock() /* can be invalidated by a recheck */) {
|
||||||
|
|
||||||
|
if (!tearingState.frameScheduledWhileBusy)
|
||||||
|
return; // we did not schedule a frame yet to be displayed, but we are tearing. Why render?
|
||||||
|
|
||||||
|
tearingState.nextRenderTorn = true;
|
||||||
|
tearingState.frameScheduledWhileBusy = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto PENABLERAT = CConfigValue<Hyprlang::INT>("misc:render_ahead_of_time");
|
||||||
|
static auto PRATSAFE = CConfigValue<Hyprlang::INT>("misc:render_ahead_safezone");
|
||||||
|
|
||||||
|
lastPresentationTimer.reset();
|
||||||
|
|
||||||
|
if (*PENABLERAT && !tearingState.nextRenderTorn) {
|
||||||
|
if (!RATScheduled) {
|
||||||
|
// render
|
||||||
|
g_pHyprRenderer->renderMonitor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
RATScheduled = false;
|
||||||
|
|
||||||
|
const auto& [avg, max, min] = g_pHyprRenderer->getRenderTimes(this);
|
||||||
|
|
||||||
|
if (max + *PRATSAFE > 1000.0 / refreshRate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto MSLEFT = 1000.0 / refreshRate - lastPresentationTimer.getMillis();
|
||||||
|
|
||||||
|
RATScheduled = true;
|
||||||
|
|
||||||
|
const auto ESTRENDERTIME = std::ceil(avg + *PRATSAFE);
|
||||||
|
const auto TIMETOSLEEP = std::floor(MSLEFT - ESTRENDERTIME);
|
||||||
|
|
||||||
|
if (MSLEFT < 1 || MSLEFT < ESTRENDERTIME || TIMETOSLEEP < 1)
|
||||||
|
g_pHyprRenderer->renderMonitor(this);
|
||||||
|
else
|
||||||
|
wl_event_source_timer_update(renderTimer, TIMETOSLEEP);
|
||||||
|
} else
|
||||||
|
g_pHyprRenderer->renderMonitor(this);
|
||||||
|
}
|
||||||
|
|
||||||
CMonitorState::CMonitorState(CMonitor* owner) {
|
CMonitorState::CMonitorState(CMonitor* owner) {
|
||||||
m_pOwner = owner;
|
m_pOwner = owner;
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,6 +186,7 @@ class CMonitor {
|
||||||
void setCTM(const Mat3x3& ctm);
|
void setCTM(const Mat3x3& ctm);
|
||||||
|
|
||||||
void debugLastPresentation(const std::string& message);
|
void debugLastPresentation(const std::string& message);
|
||||||
|
void onMonitorFrame();
|
||||||
|
|
||||||
bool m_bEnabled = false;
|
bool m_bEnabled = false;
|
||||||
bool m_bRenderingInitPassed = false;
|
bool m_bRenderingInitPassed = false;
|
||||||
|
|
Loading…
Reference in a new issue