[client] egl: improve HDR cursor rendering, fixes alpha blending

This commit is contained in:
Geoffrey McRae
2026-07-17 16:48:57 +10:00
parent 04441bfd85
commit d41c9fdc5d
4 changed files with 53 additions and 86 deletions

View File

@@ -3,6 +3,7 @@ precision highp float;
precision highp int;
#include "color_blind.h"
#include "hdr.h"
in vec2 uv;
out vec4 color;
@@ -10,6 +11,7 @@ out vec4 color;
uniform sampler2D sampler1;
uniform float scale;
uniform int cbMode;
uniform bool mapSDRtoPQ;
void main()
{
@@ -27,4 +29,18 @@ void main()
if (cbMode > 0)
color = cbTransform(color, cbMode);
if (mapSDRtoPQ)
{
if (color.a > 0.0)
{
// Cursor pixels are premultiplied. Convert the straight color to PQ,
// then premultiply again so the blend operation remains valid.
vec3 srgb = clamp(color.rgb / color.a, 0.0, 1.0);
vec3 linear = bt709to2020(srgb2lin(srgb));
color.rgb = lin2pq(linear * (203.0 / 10000.0)) * color.a;
}
else
color.rgb = vec3(0.0);
}
}

View File

@@ -21,6 +21,8 @@ const float ratio = 4.0; // Compressor ratio: 1 = disabled, <1 = exp
const float compressor = 1.0 / ratio;
// PQ constants
const float m1 = 2610.0 / 16384.0;
const float m2 = 2523.0 / 32.0;
const float m1inv = 16384.0 / 2610.0;
const float m2inv = 32.0 / 2523.0;
const float c1 = 3424.0 / 4096.0;
@@ -72,6 +74,13 @@ vec3 pq2lin(vec3 pq, float gain)
return pow(d, vec3(m1inv)) * gain;
}
vec3 lin2pq(vec3 linear)
{
// ST.2084 uses absolute luminance normalized to 10000 cd/m².
vec3 p = pow(linear, vec3(m1));
return pow((c1 + c2 * p) / (1.0 + c3 * p), vec3(m2));
}
vec3 srgb2lin(vec3 c)
{
vec3 v = c / 12.92;
@@ -99,6 +108,15 @@ vec3 bt2020to709(vec3 bt2020)
bt2020.r * -0.0182 + bt2020.g * -0.1006 + bt2020.b * 1.1187);
}
// in linear space
vec3 bt709to2020(vec3 bt709)
{
return vec3(
bt709.r * 0.6274 + bt709.g * 0.3293 + bt709.b * 0.0433,
bt709.r * 0.0691 + bt709.g * 0.9195 + bt709.b * 0.0114,
bt709.r * 0.0164 + bt709.g * 0.0880 + bt709.b * 0.8956);
}
vec3 mapToSDR(vec3 color, float gain, bool pq)
{
if (pq)