Bug 494305 - Visual bell invert effect broken
Summary: Visual bell invert effect broken
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: general (show other bugs)
Version: master
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-10-08 19:37 UTC by Nicolas Fella
Modified: 2024-10-08 20:18 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nicolas Fella 2024-10-08 19:37:21 UTC
STEPS TO REPRODUCE
1. Configure visual bell in Accessibility settings to invert the screen 
2. Run qdbus org.kde.KWin /org/kde/KWin/Effect/SystemBell1 org.kde.KWin.Effect.SystemBell1.triggerScreen

OBSERVED RESULT
Screen flashes white

EXPECTED RESULT
Screen inverts

SOFTWARE/OS VERSIONS
KDE Plasma Version: master
KDE Frameworks Version: master
Qt Version: 6.8

ADDITIONAL INFORMATION

Bisected to https://invent.kde.org/plasma/kwin/-/commit/bea4d1064ceecafb5e3251b061c8aae8d0b9e909
Comment 1 Nicolas Fella 2024-10-08 19:40:03 UTC
kwin_scene_opengl: 0x2: 0:217(8): error: no matching function for call to `nitsToEncoding(vec4, int, float)'; candidates are:
kwin_scene_opengl: 0x3: 0:217(8): error:    vec4 nitsToEncoding(vec4, int, float, float)
kwin_scene_opengl: 0x4: 0:222(8): error: no matching function for call to `encodingToNits(vec4, int, float)'; candidates are:
kwin_scene_opengl: 0x5: 0:222(8): error:    vec4 encodingToNits(vec4, int, float, float)
kwin_scene_opengl: Failed to compile fragment shader: 
 "0:217(8): error: no matching function for call to `nitsToEncoding(vec4, int, float)'; candidates are:\n0:217(8): error:    vec4 nitsToEncoding(vec4, int, float, float)\n0:222(8): error: no matching function for call to `encodingToNits(vec4, int, float)'; candidates are:\n0:222(8): error:    vec4 encodingToNits(vec4, int, float, float)\n\x00"
kwin_scene_opengl: line 0:"#version 140"
kwin_scene_opengl: line 1:""
kwin_scene_opengl: line 2:"const int sRGB_EOTF = 0;"
kwin_scene_opengl: line 3:"const int linear_EOTF = 1;"
kwin_scene_opengl: line 4:"const int PQ_EOTF = 2;"
kwin_scene_opengl: line 5:"const int gamma22_EOTF = 3;"
kwin_scene_opengl: line 6:""
kwin_scene_opengl: line 7:"uniform mat4 colorimetryTransform;"
kwin_scene_opengl: line 8:""
kwin_scene_opengl: line 9:"uniform int sourceNamedTransferFunction;"
kwin_scene_opengl: line 10:"/**"
kwin_scene_opengl: line 11:" * x: min luminance"
kwin_scene_opengl: line 12:" * y: max luminance - min luminance"
kwin_scene_opengl: line 13:" */"
kwin_scene_opengl: line 14:"uniform vec2 sourceTransferFunctionParams;"
kwin_scene_opengl: line 15:""
kwin_scene_opengl: line 16:"uniform int destinationNamedTransferFunction;"
kwin_scene_opengl: line 17:"/**"
kwin_scene_opengl: line 18:" * x: min luminance"
kwin_scene_opengl: line 19:" * y: max luminance - min luminance"
kwin_scene_opengl: line 20:" */"
kwin_scene_opengl: line 21:"uniform vec2 destinationTransferFunctionParams;"
kwin_scene_opengl: line 22:""
kwin_scene_opengl: line 23:"// in nits"
kwin_scene_opengl: line 24:"uniform float sourceReferenceLuminance;"
kwin_scene_opengl: line 25:"uniform float maxTonemappingLuminance;"
kwin_scene_opengl: line 26:"uniform float destinationReferenceLuminance;"
kwin_scene_opengl: line 27:"uniform float maxDestinationLuminance;"
kwin_scene_opengl: line 28:""
kwin_scene_opengl: line 29:"uniform mat4 destinationToLMS;"
kwin_scene_opengl: line 30:"uniform mat4 lmsToDestination;"
kwin_scene_opengl: line 31:""
kwin_scene_opengl: line 32:"vec3 linearToPq(vec3 linear) {"
kwin_scene_opengl: line 33:"    const float c1 = 0.8359375;"
kwin_scene_opengl: line 34:"    const float c2 = 18.8515625;"
kwin_scene_opengl: line 35:"    const float c3 = 18.6875;"
kwin_scene_opengl: line 36:"    const float m1 = 0.1593017578125;"
kwin_scene_opengl: line 37:"    const float m2 = 78.84375;"
kwin_scene_opengl: line 38:"    vec3 powed = pow(clamp(linear, vec3(0), vec3(1)), vec3(m1));"
kwin_scene_opengl: line 39:"    vec3 num = vec3(c1) + c2 * powed;"
kwin_scene_opengl: line 40:"    vec3 denum = vec3(1.0) + c3 * powed;"
kwin_scene_opengl: line 41:"    return pow(num / denum, vec3(m2));"
kwin_scene_opengl: line 42:"}"
kwin_scene_opengl: line 43:"vec3 pqToLinear(vec3 pq) {"
kwin_scene_opengl: line 44:"    const float c1 = 0.8359375;"
kwin_scene_opengl: line 45:"    const float c2 = 18.8515625;"
kwin_scene_opengl: line 46:"    const float c3 = 18.6875;"
kwin_scene_opengl: line 47:"    const float m1_inv = 1.0 / 0.1593017578125;"
kwin_scene_opengl: line 48:"    const float m2_inv = 1.0 / 78.84375;"
kwin_scene_opengl: line 49:"    vec3 powed = pow(clamp(pq, vec3(0.0), vec3(1.0)), vec3(m2_inv));"
kwin_scene_opengl: line 50:"    vec3 num = max(powed - c1, vec3(0.0));"
kwin_scene_opengl: line 51:"    vec3 den = c2 - c3 * powed;"
kwin_scene_opengl: line 52:"    return pow(num / den, vec3(m1_inv));"
kwin_scene_opengl: line 53:"}"
kwin_scene_opengl: line 54:"float singleLinearToPq(float linear) {"
kwin_scene_opengl: line 55:"    const float c1 = 0.8359375;"
kwin_scene_opengl: line 56:"    const float c2 = 18.8515625;"
kwin_scene_opengl: line 57:"    const float c3 = 18.6875;"
kwin_scene_opengl: line 58:"    const float m1 = 0.1593017578125;"
kwin_scene_opengl: line 59:"    const float m2 = 78.84375;"
kwin_scene_opengl: line 60:"    float powed = pow(clamp(linear, 0.0, 1.0), m1);"
kwin_scene_opengl: line 61:"    float num = c1 + c2 * powed;"
kwin_scene_opengl: line 62:"    float denum = 1.0 + c3 * powed;"
kwin_scene_opengl: line 63:"    return pow(num / denum, m2);"
kwin_scene_opengl: line 64:"}"
kwin_scene_opengl: line 65:"float singlePqToLinear(float pq) {"
kwin_scene_opengl: line 66:"    const float c1 = 0.8359375;"
kwin_scene_opengl: line 67:"    const float c2 = 18.8515625;"
kwin_scene_opengl: line 68:"    const float c3 = 18.6875;"
kwin_scene_opengl: line 69:"    const float m1_inv = 1.0 / 0.1593017578125;"
kwin_scene_opengl: line 70:"    const float m2_inv = 1.0 / 78.84375;"
kwin_scene_opengl: line 71:"    float powed = pow(clamp(pq, 0.0, 1.0), m2_inv);"
kwin_scene_opengl: line 72:"    float num = max(powed - c1, 0.0);"
kwin_scene_opengl: line 73:"    float den = c2 - c3 * powed;"
kwin_scene_opengl: line 74:"    return pow(num / den, m1_inv);"
kwin_scene_opengl: line 75:"}"
kwin_scene_opengl: line 76:"vec3 srgbToLinear(vec3 color) {"
kwin_scene_opengl: line 77:"    bvec3 isLow = lessThanEqual(color, vec3(0.04045));"
kwin_scene_opengl: line 78:"    vec3 loPart = color / 12.92;"
kwin_scene_opengl: line 79:"    vec3 hiPart = pow((color + 0.055) / 1.055, vec3(12.0 / 5.0));"
kwin_scene_opengl: line 80:"#if __VERSION__ >= 130"
kwin_scene_opengl: line 81:"    return mix(hiPart, loPart, isLow);"
kwin_scene_opengl: line 82:"#else"
kwin_scene_opengl: line 83:"    return mix(hiPart, loPart, vec3(isLow.r ? 1.0 : 0.0, isLow.g ? 1.0 : 0.0, isLow.b ? 1.0 : 0.0));"
kwin_scene_opengl: line 84:"#endif"
kwin_scene_opengl: line 85:"}"
kwin_scene_opengl: line 86:""
kwin_scene_opengl: line 87:"vec3 linearToSrgb(vec3 color) {"
kwin_scene_opengl: line 88:"    bvec3 isLow = lessThanEqual(color, vec3(0.0031308));"
kwin_scene_opengl: line 89:"    vec3 loPart = color * 12.92;"
kwin_scene_opengl: line 90:"    vec3 hiPart = pow(color, vec3(5.0 / 12.0)) * 1.055 - 0.055;"
kwin_scene_opengl: line 91:"#if __VERSION__ >= 130"
kwin_scene_opengl: line 92:"    return mix(hiPart, loPart, isLow);"
kwin_scene_opengl: line 93:"#else"
kwin_scene_opengl: line 94:"    return mix(hiPart, loPart, vec3(isLow.r ? 1.0 : 0.0, isLow.g ? 1.0 : 0.0, isLow.b ? 1.0 : 0.0));"
kwin_scene_opengl: line 95:"#endif"
kwin_scene_opengl: line 96:"}"
kwin_scene_opengl: line 97:""
kwin_scene_opengl: line 98:"const mat3 toICtCp = mat3("
kwin_scene_opengl: line 99:"    0.5,  1.613769531250,   4.378173828125,"
kwin_scene_opengl: line 100:"    0.5, -3.323486328125, -4.245605468750,"
kwin_scene_opengl: line 101:"    0.0,  1.709716796875, -0.132568359375"
kwin_scene_opengl: line 102:");"
kwin_scene_opengl: line 103:"const mat3 fromICtCp = mat3("
kwin_scene_opengl: line 104:"    1.0,               1.0,             1.0,"
kwin_scene_opengl: line 105:"    0.00860903703793, -0.008609037037,  0.56031335710680,"
kwin_scene_opengl: line 106:"    0.11102962500303, -0.111029625003, -0.32062717498732"
kwin_scene_opengl: line 107:");"
kwin_scene_opengl: line 108:""
kwin_scene_opengl: line 109:"vec3 doTonemapping(vec3 color) {"
kwin_scene_opengl: line 110:"    if (maxTonemappingLuminance < maxDestinationLuminance * 1.01) {"
kwin_scene_opengl: line 111:"        // clipping is enough"
kwin_scene_opengl: line 112:"        return clamp(color.rgb, vec3(0.0), vec3(maxDestinationLuminance));"
kwin_scene_opengl: line 113:"    }"
kwin_scene_opengl: line 114:""
kwin_scene_opengl: line 115:"    // first, convert to ICtCp, to properly split luminance and color"
kwin_scene_opengl: line 116:"    // intensity is PQ-encoded luminance"
kwin_scene_opengl: line 117:"    vec3 lms = (destinationToLMS * vec4(color, 1.0)).rgb;"
kwin_scene_opengl: line 118:"    vec3 lms_PQ = linearToPq(lms / 10000.0);"
kwin_scene_opengl: line 119:"    vec3 ICtCp = toICtCp * lms_PQ;"
kwin_scene_opengl: line 120:"    float luminance = singlePqToLinear(ICtCp.r) * 10000.0;"
kwin_scene_opengl: line 121:""
kwin_scene_opengl: line 122:"    float inputRange = maxTonemappingLuminance / destinationReferenceLuminance;"
kwin_scene_opengl: line 123:"    float outputRange = maxDestinationLuminance / destinationReferenceLuminance;"
kwin_scene_opengl: line 124:"    // how much dynamic range we need to decently present the content"
kwin_scene_opengl: line 125:"    float minDecentRange = min(inputRange, 1.5);"
kwin_scene_opengl: line 126:"    // if the output doesn't provide enough HDR headroom for the tone mapper to do a good job, dim the image to create some"
kwin_scene_opengl: line 127:"    float referenceDimming = 1.0 / clamp(outputRange / minDecentRange, 1.0, minDecentRange);"
kwin_scene_opengl: line 128:"    float outputReferenceLuminance = destinationReferenceLuminance * referenceDimming;"
kwin_scene_opengl: line 129:""
kwin_scene_opengl: line 130:"    // keep it linear up to the reference luminance"
kwin_scene_opengl: line 131:"    float low = min(luminance * referenceDimming, outputReferenceLuminance);"
kwin_scene_opengl: line 132:"    // and apply a nonlinear curve above, to reduce the luminance without completely removing differences"
kwin_scene_opengl: line 133:"    float relativeHighlight = clamp((luminance / destinationReferenceLuminance - 1.0) / (inputRange - 1.0), 0.0, 1.0);"
kwin_scene_opengl: line 134:"    const float e = 2.718281828459045;"
kwin_scene_opengl: line 135:"    float high = log(relativeHighlight * (e - 1.0) + 1.0) * (maxDestinationLuminance - outputReferenceLuminance);"
kwin_scene_opengl: line 136:"    luminance = low + high;"
kwin_scene_opengl: line 137:""
kwin_scene_opengl: line 138:"    // last, convert back to rgb"
kwin_scene_opengl: line 139:"    ICtCp.r = singleLinearToPq(luminance / 10000.0);"
kwin_scene_opengl: line 140:"    return (lmsToDestination * vec4(pqToLinear(fromICtCp * ICtCp), 1.0)).rgb * 10000.0;"
kwin_scene_opengl: line 141:"}"
kwin_scene_opengl: line 142:""
kwin_scene_opengl: line 143:"vec4 encodingToNits(vec4 color, int sourceTransferFunction, float luminanceOffset, float luminanceScale) {"
kwin_scene_opengl: line 144:"    if (sourceTransferFunction == sRGB_EOTF) {"
kwin_scene_opengl: line 145:"        color.rgb /= max(color.a, 0.001);"
kwin_scene_opengl: line 146:"        color.rgb = srgbToLinear(color.rgb) * luminanceScale + vec3(luminanceOffset);"
kwin_scene_opengl: line 147:"        color.rgb *= color.a;"
kwin_scene_opengl: line 148:"    } else if (sourceTransferFunction == linear_EOTF) {"
kwin_scene_opengl: line 149:"        color.rgb = color.rgb * luminanceScale + vec3(luminanceOffset);"
kwin_scene_opengl: line 150:"    } else if (sourceTransferFunction == PQ_EOTF) {"
kwin_scene_opengl: line 151:"        color.rgb /= max(color.a, 0.001);"
kwin_scene_opengl: line 152:"        color.rgb = pqToLinear(color.rgb) * luminanceScale + vec3(luminanceOffset);"
kwin_scene_opengl: line 153:"        color.rgb *= color.a;"
kwin_scene_opengl: line 154:"    } else if (sourceTransferFunction == gamma22_EOTF) {"
kwin_scene_opengl: line 155:"        color.rgb /= max(color.a, 0.001);"
kwin_scene_opengl: line 156:"        color.rgb = pow(max(color.rgb, vec3(0.0)), vec3(2.2)) * luminanceScale + vec3(luminanceOffset);"
kwin_scene_opengl: line 157:"        color.rgb *= color.a;"
kwin_scene_opengl: line 158:"    }"
kwin_scene_opengl: line 159:"    return color;"
kwin_scene_opengl: line 160:"}"
kwin_scene_opengl: line 161:""
kwin_scene_opengl: line 162:"vec4 sourceEncodingToNitsInDestinationColorspace(vec4 color) {"
kwin_scene_opengl: line 163:"    color = encodingToNits(color, sourceNamedTransferFunction, sourceTransferFunctionParams.x, sourceTransferFunctionParams.y);"
kwin_scene_opengl: line 164:"    color.rgb = (colorimetryTransform * vec4(color.rgb, 1.0)).rgb;"
kwin_scene_opengl: line 165:"    return vec4(doTonemapping(color.rgb), color.a);"
kwin_scene_opengl: line 166:"}"
kwin_scene_opengl: line 167:""
kwin_scene_opengl: line 168:"vec4 nitsToEncoding(vec4 color, int destinationTransferFunction, float luminanceOffset, float luminanceScale) {"
kwin_scene_opengl: line 169:"    if (destinationTransferFunction == sRGB_EOTF) {"
kwin_scene_opengl: line 170:"        color.rgb /= max(color.a, 0.001);"
kwin_scene_opengl: line 171:"        color.rgb = linearToSrgb((color.rgb - vec3(luminanceOffset)) / luminanceScale);"
kwin_scene_opengl: line 172:"        color.rgb *= color.a;"
kwin_scene_opengl: line 173:"    } else if (destinationTransferFunction == linear_EOTF) {"
kwin_scene_opengl: line 174:"        color.rgb = (color.rgb - vec3(luminanceOffset)) / luminanceScale;"
kwin_scene_opengl: line 175:"    } else if (destinationTransferFunction == PQ_EOTF) {"
kwin_scene_opengl: line 176:"        color.rgb /= max(color.a, 0.001);"
kwin_scene_opengl: line 177:"        color.rgb = linearToPq((color.rgb - vec3(luminanceOffset)) / luminanceScale);"
kwin_scene_opengl: line 178:"        color.rgb *= color.a;"
kwin_scene_opengl: line 179:"    } else if (destinationTransferFunction == gamma22_EOTF) {"
kwin_scene_opengl: line 180:"        color.rgb /= max(color.a, 0.001);"
kwin_scene_opengl: line 181:"        color.rgb = pow(max((color.rgb - vec3(luminanceOffset)) / luminanceScale, vec3(0.0)), vec3(1.0 / 2.2));"
kwin_scene_opengl: line 182:"        color.rgb *= color.a;"
kwin_scene_opengl: line 183:"    }"
kwin_scene_opengl: line 184:"    return color;"
kwin_scene_opengl: line 185:"}"
kwin_scene_opengl: line 186:""
kwin_scene_opengl: line 187:"vec4 nitsToDestinationEncoding(vec4 color) {"
kwin_scene_opengl: line 188:"    return nitsToEncoding(color, destinationNamedTransferFunction, destinationTransferFunctionParams.x, destinationTransferFunctionParams.y);"
kwin_scene_opengl: line 189:"}"
kwin_scene_opengl: line 190:""
kwin_scene_opengl: line 191:"uniform float saturation;"
kwin_scene_opengl: line 192:"uniform vec3 primaryBrightness;"
kwin_scene_opengl: line 193:""
kwin_scene_opengl: line 194:"vec4 adjustSaturation(vec4 color) {"
kwin_scene_opengl: line 195:"    // this calculates the Y component of the XYZ color representation for the color,"
kwin_scene_opengl: line 196:"    // which roughly corresponds to the brightness of the RGB tuple"
kwin_scene_opengl: line 197:"    float Y = dot(color.rgb, primaryBrightness);"
kwin_scene_opengl: line 198:"    return vec4(mix(vec3(Y), color.rgb, saturation), color.a);"
kwin_scene_opengl: line 199:"}"
kwin_scene_opengl: line 200:""
kwin_scene_opengl: line 201:""
kwin_scene_opengl: line 202:"uniform sampler2D sampler;"
kwin_scene_opengl: line 203:"uniform vec4 modulation;"
kwin_scene_opengl: line 204:""
kwin_scene_opengl: line 205:"in vec2 texcoord0;"
kwin_scene_opengl: line 206:""
kwin_scene_opengl: line 207:"out vec4 fragColor;"
kwin_scene_opengl: line 208:""
kwin_scene_opengl: line 209:"void main()"
kwin_scene_opengl: line 210:"{"
kwin_scene_opengl: line 211:"    vec4 tex = texture(sampler, texcoord0);"
kwin_scene_opengl: line 212:"    tex = sourceEncodingToNitsInDestinationColorspace(tex);"
kwin_scene_opengl: line 213:"    tex = adjustSaturation(tex);"
kwin_scene_opengl: line 214:""
kwin_scene_opengl: line 215:"    // to preserve perceptual contrast, apply the inversion in gamma 2.2 space"
kwin_scene_opengl: line 216:"    tex = nitsToEncoding(tex, gamma22_EOTF, destinationReferenceLuminance);"
kwin_scene_opengl: line 217:"    tex.rgb /= max(0.001, tex.a);"
kwin_scene_opengl: line 218:"    tex.rgb = vec3(1.0) - tex.rgb;"
kwin_scene_opengl: line 219:"    tex *= modulation;"
kwin_scene_opengl: line 220:"    tex.rgb *= tex.a;"
kwin_scene_opengl: line 221:"    tex = encodingToNits(tex, gamma22_EOTF, destinationReferenceLuminance);"
kwin_scene_opengl: line 222:""
kwin_scene_opengl: line 223:"    fragColor = nitsToDestinationEncoding(tex);"
kwin_scene_opengl: line 224:"}"
kwin_scene_opengl: line 225:""
kwin_scene_opengl: line 226:""
Comment 2 Bug Janitor Service 2024-10-08 19:48:05 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/6579
Comment 3 Nicolas Fella 2024-10-08 19:57:30 UTC
Git commit 7b512872f97425f3aefa61f3c06bb0950f60724e by Nicolas Fella.
Committed on 08/10/2024 at 19:46.
Pushed by nicolasfella into branch 'master'.

plugins/systembell: Adapt shader to color management changes

M  +2    -2    src/plugins/systembell/shaders/invert.frag
M  +2    -2    src/plugins/systembell/shaders/invert_core.frag

https://invent.kde.org/plasma/kwin/-/commit/7b512872f97425f3aefa61f3c06bb0950f60724e
Comment 4 Nicolas Fella 2024-10-08 20:18:31 UTC
Git commit d3e360c5f0a8b4f05f7f9ab1cac68a8d7376ae2c by Nicolas Fella.
Committed on 08/10/2024 at 19:58.
Pushed by nicolasfella into branch 'Plasma/6.2'.

plugins/systembell: Adapt shader to color management changes
(cherry picked from commit 7b512872f97425f3aefa61f3c06bb0950f60724e)

M  +2    -2    src/plugins/systembell/shaders/invert.frag
M  +2    -2    src/plugins/systembell/shaders/invert_core.frag

https://invent.kde.org/plasma/kwin/-/commit/d3e360c5f0a8b4f05f7f9ab1cac68a8d7376ae2c