mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-06 15:11:57 -07:00
cm: Use precomputed primaries conversion (#9814)
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
#include <GLES3/gl32.h>
|
||||
#include <hyprgraphics/color/Color.hpp>
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <hyprutils/path/Path.hpp>
|
||||
#include <random>
|
||||
@@ -908,13 +910,15 @@ static void getCMShaderUniforms(CShader& shader) {
|
||||
shader.skipCM = glGetUniformLocation(shader.program, "skipCM");
|
||||
shader.sourceTF = glGetUniformLocation(shader.program, "sourceTF");
|
||||
shader.targetTF = glGetUniformLocation(shader.program, "targetTF");
|
||||
shader.sourcePrimaries = glGetUniformLocation(shader.program, "sourcePrimaries");
|
||||
shader.srcTFRange = glGetUniformLocation(shader.program, "srcTFRange");
|
||||
shader.dstTFRange = glGetUniformLocation(shader.program, "dstTFRange");
|
||||
shader.targetPrimaries = glGetUniformLocation(shader.program, "targetPrimaries");
|
||||
shader.maxLuminance = glGetUniformLocation(shader.program, "maxLuminance");
|
||||
shader.dstMaxLuminance = glGetUniformLocation(shader.program, "dstMaxLuminance");
|
||||
shader.dstRefLuminance = glGetUniformLocation(shader.program, "dstRefLuminance");
|
||||
shader.sdrSaturation = glGetUniformLocation(shader.program, "sdrSaturation");
|
||||
shader.sdrBrightness = glGetUniformLocation(shader.program, "sdrBrightnessMultiplier");
|
||||
shader.convertMatrix = glGetUniformLocation(shader.program, "convertMatrix");
|
||||
}
|
||||
|
||||
// shader has #include "rounding.glsl"
|
||||
@@ -1437,27 +1441,26 @@ void CHyprOpenGLImpl::renderTextureWithDamage(SP<CTexture> tex, const CBox& box,
|
||||
scissor(nullptr);
|
||||
}
|
||||
|
||||
static std::map<std::pair<uint32_t, uint32_t>, std::array<GLfloat, 9>> primariesConversionCache;
|
||||
|
||||
void CHyprOpenGLImpl::passCMUniforms(const CShader& shader, const NColorManagement::SImageDescription& imageDescription,
|
||||
const NColorManagement::SImageDescription& targetImageDescription, bool modifySDR) {
|
||||
glUniform1i(shader.sourceTF, imageDescription.transferFunction);
|
||||
glUniform1i(shader.targetTF, targetImageDescription.transferFunction);
|
||||
const auto sourcePrimaries =
|
||||
imageDescription.primariesNameSet || imageDescription.primaries == SPCPRimaries{} ? getPrimaries(imageDescription.primariesNamed) : imageDescription.primaries;
|
||||
|
||||
const auto targetPrimaries = targetImageDescription.primariesNameSet || targetImageDescription.primaries == SPCPRimaries{} ?
|
||||
getPrimaries(targetImageDescription.primariesNamed) :
|
||||
targetImageDescription.primaries;
|
||||
|
||||
const GLfloat glSourcePrimaries[8] = {
|
||||
sourcePrimaries.red.x, sourcePrimaries.red.y, sourcePrimaries.green.x, sourcePrimaries.green.y,
|
||||
sourcePrimaries.blue.x, sourcePrimaries.blue.y, sourcePrimaries.white.x, sourcePrimaries.white.y,
|
||||
};
|
||||
const GLfloat glTargetPrimaries[8] = {
|
||||
targetPrimaries.red.x, targetPrimaries.red.y, targetPrimaries.green.x, targetPrimaries.green.y,
|
||||
targetPrimaries.blue.x, targetPrimaries.blue.y, targetPrimaries.white.x, targetPrimaries.white.y,
|
||||
};
|
||||
glUniformMatrix4x2fv(shader.sourcePrimaries, 1, false, glSourcePrimaries);
|
||||
glUniformMatrix4x2fv(shader.targetPrimaries, 1, false, glTargetPrimaries);
|
||||
|
||||
glUniform2f(shader.srcTFRange, imageDescription.getTFMinLuminance(), imageDescription.getTFMaxLuminance());
|
||||
glUniform2f(shader.dstTFRange, targetImageDescription.getTFMinLuminance(), targetImageDescription.getTFMaxLuminance());
|
||||
|
||||
const float maxLuminance = imageDescription.luminances.max > 0 ? imageDescription.luminances.max : imageDescription.luminances.reference;
|
||||
glUniform1f(shader.maxLuminance, maxLuminance * targetImageDescription.luminances.reference / imageDescription.luminances.reference);
|
||||
glUniform1f(shader.dstMaxLuminance, targetImageDescription.luminances.max > 0 ? targetImageDescription.luminances.max : 10000);
|
||||
@@ -1469,7 +1472,19 @@ void CHyprOpenGLImpl::passCMUniforms(const CShader& shader, const NColorManageme
|
||||
glUniform1f(shader.sdrBrightness,
|
||||
modifySDR && m_RenderData.pMonitor->sdrBrightness > 0 && targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ?
|
||||
m_RenderData.pMonitor->sdrBrightness :
|
||||
|
||||
1.0f);
|
||||
const auto cacheKey = std::make_pair(imageDescription.getId(), targetImageDescription.getId());
|
||||
if (!primariesConversionCache.contains(cacheKey)) {
|
||||
const auto mat = imageDescription.getPrimaries().convertMatrix(targetImageDescription.getPrimaries()).mat();
|
||||
const std::array<GLfloat, 9> glConvertMatrix = {
|
||||
mat[0][0], mat[1][0], mat[2][0], //
|
||||
mat[0][1], mat[1][1], mat[2][1], //
|
||||
mat[0][2], mat[1][2], mat[2][2], //
|
||||
};
|
||||
primariesConversionCache.insert(std::make_pair(cacheKey, glConvertMatrix));
|
||||
}
|
||||
glUniformMatrix3fv(shader.convertMatrix, 1, false, &primariesConversionCache[cacheKey][0]);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::passCMUniforms(const CShader& shader, const SImageDescription& imageDescription) {
|
||||
|
Reference in New Issue
Block a user