[kwin] [Bug 524038] HDR ICC profile in KWin 6.7.4 crushes PQ blacks and compresses midtones

[email protected]
Newsgroups gmane.comp.kde.devel.bugs
Message-ID <[email protected]/>
https://bugs.kde.org/show_bug.cgi?id=524038

--- Comment #6 from [email protected] ---
I traced this through KWin 6.7.4 source and found three concrete problems. The
same code is still present on current KWin master.

For context, we are developing PGenerator+, a display calibration and pattern
generation system. These measurements use its Native Wayland patch application,
which submits HDR patches through Wayland rather than X11 or an SDR
compatibility path. The tested profile is an Argyll-generated ICC v2.2 display
profile, not v4. Its B2A0 tag is a 16-bit mft2 transform with a 33x33x33 cLUT
and 2048-entry input and output tables.

1. The DRM output checks the SDR profile source before attaching the HDR
profile.

In src/backends/drm/drm_output.cpp, DrmOutput::queueChanges() tests
m_nextState->colorProfileSource. When HDR is active it should test
hdrColorProfileSource. On this system the HDR source was ICC while the SDR
source was sRGB, so KWin called setIccProfile(nullptr). Changing only the
unused SDR source to ICC changed the measured HDR result from 30%=0.76,
50%=51.4, 100%=307.9 cd/m2 to 30%=6.37, 50%=56.7, 100%=249.5 cd/m2. This
confirms that the SDR setting incorrectly controls whether the HDR profile
pointer reaches the shadow render path.

A minimal correction is:

const auto profileSource = hdr ? m_nextState->hdrColorProfileSource :
m_nextState->colorProfileSource;

2. KWin does not fall back from B2A1 to B2A0.

The tested Argyll profile contains B2A0 but no B2A1. IccProfile::BToATag()
returns null for relative and absolute colorimetric intents when B2A1 is
absent. KWin then uses matrix/TRC instead of the profile cLUT. ICC transform
precedence requires trying B2A0 before falling back to matrix/TRC when the
intent-specific transform is unavailable. BToATag() should return B2A0 when
B2A1 is absent.

3. The ICC shader rejects this Argyll mft2 BToA transform.

parseBToATag() prepends a ColorMultiplier for ICC XYZ encoding. LittleCMS
removes the identity matrix stage from this Argyll mft2 tag, leaving these
operations:

ColorMultiplier, ColorTransformation, ColorLUT3D, ColorTransformation

IccShader::setProfile() accepts an optional ColorTransformation or ColorMatrix
first, but not ColorMultiplier. It leaves the operations unconsumed, returns
false, and KWin repeatedly logs:

Could not represent ICC profile in the ICC shader!

I confirmed this with a B2A1 probe profile whose cLUT forces solid red. The
displayed patch remained neutral while the journal logged the shader error
every frame. KWin's existing Framework 13 LUT test does not expose this because
that test profile has a non-identity matrix stage, which absorbs the initial
multiplier during ColorPipeline optimization.

The shader can handle this case by consuming an initial ColorMultiplier and
left-multiplying it into toXYZD50 before the B curves. setUniforms() also
should not silently continue with stale or default shader state when
setProfile() fails for an ordinary profile.

ICC v2.2 does not have a named ST 2084 transfer-function tag. The profile
represents the device transform with sampled curves and the cLUT. That
limitation does not explain this failure: applying this same B2A0 cLUT directly
in the PGenerator+ Native Wayland application measured the expected PQ
response, including 20%=2.42, 30%=10.03, 50%=92.54 and 100%=307.73 cd/m2. With
KWin profile handling, the same patches measured 30%=0.76, 50%=51.43 and
100%=307.87 cd/m2.

I prepared a small candidate source patch for the wrong HDR source check, B2A0
fallback and initial ColorMultiplier handling. It passes git diff checks. I
could not compile KWin on the development machine because it does not have the
required ECM 6.26 development package.

-- 
You are receiving this mail because:
You are watching all bug changes.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.