opengl: simplify cm pipeline

fixes a few mistakes, and skips the CM shader in cpu instead of adding a costly branch

ref #9641
This commit is contained in:
Vaxry 2025-03-16 21:50:15 +00:00
parent 2ddd16ef28
commit 22154fa272
3 changed files with 73 additions and 80 deletions

View file

@ -875,7 +875,6 @@ void CHyprOpenGLImpl::initShaders() {
m_RenderData.pCurrentMonData->m_shCM.proj = glGetUniformLocation(prog, "proj"); m_RenderData.pCurrentMonData->m_shCM.proj = glGetUniformLocation(prog, "proj");
m_RenderData.pCurrentMonData->m_shCM.tex = glGetUniformLocation(prog, "tex"); m_RenderData.pCurrentMonData->m_shCM.tex = glGetUniformLocation(prog, "tex");
m_RenderData.pCurrentMonData->m_shCM.texType = glGetUniformLocation(prog, "texType"); m_RenderData.pCurrentMonData->m_shCM.texType = glGetUniformLocation(prog, "texType");
m_RenderData.pCurrentMonData->m_shCM.skipCM = glGetUniformLocation(prog, "skipCM");
m_RenderData.pCurrentMonData->m_shCM.sourceTF = glGetUniformLocation(prog, "sourceTF"); m_RenderData.pCurrentMonData->m_shCM.sourceTF = glGetUniformLocation(prog, "sourceTF");
m_RenderData.pCurrentMonData->m_shCM.targetTF = glGetUniformLocation(prog, "targetTF"); m_RenderData.pCurrentMonData->m_shCM.targetTF = glGetUniformLocation(prog, "targetTF");
m_RenderData.pCurrentMonData->m_shCM.sourcePrimaries = glGetUniformLocation(prog, "sourcePrimaries"); m_RenderData.pCurrentMonData->m_shCM.sourcePrimaries = glGetUniformLocation(prog, "sourcePrimaries");
@ -1352,11 +1351,6 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
shader = &m_RenderData.pCurrentMonData->m_shPASSTHRURGBA; shader = &m_RenderData.pCurrentMonData->m_shPASSTHRURGBA;
usingFinalShader = true; usingFinalShader = true;
} else { } else {
#ifndef GLES2
if (m_bCMSupported)
shader = &m_RenderData.pCurrentMonData->m_shCM;
else
#endif
switch (tex->m_iType) { switch (tex->m_iType) {
case TEXTURE_RGBA: shader = &m_RenderData.pCurrentMonData->m_shRGBA; break; case TEXTURE_RGBA: shader = &m_RenderData.pCurrentMonData->m_shRGBA; break;
case TEXTURE_RGBX: shader = &m_RenderData.pCurrentMonData->m_shRGBX; break; case TEXTURE_RGBX: shader = &m_RenderData.pCurrentMonData->m_shRGBX; break;
@ -1367,12 +1361,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
} }
} }
if (m_RenderData.currentWindow && m_RenderData.currentWindow->m_sWindowData.RGBX.valueOrDefault()) { if (m_RenderData.currentWindow && m_RenderData.currentWindow->m_sWindowData.RGBX.valueOrDefault())
#ifdef GLES2
shader = &m_RenderData.pCurrentMonData->m_shRGBX;
#endif
texType = TEXTURE_RGBX; texType = TEXTURE_RGBX;
}
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(tex->m_iTarget, tex->m_iTexID); glBindTexture(tex->m_iTarget, tex->m_iTexID);
@ -1388,22 +1378,18 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
glTexParameteri(tex->m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(tex->m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} }
const bool skipCM = !m_RenderData.surface /* No surface - no point in CM */
|| !m_bCMSupported /* CM unsupported - hw failed to compile the shader probably */
|| (*PPASS && m_RenderData.pMonitor->activeWorkspace && m_RenderData.pMonitor->activeWorkspace->m_bHasFullscreenWindow &&
m_RenderData.pMonitor->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN) /* Fullscreen window with pass cm enabled */;
glUseProgram(shader->program); glUseProgram(shader->program);
#ifndef GLES2 #ifndef GLES2
glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix.getMatrix().data()); if (!skipCM && !usingFinalShader && (texType == TEXTURE_RGBA || texType == TEXTURE_RGBX)) {
#else shader = &m_RenderData.pCurrentMonData->m_shCM;
glMatrix.transpose(); glUseProgram(shader->program);
glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix.getMatrix().data());
#endif
glUniform1i(shader->tex, 0);
#ifndef GLES2
if (shader == &m_RenderData.pCurrentMonData->m_shCM && !usingFinalShader && (texType == TEXTURE_RGBA || texType == TEXTURE_RGBX)) {
const bool skipCM = *PPASS && m_RenderData.pMonitor->activeWorkspace && m_RenderData.pMonitor->activeWorkspace->m_bHasFullscreenWindow &&
m_RenderData.pMonitor->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN;
glUniform1i(shader->texType, texType); glUniform1i(shader->texType, texType);
glUniform1i(shader->skipCM, skipCM);
if (!skipCM) {
const auto imageDescription = const auto imageDescription =
m_RenderData.surface.valid() && m_RenderData.surface->colorManagement.valid() ? m_RenderData.surface->colorManagement->imageDescription() : SImageDescription{}; m_RenderData.surface.valid() && m_RenderData.surface->colorManagement.valid() ? m_RenderData.surface->colorManagement->imageDescription() : SImageDescription{};
glUniform1i(shader->sourceTF, imageDescription.transferFunction); glUniform1i(shader->sourceTF, imageDescription.transferFunction);
@ -1438,9 +1424,16 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB
m_RenderData.pMonitor->sdrBrightness : m_RenderData.pMonitor->sdrBrightness :
1.0f); 1.0f);
} }
}
#endif #endif
#ifndef GLES2
glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix.getMatrix().data());
#else
glMatrix.transpose();
glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix.getMatrix().data());
#endif
glUniform1i(shader->tex, 0);
if ((usingFinalShader && *PDT == 0) || CRASHING) { if ((usingFinalShader && *PDT == 0) || CRASHING) {
glUniform1f(shader->time, m_tGlobalTimer.getSeconds() - shader->initialTime); glUniform1f(shader->time, m_tGlobalTimer.getSeconds() - shader->initialTime);
} else if (usingFinalShader && shader->time != -1) { } else if (usingFinalShader && shader->time != -1) {

View file

@ -12,7 +12,6 @@ class CShader {
GLint color = -1; GLint color = -1;
GLint alphaMatte = -1; GLint alphaMatte = -1;
GLint texType = -1; GLint texType = -1;
GLint skipCM = -1;
GLint sourceTF = -1; GLint sourceTF = -1;
GLint targetTF = -1; GLint targetTF = -1;
GLint sourcePrimaries = -1; GLint sourcePrimaries = -1;

View file

@ -8,7 +8,6 @@ uniform sampler2D tex;
//uniform samplerExternalOES texture0; //uniform samplerExternalOES texture0;
uniform int texType; // eTextureType: 0 - rgba, 1 - rgbx, 2 - ext uniform int texType; // eTextureType: 0 - rgba, 1 - rgbx, 2 - ext
uniform int skipCM;
uniform int sourceTF; // eTransferFunction uniform int sourceTF; // eTransferFunction
uniform int targetTF; // eTransferFunction uniform int targetTF; // eTransferFunction
uniform mat4x2 sourcePrimaries; uniform mat4x2 sourcePrimaries;
@ -408,25 +407,27 @@ void main() {
if (discardAlpha == 1 && pixColor[3] <= discardAlphaValue) if (discardAlpha == 1 && pixColor[3] <= discardAlphaValue)
discard; discard;
if (skipCM == 0) {
pixColor.rgb /= max(pixColor.a, 0.001); pixColor.rgb /= max(pixColor.a, 0.001);
pixColor.rgb = toLinearRGB(pixColor.rgb, sourceTF); pixColor.rgb = toLinearRGB(pixColor.rgb, sourceTF);
mat3 srcxyz = primaries2xyz(sourcePrimaries); mat3 srcxyz = primaries2xyz(sourcePrimaries);
mat3 dstxyz; mat3 dstxyz;
if (sourcePrimaries == targetPrimaries) if (sourcePrimaries == targetPrimaries)
dstxyz = srcxyz; dstxyz = srcxyz;
else { else {
dstxyz = primaries2xyz(targetPrimaries); dstxyz = primaries2xyz(targetPrimaries);
pixColor = convertPrimaries(pixColor, srcxyz, sourcePrimaries[3], dstxyz, targetPrimaries[3]); pixColor = convertPrimaries(pixColor, srcxyz, sourcePrimaries[3], dstxyz, targetPrimaries[3]);
} }
pixColor = toNit(pixColor, sourceTF); pixColor = toNit(pixColor, sourceTF);
pixColor.rgb *= pixColor.a; pixColor.rgb *= pixColor.a;
pixColor = tonemap(pixColor, dstxyz); pixColor = tonemap(pixColor, dstxyz);
if (sourceTF == CM_TRANSFER_FUNCTION_SRGB && targetTF == CM_TRANSFER_FUNCTION_ST2084_PQ) if (sourceTF == CM_TRANSFER_FUNCTION_SRGB && targetTF == CM_TRANSFER_FUNCTION_ST2084_PQ)
pixColor = saturate(pixColor, srcxyz, sdrSaturation); pixColor = saturate(pixColor, srcxyz, sdrSaturation);
pixColor *= sdrBrightnessMultiplier; pixColor *= sdrBrightnessMultiplier;
pixColor = fromLinearNit(pixColor, targetTF); pixColor = fromLinearNit(pixColor, targetTF);
}
if (applyTint == 1) if (applyTint == 1)
pixColor = vec4(pixColor.rgb * tint.rgb, pixColor[3]); pixColor = vec4(pixColor.rgb * tint.rgb, pixColor[3]);