summaryrefslogtreecommitdiff
path: root/src/render/Renderer.cpp
diff options
context:
space:
mode:
authorUjinT34 <41110182+UjinT34@users.noreply.github.com>2026-04-16 21:19:25 +0300
committerGitHub <noreply@github.com>2026-04-16 19:19:25 +0100
commit66ea2e2c9ed4e9257521e6706fbd21feb7e3cc5b (patch)
tree6c0c9842245917e9828874263cd11d6f556a0a48 /src/render/Renderer.cpp
parent4cce7f60a9c8772d18ffb43cb74aa227ab4b3bc4 (diff)
renderer: Various CM fixes, part 8 of refactors (#13860)
Part 8 of Ujin's refactors.
Diffstat (limited to 'src/render/Renderer.cpp')
-rw-r--r--src/render/Renderer.cpp105
1 files changed, 69 insertions, 36 deletions
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index ba82fa15..df1106b0 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -53,6 +53,7 @@
#include "Texture.hpp"
#include "./pass/PreBlurElement.hpp"
#include "types.hpp"
+#include <hyprgraphics/color/Color.hpp>
#include <hyprutils/math/Mat3x3.hpp>
#include <hyprutils/math/Region.hpp>
#include <hyprutils/math/Vector2D.hpp>
@@ -1514,7 +1515,7 @@ SP<ITexture> IHyprRenderer::renderText(const std::string& text, CHyprColor col,
cairo_surface_flush(CAIROSURFACE);
- auto tex = createTexture(cairo_image_surface_get_width(CAIROSURFACE), cairo_image_surface_get_height(CAIROSURFACE), cairo_image_surface_get_data(CAIROSURFACE));
+ auto tex = createTexture(CAIROSURFACE);
cairo_destroy(CAIRO);
cairo_surface_destroy(CAIROSURFACE);
@@ -1779,10 +1780,10 @@ void IHyprRenderer::clearCMSettingsCache() {
}
SCMSettings IHyprRenderer::getCMSettings(const NColorManagement::PImageDescription imageDescription, const NColorManagement::PImageDescription targetImageDescription,
- SP<CWLSurfaceResource> surface, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance) {
+ SP<CWLSurfaceResource> surface, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance, bool shouldUseSurface) {
const auto srcId = imageDescription->id();
const auto dstId = targetImageDescription->id();
- void* sPtr = m_renderData.surface.get();
+ void* sPtr = shouldUseSurface ? m_renderData.surface.get() : nullptr;
for (auto const& entry : m_cmSettingsCache) {
if (entry.srcDescId == srcId && entry.dstDescId == dstId && entry.surfacePtr == sPtr && entry.modifySDR == modifySDR && entry.sdrMinLuminance == sdrMinLuminance &&
@@ -1793,7 +1794,8 @@ SCMSettings IHyprRenderer::getCMSettings(const NColorManagement::PImageDescripti
const auto sdrEOTF = NTransferFunction::fromConfig();
NColorManagement::eTransferFunction srcTF;
- if (m_renderData.surface.valid()) {
+ if (shouldUseSurface && m_renderData.surface.valid() &&
+ (imageDescription->value().transferFunction == CM_TRANSFER_FUNCTION_GAMMA22 || imageDescription->value().transferFunction == CM_TRANSFER_FUNCTION_SRGB)) {
if (m_renderData.surface->m_colorManagement.valid()) {
if (sdrEOTF == NTransferFunction::TF_FORCED_GAMMA22 && imageDescription->value().transferFunction == NColorManagement::eTransferFunction::CM_TRANSFER_FUNCTION_SRGB)
srcTF = NColorManagement::eTransferFunction::CM_TRANSFER_FUNCTION_GAMMA22;
@@ -1842,7 +1844,15 @@ SCMSettings IHyprRenderer::getCMSettings(const NColorManagement::PImageDescripti
.sdrBrightnessMultiplier = needsSDRmod && m_renderData.pMonitor->m_sdrBrightness > 0 ? m_renderData.pMonitor->m_sdrBrightness : 1.0f,
};
- m_cmSettingsCache.push_back({srcId, dstId, sPtr, modifySDR, sdrMinLuminance, sdrMaxLuminance, result});
+ m_cmSettingsCache.push_back({
+ .srcDescId = srcId,
+ .dstDescId = dstId,
+ .surfacePtr = sPtr,
+ .modifySDR = modifySDR,
+ .sdrMinLuminance = sdrMinLuminance,
+ .sdrMaxLuminance = sdrMaxLuminance,
+ .settings = result,
+ });
return result;
}
@@ -1937,11 +1947,16 @@ void IHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) {
if (canAttemptDirectScanout) {
if (pMonitor->attemptDirectScanout()) {
- pMonitor->m_directScanoutIsActive = true;
+ if (!pMonitor->m_directScanoutIsActive) {
+ pMonitor->m_previousFSWindow.reset(); // recalc fs settings
+ pMonitor->m_directScanoutIsActive = true;
+ }
+ handleFullscreenSettings(pMonitor);
return;
} else if (!pMonitor->m_lastScanout.expired() || pMonitor->m_directScanoutIsActive) {
Log::logger->log(Log::DEBUG, "Left a direct scanout.");
pMonitor->m_lastScanout.reset();
+ pMonitor->m_previousFSWindow.reset(); // recalc fs settings
pMonitor->m_directScanoutIsActive = false;
// reset DRM format, but only if needed since it might modeset
@@ -2183,11 +2198,11 @@ static hdr_output_metadata createHDRMetadata(SImageDescription settings, S
};
}
-bool IHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
+void IHyprRenderer::handleFullscreenSettings(PHLMONITOR pMonitor) {
static auto PCT = CConfigValue<Hyprlang::INT>("render:send_content_type");
- static auto PPASS = CConfigValue<Hyprlang::INT>("render:cm_fs_passthrough");
static auto PAUTOHDR = CConfigValue<Hyprlang::INT>("render:cm_auto_hdr");
static auto PNONSHADER = CConfigValue<Hyprlang::INT>("render:non_shader_cm");
+ static auto PNSINTEROP = CConfigValue<Hyprlang::INT>("render:non_shader_cm_interop");
const bool configuredHDR = (pMonitor->m_cmType == NCMType::CM_HDR_EDID || pMonitor->m_cmType == NCMType::CM_HDR);
bool wantHDR = configuredHDR;
@@ -2198,14 +2213,6 @@ bool IHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
// HDR metadata determined by
// HDR scRGB - monitor settings
// HDR PQ surface & DS is active - surface settings
- // PPASS = 0 monitor settings
- // PPASS = 1
- // windowed: monitor settings
- // fullscreen surface: surface settings FIXME: fullscreen SDR surface passthrough - pass degamma, gamma if needed
- // PPASS = 2
- // windowed: monitor settings
- // fullscreen SDR surface: monitor settings
- // fullscreen HDR surface: surface settings
bool hdrIsHandled = false;
if (FS_WINDOW) {
@@ -2215,8 +2222,9 @@ bool IHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
// we have a surface with image description
if (SURF && SURF->m_colorManagement.valid() && SURF->m_colorManagement->hasImageDescription()) {
const bool surfaceIsHDR = SURF->m_colorManagement->isHDR();
- if (!SURF->m_colorManagement->isWindowsScRGB() && (*PPASS == 1 || ((*PPASS == 2 || !pMonitor->m_lastScanout.expired()) && surfaceIsHDR))) {
- // passthrough
+ wantHDR = *PAUTOHDR && surfaceIsHDR;
+ if (surfaceIsHDR && !SURF->m_colorManagement->isWindowsScRGB() && !pMonitor->m_lastScanout.expired()) {
+ // DS HDR
bool needsHdrMetadataUpdate = SURF->m_colorManagement->needsHdrMetadataUpdate() || pMonitor->m_previousFSWindow != FS_WINDOW || pMonitor->m_needsHDRupdate;
if (SURF->m_colorManagement->needsHdrMetadataUpdate()) {
Log::logger->log(Log::INFO, "[CM] Recreating HDR metadata for surface");
@@ -2228,8 +2236,7 @@ bool IHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
}
hdrIsHandled = true;
pMonitor->m_needsHDRupdate = false;
- } else if (*PAUTOHDR && surfaceIsHDR)
- wantHDR = true; // auto-hdr: hdr on
+ }
}
}
@@ -2271,28 +2278,50 @@ bool IHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
if (*PCT)
pMonitor->m_output->state->setContentType(NContentType::toDRM(FS_WINDOW ? FS_WINDOW->getContentType() : CONTENT_TYPE_NONE));
- if (FS_WINDOW != pMonitor->m_previousFSWindow || (!FS_WINDOW && pMonitor->m_noShaderCTM)) {
- if (*PNONSHADER == CM_NS_IGNORE || !FS_WINDOW || !pMonitor->needsCM() || !pMonitor->canNoShaderCM() ||
- (*PNONSHADER == CM_NS_ONDEMAND && pMonitor->m_lastScanout.expired() && *PPASS != 1)) {
- if (pMonitor->m_noShaderCTM) {
- Log::logger->log(Log::INFO, "[CM] No fullscreen CTM, restoring previous one");
- pMonitor->m_noShaderCTM = false;
- pMonitor->m_ctmUpdated = true;
- }
- } else {
- const auto FS_DESC = pMonitor->getFSImageDescription();
- if (FS_DESC.has_value()) {
+ if (FS_WINDOW != pMonitor->m_previousFSWindow || (!FS_WINDOW && pMonitor->m_noShaderCTM) || pMonitor->m_ctmUpdated) {
+ const bool INTEROP = (*PNSINTEROP == 1 || (*PNSINTEROP == 2 && FS_WINDOW && FS_WINDOW->getContentType() == CONTENT_TYPE_NONE));
+ bool resetCTM = !FS_WINDOW;
+ if (FS_WINDOW) {
+ if (*PNONSHADER == CM_NS_IGNORE)
+ resetCTM = true;
+ else if (const auto FS_DESC = pMonitor->getFSImageDescription(); pMonitor->needsCM() && pMonitor->canNoShaderCM(!pMonitor->m_lastScanout.expired()) &&
+ FS_DESC.has_value() && (*PNONSHADER != CM_NS_ONDEMAND || !pMonitor->m_lastScanout.expired())) {
Log::logger->log(Log::INFO, "[CM] Updating fullscreen CTM");
- pMonitor->m_noShaderCTM = true;
- auto conversion = FS_DESC.value()->getPrimaries()->convertMatrix(pMonitor->m_imageDescription->getPrimaries());
- const auto mat = conversion.mat();
- const std::array<float, 9> CTM = {
+ pMonitor->m_noShaderCTM = true;
+ pMonitor->m_ctmUpdated = false;
+ auto conversion = FS_DESC.value()->getPrimaries()->convertMatrix(pMonitor->m_imageDescription->getPrimaries());
+ if (pMonitor->m_ctm != Mat3x3::identity() && INTEROP) {
+ const auto& ctm = pMonitor->m_ctm.getMatrix();
+ std::array<std::array<double, 3>, 3> values = {
+ {
+ {ctm[0], ctm[1], ctm[2]},
+ {ctm[3], ctm[4], ctm[5]},
+ {ctm[6], ctm[7], ctm[8]},
+ },
+ };
+ conversion = conversion * Hyprgraphics::CMatrix3(values);
+ }
+ const auto mat = conversion.mat();
+ const std::array<float, 9> CTM = {
mat[0][0], mat[0][1], mat[0][2], //
mat[1][0], mat[1][1], mat[1][2], //
mat[2][0], mat[2][1], mat[2][2], //
};
pMonitor->m_output->state->setCTM(CTM);
- }
+ } else if (!INTEROP && pMonitor->m_ctm != Mat3x3::identity()) {
+ Log::logger->log(Log::INFO, "[CM] Setting identity CTM");
+ pMonitor->m_noShaderCTM = true;
+ pMonitor->m_ctmUpdated = false;
+
+ pMonitor->m_output->state->setCTM(Mat3x3::identity());
+ } else
+ resetCTM = true;
+ }
+
+ if (resetCTM && pMonitor->m_noShaderCTM) {
+ Log::logger->log(Log::INFO, "[CM] No fullscreen CTM, restoring previous one");
+ pMonitor->m_noShaderCTM = false;
+ pMonitor->m_ctmUpdated = true;
}
}
@@ -2302,6 +2331,10 @@ bool IHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
}
pMonitor->m_previousFSWindow = FS_WINDOW;
+}
+
+bool IHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
+ handleFullscreenSettings(pMonitor);
bool ok = pMonitor->m_state.commit();
if (!ok) {