cm: Use precomputed primaries conversion (#9814)

This commit is contained in:
UjinT34 2025-04-29 22:29:40 +03:00 committed by GitHub
parent 94bc132084
commit 49974d5e34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 164 additions and 136 deletions

View file

@ -8,8 +8,6 @@
using namespace NColorManagement;
static uint64_t lastImageID = 0; // FIXME use for deduplication
CColorManager::CColorManager(SP<CWpColorManagerV1> resource) : m_resource(resource) {
if UNLIKELY (!good())
return;
@ -191,14 +189,13 @@ CColorManager::CColorManager(SP<CWpColorManagerV1> resource) : m_resource(resour
}
RESOURCE->self = RESOURCE;
RESOURCE->settings.id = ++lastImageID;
RESOURCE->settings.windowsScRGB = true;
RESOURCE->settings.primariesNamed = NColorManagement::CM_PRIMARIES_SRGB;
RESOURCE->settings.primariesNameSet = true;
RESOURCE->settings.primaries = NColorPrimaries::BT709;
RESOURCE->settings.transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_EXT_LINEAR;
RESOURCE->settings.luminances.reference = 203;
RESOURCE->resource()->sendReady(RESOURCE->settings.id);
RESOURCE->resource()->sendReady(RESOURCE->settings.updateId());
});
m_resource->setOnDestroy([this](CWpColorManagerV1* r) { PROTO::colorManagement->destroyResource(this); });
@ -239,9 +236,7 @@ CColorManagementOutput::CColorManagementOutput(SP<CWpColorManagementOutputV1> re
RESOURCE->m_resource->sendFailed(WP_IMAGE_DESCRIPTION_V1_CAUSE_NO_OUTPUT, "No output");
else {
RESOURCE->settings = m_monitor->imageDescription;
if (RESOURCE->settings.id)
RESOURCE->settings.id = ++lastImageID;
RESOURCE->m_resource->sendReady(RESOURCE->settings.id); // FIXME: create correct id
RESOURCE->m_resource->sendReady(RESOURCE->settings.updateId());
}
});
}
@ -383,10 +378,7 @@ CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SP<CWpColorMana
m_currentPreferred = RESOURCE;
m_currentPreferred->settings = g_pCompositor->getPreferredImageDescription();
if (!m_currentPreferred->settings.id)
m_currentPreferred->settings.id = ++lastImageID;
RESOURCE->resource()->sendReady(++lastImageID); // FIXME: create correct id
RESOURCE->resource()->sendReady(m_currentPreferred->settings.updateId());
});
m_resource->setGetPreferredParametric([this](CWpColorManagementSurfaceFeedbackV1* r, uint32_t id) {
@ -419,7 +411,7 @@ CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SP<CWpColorMana
return;
}
RESOURCE->resource()->sendReady(++lastImageID); // FIXME: create correct id
RESOURCE->resource()->sendReady(m_currentPreferred->settings.updateId());
});
}
@ -467,8 +459,7 @@ CColorManagementIccCreator::CColorManagementIccCreator(SP<CWpImageDescriptionCre
RESOURCE->self = RESOURCE;
RESOURCE->settings = settings;
settings.id = ++lastImageID;
RESOURCE->resource()->sendReady(settings.id); // FIXME: create correct id
RESOURCE->resource()->sendReady(settings.updateId());
PROTO::colorManagement->destroyResource(this);
});
@ -522,8 +513,7 @@ CColorManagementParametricCreator::CColorManagementParametricCreator(SP<CWpImage
RESOURCE->self = RESOURCE;
RESOURCE->settings = settings;
settings.id = ++lastImageID;
RESOURCE->resource()->sendReady(settings.id); // FIXME: create correct id
RESOURCE->resource()->sendReady(settings.updateId());
PROTO::colorManagement->destroyResource(this);
});

View file

@ -1,7 +1,11 @@
#include "ColorManagement.hpp"
#include <map>
namespace NColorManagement {
const SPCPRimaries& getPrimaries(ePrimaries name) {
static uint32_t lastImageID = 0;
static std::map<uint32_t, SImageDescription> knownDescriptionIds; // expected to be small
const SPCPRimaries& getPrimaries(ePrimaries name) {
switch (name) {
case CM_PRIMARIES_SRGB: return NColorPrimaries::BT709;
case CM_PRIMARIES_BT2020: return NColorPrimaries::BT2020;
@ -17,4 +21,26 @@ namespace NColorManagement {
}
}
// TODO make image descriptions immutable and always set an id
uint32_t SImageDescription::findId() const {
for (auto it = knownDescriptionIds.begin(); it != knownDescriptionIds.end(); ++it) {
if (it->second == *this)
return it->first;
}
const auto newId = ++lastImageID;
knownDescriptionIds.insert(std::make_pair(newId, *this));
return newId;
}
uint32_t SImageDescription::getId() const {
return id > 0 ? id : findId();
}
uint32_t SImageDescription::updateId() {
id = 0;
id = findId();
return id;
}
}

View file

@ -1,6 +1,13 @@
#pragma once
#include "color-management-v1.hpp"
#include <hyprgraphics/color/Color.hpp>
#define SDR_MIN_LUMINANCE 0.2
#define SDR_MAX_LUMINANCE 80.0
#define HDR_MIN_LUMINANCE 0.005
#define HDR_MAX_LUMINANCE 10000.0
#define HLG_MAX_LUMINANCE 1000.0
namespace NColorManagement {
enum ePrimaries : uint8_t {
@ -47,19 +54,7 @@ namespace NColorManagement {
return (eTransferFunction)tf;
}
struct SPCPRimaries {
struct xy { //NOLINT(readability-identifier-naming)
float x = 0;
float y = 0;
bool operator==(const xy& p2) const {
return x == p2.x && y == p2.y;
}
} red, green, blue, white;
bool operator==(const SPCPRimaries& p2) const {
return red == p2.red && green == p2.green && blue == p2.blue && white == p2.white;
}
};
typedef Hyprgraphics::SPCPRimaries SPCPRimaries;
namespace NColorPrimaries {
static const auto DEFAULT_PRIMARIES = SPCPRimaries{};
@ -185,5 +180,46 @@ namespace NColorManagement {
return NColorManagement::getPrimaries(primariesNamed);
return primaries;
}
float getTFMinLuminance() const {
switch (transferFunction) {
case CM_TRANSFER_FUNCTION_EXT_LINEAR: return 0;
case CM_TRANSFER_FUNCTION_ST2084_PQ:
case CM_TRANSFER_FUNCTION_HLG: return HDR_MIN_LUMINANCE;
case CM_TRANSFER_FUNCTION_GAMMA22:
case CM_TRANSFER_FUNCTION_GAMMA28:
case CM_TRANSFER_FUNCTION_BT1886:
case CM_TRANSFER_FUNCTION_ST240:
case CM_TRANSFER_FUNCTION_LOG_100:
case CM_TRANSFER_FUNCTION_LOG_316:
case CM_TRANSFER_FUNCTION_XVYCC:
case CM_TRANSFER_FUNCTION_EXT_SRGB:
case CM_TRANSFER_FUNCTION_ST428:
case CM_TRANSFER_FUNCTION_SRGB:
default: return SDR_MIN_LUMINANCE;
}
};
float getTFMaxLuminance() const {
switch (transferFunction) {
case CM_TRANSFER_FUNCTION_ST2084_PQ: return HDR_MAX_LUMINANCE;
case CM_TRANSFER_FUNCTION_HLG: return HLG_MAX_LUMINANCE;
case CM_TRANSFER_FUNCTION_GAMMA22:
case CM_TRANSFER_FUNCTION_GAMMA28:
case CM_TRANSFER_FUNCTION_BT1886:
case CM_TRANSFER_FUNCTION_ST240:
case CM_TRANSFER_FUNCTION_LOG_100:
case CM_TRANSFER_FUNCTION_LOG_316:
case CM_TRANSFER_FUNCTION_XVYCC:
case CM_TRANSFER_FUNCTION_EXT_SRGB:
case CM_TRANSFER_FUNCTION_ST428:
case CM_TRANSFER_FUNCTION_SRGB:
default: return SDR_MAX_LUMINANCE;
}
};
uint32_t findId() const;
uint32_t getId() const;
uint32_t updateId();
};
}

View file

@ -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) {

View file

@ -15,13 +15,15 @@ class CShader {
GLint skipCM = -1;
GLint sourceTF = -1;
GLint targetTF = -1;
GLint sourcePrimaries = -1;
GLint srcTFRange = -1;
GLint dstTFRange = -1;
GLint targetPrimaries = -1;
GLint maxLuminance = -1;
GLint dstMaxLuminance = -1;
GLint dstRefLuminance = -1;
GLint sdrSaturation = -1; // sdr -> hdr saturation
GLint sdrBrightness = -1; // sdr -> hdr brightness multiplier
GLint convertMatrix = -1;
GLint tex = -1;
GLint alpha = -1;
GLint posAttrib = -1;

View file

@ -11,7 +11,6 @@ uniform int texType; // eTextureType: 0 - rgba, 1 - rgbx, 2 - ext
// uniform int skipCM;
uniform int sourceTF; // eTransferFunction
uniform int targetTF; // eTransferFunction
uniform mat4x2 sourcePrimaries;
uniform mat4x2 targetPrimaries;
uniform float alpha;
@ -43,7 +42,7 @@ void main() {
discard;
// this shader shouldn't be used when skipCM == 1
pixColor = doColorManagement(pixColor, sourceTF, sourcePrimaries, targetTF, targetPrimaries);
pixColor = doColorManagement(pixColor, sourceTF, targetTF, targetPrimaries);
if (applyTint == 1)
pixColor = vec4(pixColor.rgb * tint.rgb, pixColor[3]);

View file

@ -1,8 +1,12 @@
uniform vec2 srcTFRange;
uniform vec2 dstTFRange;
uniform float maxLuminance;
uniform float dstMaxLuminance;
uniform float dstRefLuminance;
uniform float sdrSaturation;
uniform float sdrBrightnessMultiplier;
uniform mat3 convertMatrix;
//enum eTransferFunction
#define CM_TRANSFER_FUNCTION_BT1886 1
@ -117,30 +121,8 @@ vec4 toLinear(vec4 color, int tf) {
return color;
}
vec4 toNit(vec4 color, int tf) {
if (tf == CM_TRANSFER_FUNCTION_EXT_LINEAR)
color.rgb = color.rgb * SDR_MAX_LUMINANCE;
else {
switch (tf) {
case CM_TRANSFER_FUNCTION_ST2084_PQ:
color.rgb = color.rgb * (HDR_MAX_LUMINANCE - HDR_MIN_LUMINANCE) + HDR_MIN_LUMINANCE; break;
case CM_TRANSFER_FUNCTION_HLG:
color.rgb = color.rgb * (HLG_MAX_LUMINANCE - HDR_MIN_LUMINANCE) + HDR_MIN_LUMINANCE; break;
case CM_TRANSFER_FUNCTION_GAMMA22:
case CM_TRANSFER_FUNCTION_GAMMA28:
case CM_TRANSFER_FUNCTION_BT1886:
case CM_TRANSFER_FUNCTION_ST240:
case CM_TRANSFER_FUNCTION_LOG_100:
case CM_TRANSFER_FUNCTION_LOG_316:
case CM_TRANSFER_FUNCTION_XVYCC:
case CM_TRANSFER_FUNCTION_EXT_SRGB:
case CM_TRANSFER_FUNCTION_ST428:
case CM_TRANSFER_FUNCTION_SRGB:
default:
color.rgb = color.rgb * (SDR_MAX_LUMINANCE - SDR_MIN_LUMINANCE) + SDR_MIN_LUMINANCE; break;
}
}
vec4 toNit(vec4 color, vec2 range) {
color.rgb = color.rgb * (range[1] - range[0]) + range[0];
return color;
}
@ -195,33 +177,13 @@ vec4 fromLinear(vec4 color, int tf) {
return color;
}
vec4 fromLinearNit(vec4 color, int tf) {
vec4 fromLinearNit(vec4 color, int tf, vec2 range) {
if (tf == CM_TRANSFER_FUNCTION_EXT_LINEAR)
color.rgb = color.rgb / SDR_MAX_LUMINANCE;
else {
color.rgb /= max(color.a, 0.001);
switch (tf) {
case CM_TRANSFER_FUNCTION_ST2084_PQ:
color.rgb = (color.rgb - HDR_MIN_LUMINANCE) / (HDR_MAX_LUMINANCE - HDR_MIN_LUMINANCE); break;
case CM_TRANSFER_FUNCTION_HLG:
color.rgb = (color.rgb - HDR_MIN_LUMINANCE) / (HLG_MAX_LUMINANCE - HDR_MIN_LUMINANCE); break;
case CM_TRANSFER_FUNCTION_GAMMA22:
case CM_TRANSFER_FUNCTION_GAMMA28:
case CM_TRANSFER_FUNCTION_BT1886:
case CM_TRANSFER_FUNCTION_ST240:
case CM_TRANSFER_FUNCTION_LOG_100:
case CM_TRANSFER_FUNCTION_LOG_316:
case CM_TRANSFER_FUNCTION_XVYCC:
case CM_TRANSFER_FUNCTION_EXT_SRGB:
case CM_TRANSFER_FUNCTION_ST428:
case CM_TRANSFER_FUNCTION_SRGB:
default:
color.rgb = (color.rgb - SDR_MIN_LUMINANCE) / (SDR_MAX_LUMINANCE - SDR_MIN_LUMINANCE); break;
}
color.rgb = (color.rgb - range[0]) / (range[1] - range[0]);
color.rgb = fromLinearRGB(color.rgb, tf);
color.rgb *= color.a;
}
return color;
@ -250,13 +212,6 @@ mat3 primaries2xyz(mat4x2 primaries) {
);
}
// const vec2 D65 = vec2(0.3127, 0.3290);
const mat3 Bradford = mat3(
0.8951, 0.2664, -0.1614,
-0.7502, 1.7135, 0.0367,
0.0389, -0.0685, 1.0296
);
const mat3 BradfordInv = inverse(Bradford);
mat3 adaptWhite(vec2 src, vec2 dst) {
if (src == dst)
@ -266,6 +221,13 @@ mat3 adaptWhite(vec2 src, vec2 dst) {
0.0, 0.0, 1.0
);
// const vec2 D65 = vec2(0.3127, 0.3290);
const mat3 Bradford = mat3(
0.8951, 0.2664, -0.1614,
-0.7502, 1.7135, 0.0367,
0.0389, -0.0685, 1.0296
);
mat3 BradfordInv = inverse(Bradford);
vec3 srcXYZ = xy2xyz(src);
vec3 dstXYZ = xy2xyz(dst);
vec3 factors = (Bradford * dstXYZ) / (Bradford * srcXYZ);
@ -287,21 +249,37 @@ const mat3 BT2020toLMS = mat3(
-0.1922, 1.1004, 0.0755,
0.0070, 0.0749, 0.8434
);
const mat3 LMStoBT2020 = inverse(BT2020toLMS);
//const mat3 LMStoBT2020 = inverse(BT2020toLMS);
const mat3 LMStoBT2020 = mat3(
2.0701800566956135096, -1.3264568761030210255, 0.20661600684785517081,
0.36498825003265747974, 0.68046736285223514102, -0.045421753075853231409,
-0.049595542238932107896, -0.049421161186757487412, 1.1879959417328034394
);
const mat3 ICtCpPQ = transpose(mat3(
2048.0, 2048.0, 0.0,
6610.0, -13613.0, 7003.0,
17933.0, -17390.0, -543.0
) / 4096.0);
const mat3 ICtCpPQInv = inverse(ICtCpPQ);
// const mat3 ICtCpPQ = transpose(mat3(
// 2048.0, 2048.0, 0.0,
// 6610.0, -13613.0, 7003.0,
// 17933.0, -17390.0, -543.0
// ) / 4096.0);
const mat3 ICtCpPQ = mat3(
0.5, 1.61376953125, 4.378173828125,
0.5, -3.323486328125, -4.24560546875,
0.0, 1.709716796875, -0.132568359375
);
//const mat3 ICtCpPQInv = inverse(ICtCpPQ);
const mat3 ICtCpPQInv = mat3(
1.0, 1.0, 1.0,
0.0086090370379327566, -0.0086090370379327566, 0.560031335710679118,
0.11102962500302595656, -0.11102962500302595656, -0.32062717498731885185
);
const mat3 ICtCpHLG = transpose(mat3(
2048.0, 2048.0, 0.0,
3625.0, -7465.0, 3840.0,
9500.0, -9212.0, -288.0
) / 4096.0);
const mat3 ICtCpHLGInv = inverse(ICtCpHLG);
// unused for now
// const mat3 ICtCpHLG = transpose(mat3(
// 2048.0, 2048.0, 0.0,
// 3625.0, -7465.0, 3840.0,
// 9500.0, -9212.0, -288.0
// ) / 4096.0);
// const mat3 ICtCpHLGInv = inverse(ICtCpHLG);
vec4 tonemap(vec4 color, mat3 dstXYZ) {
if (maxLuminance < dstMaxLuminance * 1.01)
@ -339,23 +317,17 @@ vec4 tonemap(vec4 color, mat3 dstXYZ) {
return vec4(fromLMS * toLinear(vec4(ICtCpPQInv * ICtCp, 1.0), CM_TRANSFER_FUNCTION_ST2084_PQ).rgb * HDR_MAX_LUMINANCE, color[3]);
}
vec4 doColorManagement(vec4 pixColor, int srcTF, mat4x2 srcPrimaries, int dstTF, mat4x2 dstPrimaries) {
vec4 doColorManagement(vec4 pixColor, int srcTF, int dstTF, mat4x2 dstPrimaries) {
pixColor.rgb /= max(pixColor.a, 0.001);
pixColor.rgb = toLinearRGB(pixColor.rgb, srcTF);
mat3 srcxyz = primaries2xyz(srcPrimaries);
mat3 dstxyz;
if (srcPrimaries == dstPrimaries)
dstxyz = srcxyz;
else {
dstxyz = primaries2xyz(dstPrimaries);
pixColor = convertPrimaries(pixColor, srcxyz, srcPrimaries[3], dstxyz, dstPrimaries[3]);
}
pixColor = toNit(pixColor, srcTF);
pixColor.rgb = convertMatrix * pixColor.rgb;
pixColor = toNit(pixColor, srcTFRange);
pixColor.rgb *= pixColor.a;
mat3 dstxyz = primaries2xyz(dstPrimaries);
pixColor = tonemap(pixColor, dstxyz);
pixColor = fromLinearNit(pixColor, dstTF);
pixColor = fromLinearNit(pixColor, dstTF, dstTFRange);
if (srcTF == CM_TRANSFER_FUNCTION_SRGB && dstTF == CM_TRANSFER_FUNCTION_ST2084_PQ) {
pixColor = saturate(pixColor, srcxyz, sdrSaturation);
pixColor = saturate(pixColor, dstxyz, sdrSaturation);
pixColor.rgb /= pixColor.a;
pixColor.rgb *= sdrBrightnessMultiplier;
pixColor.rgb *= pixColor.a;

View file

@ -11,8 +11,6 @@ uniform float brightness;
uniform int skipCM;
uniform int sourceTF; // eTransferFunction
uniform int targetTF; // eTransferFunction
uniform mat4x2 sourcePrimaries;
uniform mat4x2 targetPrimaries;
#include "CM.glsl"
@ -29,17 +27,9 @@ void main() {
if (sourceTF == CM_TRANSFER_FUNCTION_ST2084_PQ) {
pixColor.rgb /= sdrBrightnessMultiplier;
}
pixColor.rgb = toLinearRGB(pixColor.rgb, sourceTF);
mat3 srcxyz = primaries2xyz(sourcePrimaries);
mat3 dstxyz;
if (sourcePrimaries == targetPrimaries)
dstxyz = srcxyz;
else {
dstxyz = primaries2xyz(targetPrimaries);
pixColor = convertPrimaries(pixColor, srcxyz, sourcePrimaries[3], dstxyz, targetPrimaries[3]);
}
pixColor = toNit(pixColor, sourceTF);
pixColor = fromLinearNit(pixColor, targetTF);
pixColor.rgb = convertMatrix * toLinearRGB(pixColor.rgb, sourceTF);
pixColor = toNit(pixColor, srcTFRange);
pixColor = fromLinearNit(pixColor, targetTF, dstTFRange);
}
// contrast

View file

@ -7,7 +7,6 @@ in vec2 v_texcoord;
uniform int skipCM;
uniform int sourceTF; // eTransferFunction
uniform int targetTF; // eTransferFunction
uniform mat4x2 sourcePrimaries;
uniform mat4x2 targetPrimaries;
uniform vec2 fullSizeUntransformed;
@ -175,7 +174,7 @@ void main() {
pixColor.rgb *= pixColor[3];
if (skipCM == 0)
pixColor = doColorManagement(pixColor, sourceTF, sourcePrimaries, targetTF, targetPrimaries);
pixColor = doColorManagement(pixColor, sourceTF, targetTF, targetPrimaries);
pixColor *= alpha * additionalAlpha;

View file

@ -8,7 +8,6 @@ in vec2 v_texcoord;
uniform int skipCM;
uniform int sourceTF; // eTransferFunction
uniform int targetTF; // eTransferFunction
uniform mat4x2 sourcePrimaries;
uniform mat4x2 targetPrimaries;
uniform vec2 topLeft;
@ -94,7 +93,7 @@ void main() {
pixColor.rgb *= pixColor[3];
if (skipCM == 0)
pixColor = doColorManagement(pixColor, sourceTF, sourcePrimaries, targetTF, targetPrimaries);
pixColor = doColorManagement(pixColor, sourceTF, targetTF, targetPrimaries);
fragColor = pixColor;
}