monitor: wrap usage of wlr_output_state

for better control and convenience in usage.

fixes #4546
This commit is contained in:
Vaxry
2024-01-28 01:57:13 +00:00
parent 9002657bcc
commit bfcc2adbda
8 changed files with 124 additions and 101 deletions

View File

@@ -903,9 +903,9 @@ bool CHyprRenderer::attemptDirectScanout(CMonitor* pMonitor) {
return false;
// finally, we should be GTG.
wlr_output_state_set_buffer(&pMonitor->outputState, &PSURFACE->buffer->base);
wlr_output_state_set_buffer(pMonitor->state.wlr(), &PSURFACE->buffer->base);
if (!wlr_output_test_state(pMonitor->output, &pMonitor->outputState))
if (!wlr_output_test_state(pMonitor->output, pMonitor->state.wlr()))
return false;
timespec now;
@@ -913,7 +913,7 @@ bool CHyprRenderer::attemptDirectScanout(CMonitor* pMonitor) {
wlr_surface_send_frame_done(PSURFACE, &now);
wlr_presentation_surface_scanned_out_on_output(PSURFACE, pMonitor->output);
if (wlr_output_commit_state(pMonitor->output, &pMonitor->outputState)) {
if (pMonitor->state.commit()) {
if (!m_pLastScanout) {
m_pLastScanout = PCANDIDATE;
Debug::log(LOG, "Entered a direct scanout to {:x}: \"{}\"", (uintptr_t)PCANDIDATE, PCANDIDATE->m_szTitle);
@@ -1014,15 +1014,15 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
const auto PGAMMACTRL = wlr_gamma_control_manager_v1_get_control(g_pCompositor->m_sWLRGammaCtrlMgr, pMonitor->output);
if (!wlr_gamma_control_v1_apply(PGAMMACTRL, &pMonitor->outputState)) {
if (!wlr_gamma_control_v1_apply(PGAMMACTRL, pMonitor->state.wlr())) {
Debug::log(ERR, "Could not apply gamma control to {}", pMonitor->szName);
return;
}
if (!wlr_output_test_state(pMonitor->output, &pMonitor->outputState)) {
if (!wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) {
Debug::log(ERR, "Output test failed for setting gamma to {}", pMonitor->szName);
// aka rollback
wlr_gamma_control_v1_apply(nullptr, &pMonitor->outputState);
wlr_gamma_control_v1_apply(nullptr, pMonitor->state.wlr());
wlr_gamma_control_v1_send_failed_and_destroy(PGAMMACTRL);
}
}
@@ -1151,6 +1151,8 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
if (UNLOCK_SC)
wlr_output_lock_software_cursors(pMonitor->output, false);
pMonitor->state.clear();
return;
}
@@ -1237,20 +1239,16 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
EMIT_HOOK_EVENT("render", RENDER_POST);
pMonitor->outputState.tearing_page_flip = shouldTear;
pMonitor->state.wlr()->tearing_page_flip = shouldTear;
if (!wlr_output_commit_state(pMonitor->output, &pMonitor->outputState)) {
if (!pMonitor->state.commit()) {
if (UNLOCK_SC)
wlr_output_lock_software_cursors(pMonitor->output, false);
pMonitor->clearState();
return;
}
pMonitor->clearState();
if (shouldTear)
pMonitor->tearingState.busy = true;
@@ -1342,7 +1340,7 @@ void CHyprRenderer::outputMgrApplyTest(wlr_output_configuration_v1* config, bool
continue;
}
wlr_output_state_set_enabled(&PMONITOR->outputState, head->state.enabled);
wlr_output_state_set_enabled(PMONITOR->state.wlr(), head->state.enabled);
if (head->state.mode)
commandForCfg +=
@@ -1356,10 +1354,10 @@ void CHyprRenderer::outputMgrApplyTest(wlr_output_configuration_v1* config, bool
if (!test) {
g_pConfigManager->parseKeyword("monitor", commandForCfg, true);
wlr_output_state_set_adaptive_sync_enabled(&PMONITOR->outputState, head->state.adaptive_sync_enabled);
wlr_output_state_set_adaptive_sync_enabled(PMONITOR->state.wlr(), head->state.adaptive_sync_enabled);
}
ok = wlr_output_test_state(OUTPUT, &PMONITOR->outputState);
ok = wlr_output_test_state(OUTPUT, PMONITOR->state.wlr());
if (!ok)
break;
@@ -1769,10 +1767,10 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
pMonitor->scale = DEFAULTSCALE;
}
wlr_output_state_set_scale(&pMonitor->outputState, pMonitor->scale);
wlr_output_state_set_scale(pMonitor->state.wlr(), pMonitor->scale);
pMonitor->setScale = pMonitor->scale;
wlr_output_state_set_transform(&pMonitor->outputState, pMonitorRule->transform);
wlr_output_state_set_transform(pMonitor->state.wlr(), pMonitorRule->transform);
pMonitor->transform = pMonitorRule->transform;
const auto WLRREFRESHRATE = (wlr_backend_is_wl(pMonitor->output->backend) || wlr_backend_is_x11(pMonitor->output->backend)) ? 0 : pMonitorRule->refreshRate * 1000;
@@ -1787,9 +1785,9 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
// if delta of refresh rate, w and h chosen and mode is < 1 we accept it
if (DELTALESSTHAN(mode->width, pMonitorRule->resolution.x, 1) && DELTALESSTHAN(mode->height, pMonitorRule->resolution.y, 1) &&
DELTALESSTHAN(mode->refresh / 1000.f, pMonitorRule->refreshRate, 1)) {
wlr_output_state_set_mode(&pMonitor->outputState, mode);
wlr_output_state_set_mode(pMonitor->state.wlr(), mode);
if (!wlr_output_test_state(pMonitor->output, &pMonitor->outputState)) {
if (!wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) {
Debug::log(LOG, "Monitor {}: REJECTED available mode: {}x{}@{:2f}!", pMonitor->output->name, mode->width, mode->height, mode->refresh / 1000.f);
continue;
}
@@ -1807,11 +1805,11 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
}
if (!found) {
wlr_output_state_set_custom_mode(&pMonitor->outputState, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, WLRREFRESHRATE);
wlr_output_state_set_custom_mode(pMonitor->state.wlr(), (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, WLRREFRESHRATE);
pMonitor->vecSize = pMonitorRule->resolution;
pMonitor->refreshRate = pMonitorRule->refreshRate;
if (!wlr_output_test_state(pMonitor->output, &pMonitor->outputState)) {
if (!wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) {
Debug::log(ERR, "Custom resolution FAILED, falling back to preferred");
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
@@ -1823,7 +1821,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
}
// Preferred is valid
wlr_output_state_set_mode(&pMonitor->outputState, PREFERREDMODE);
wlr_output_state_set_mode(pMonitor->state.wlr(), PREFERREDMODE);
Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name,
pMonitorRule->resolution, (float)pMonitorRule->refreshRate, PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f);
@@ -1845,7 +1843,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
} else {
auto* mode = wlr_drm_connector_add_mode(pMonitor->output, &pMonitorRule->drmMode);
if (mode) {
wlr_output_state_set_mode(&pMonitor->outputState, mode);
wlr_output_state_set_mode(pMonitor->state.wlr(), mode);
pMonitor->customDrmMode = pMonitorRule->drmMode;
} else {
Debug::log(ERR, "wlr_drm_connector_add_mode failed");
@@ -1853,13 +1851,13 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
}
}
} else {
wlr_output_state_set_custom_mode(&pMonitor->outputState, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, WLRREFRESHRATE);
wlr_output_state_set_custom_mode(pMonitor->state.wlr(), (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, WLRREFRESHRATE);
}
pMonitor->vecSize = pMonitorRule->resolution;
pMonitor->refreshRate = pMonitorRule->refreshRate;
if (fail || !wlr_output_test_state(pMonitor->output, &pMonitor->outputState)) {
if (fail || !wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) {
Debug::log(ERR, "Custom resolution FAILED, falling back to preferred");
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
@@ -1871,7 +1869,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
}
// Preferred is valid
wlr_output_state_set_mode(&pMonitor->outputState, PREFERREDMODE);
wlr_output_state_set_mode(pMonitor->state.wlr(), PREFERREDMODE);
Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name,
pMonitorRule->resolution, (float)pMonitorRule->refreshRate, PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f);
@@ -1895,8 +1893,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
if (pMonitorRule->resolution == Vector2D(-1, -1)) {
wl_list_for_each(mode, &pMonitor->output->modes, link) {
if ((mode->width >= currentWidth && mode->height >= currentHeight && mode->refresh >= (currentRefresh - 1000.f)) || mode->refresh > (currentRefresh + 3000.f)) {
wlr_output_state_set_mode(&pMonitor->outputState, mode);
if (wlr_output_test_state(pMonitor->output, &pMonitor->outputState)) {
wlr_output_state_set_mode(pMonitor->state.wlr(), mode);
if (wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) {
currentWidth = mode->width;
currentHeight = mode->height;
currentRefresh = mode->refresh;
@@ -1908,8 +1906,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
wl_list_for_each(mode, &pMonitor->output->modes, link) {
if ((mode->width >= currentWidth && mode->height >= currentHeight && mode->refresh >= (currentRefresh - 1000.f)) ||
(mode->width > currentWidth && mode->height > currentHeight)) {
wlr_output_state_set_mode(&pMonitor->outputState, mode);
if (wlr_output_test_state(pMonitor->output, &pMonitor->outputState)) {
wlr_output_state_set_mode(pMonitor->state.wlr(), mode);
if (wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) {
currentWidth = mode->width;
currentHeight = mode->height;
currentRefresh = mode->refresh;
@@ -1932,7 +1930,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
}
// Preferred is valid
wlr_output_state_set_mode(&pMonitor->outputState, PREFERREDMODE);
wlr_output_state_set_mode(pMonitor->state.wlr(), PREFERREDMODE);
Debug::log(ERR, "Monitor {} got an invalid requested mode: {:X0}@{:2f}, using the preferred one instead: {}x{}@{:2f}", pMonitor->output->name,
pMonitorRule->resolution, (float)pMonitorRule->refreshRate, PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f);
@@ -1957,9 +1955,9 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
wlr_output_mode* mode;
wl_list_for_each(mode, &pMonitor->output->modes, link) {
wlr_output_state_set_mode(&pMonitor->outputState, mode);
wlr_output_state_set_mode(pMonitor->state.wlr(), mode);
if (!wlr_output_test_state(pMonitor->output, &pMonitor->outputState)) {
if (!wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) {
Debug::log(LOG, "Monitor {}: REJECTED available mode: {}x{}@{:2f}!", pMonitor->output->name, mode->width, mode->height, mode->refresh / 1000.f);
continue;
}
@@ -1975,7 +1973,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
}
} else {
// Preferred is valid
wlr_output_state_set_mode(&pMonitor->outputState, PREFERREDMODE);
wlr_output_state_set_mode(pMonitor->state.wlr(), PREFERREDMODE);
pMonitor->vecSize = Vector2D(PREFERREDMODE->width, PREFERREDMODE->height);
pMonitor->refreshRate = PREFERREDMODE->refresh / 1000.f;
@@ -1984,8 +1982,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
}
}
pMonitor->vrrActive = pMonitor->outputState.adaptive_sync_enabled // disabled here, will be tested in CConfigManager::ensureVRR()
|| pMonitor->createdByUser; // wayland backend doesn't allow for disabling adaptive_sync
pMonitor->vrrActive = pMonitor->state.wlr()->adaptive_sync_enabled // disabled here, will be tested in CConfigManager::ensureVRR()
|| pMonitor->createdByUser; // wayland backend doesn't allow for disabling adaptive_sync
pMonitor->vecPixelSize = pMonitor->vecSize;
@@ -2002,7 +2000,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
Vector2D logicalZero = pMonitor->vecPixelSize / scaleZero;
if (logicalZero == logicalZero.round()) {
pMonitor->scale = scaleZero;
wlr_output_state_set_scale(&pMonitor->outputState, pMonitor->scale);
wlr_output_state_set_scale(pMonitor->state.wlr(), pMonitor->scale);
} else {
for (size_t i = 1; i < 90; ++i) {
double scaleUp = (searchScale + i) / 120.0;
@@ -2045,7 +2043,7 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
double logicalX = std::round(pMonitor->vecPixelSize.x / pMonitor->scale);
logicalX += 0.1;
wlr_output_state_set_scale(&pMonitor->outputState, pMonitor->vecPixelSize.x / logicalX);
wlr_output_state_set_scale(pMonitor->state.wlr(), pMonitor->vecPixelSize.x / logicalX);
}
}
@@ -2064,9 +2062,9 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
pMonitor->drmFormat = DRM_FORMAT_INVALID;
for (auto& fmt : formats[(int)!pMonitorRule->enable10bit]) {
wlr_output_state_set_render_format(&pMonitor->outputState, fmt.second);
wlr_output_state_set_render_format(pMonitor->state.wlr(), fmt.second);
if (!wlr_output_test_state(pMonitor->output, &pMonitor->outputState)) {
if (!wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) {
Debug::log(ERR, "output {} failed basic test on format {}", pMonitor->szName, fmt.first);
} else {
Debug::log(LOG, "output {} succeeded basic test on format {}", pMonitor->szName, fmt.first);
@@ -2080,11 +2078,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
pMonitor->enabled10bit = set10bit;
if (!wlr_output_commit_state(pMonitor->output, &pMonitor->outputState)) {
if (!pMonitor->state.commit())
Debug::log(ERR, "Couldn't commit output named {}", pMonitor->output->name);
}
pMonitor->clearState();
int x, y;
wlr_output_transformed_resolution(pMonitor->output, &x, &y);
@@ -2449,7 +2444,7 @@ bool CHyprRenderer::beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode
}
if (!buffer) {
if (!wlr_output_configure_primary_swapchain(pMonitor->output, &pMonitor->outputState, &pMonitor->output->swapchain))
if (!wlr_output_configure_primary_swapchain(pMonitor->output, pMonitor->state.wlr(), &pMonitor->output->swapchain))
return false;
m_pCurrentWlrBuffer = wlr_swapchain_acquire(pMonitor->output->swapchain, &m_iLastBufferAge);
@@ -2493,7 +2488,7 @@ void CHyprRenderer::endRender() {
glFlush();
if (m_eRenderMode == RENDER_MODE_NORMAL) {
wlr_output_state_set_buffer(&PMONITOR->outputState, m_pCurrentWlrBuffer);
wlr_output_state_set_buffer(PMONITOR->state.wlr(), m_pCurrentWlrBuffer);
unsetEGL(); // flush the context
}