Add extended sRGB linear known transfer function
Based upon the wording in https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_gl_colorspace_scrgb_linear.txt
This can be achieved already by using linear + set luminances, however not all compositors will implement that, but probably want to support this TF as it is very commonly used in games and desktop applications.
Signed-off-by: Joshua Ashton joshua@froggi.es
Merge request reports
Activity
mentioned in merge request wayland/wayland-protocols!14 (merged)
This doesn't change anything about
extended_target_volume
, clients can only really rely on being able to use colors outside of the rec.709 gamut with scRGB if that's supported.set_luminances
is not something every compositor can (if fixed function hw is involved) or wants to support though, and I think it's entirely reasonable not to require it for scRGB.Ah yes, good point, as you need negatives to represent stuff outside Rec.709.
But yes, set_luminances still stands
Edited by Autumn AshtonI just noticed that if we do !51 (merged) - clamping pixel values to the valid range - then linear +
set_luminances
is not actually enough to implement scRGBProposed in !84 (merged) .
After talking to @swick, the point about
extended_target_volume
is as follows.I have heard that gamescope does not want to support
set_luminances
because it wants to be able to pre-generate all color transformation LUTs in advance. This means it can only support a fixed enumerated list of image descriptions.set_luminances
has free parameters instead.Support for windows-scRGB requires the ability to handle negative color channel (optical) values. Support for negative optical values is indicated to clients with the
extended_target_volume
feature flag. That flag requires support forset_mastering_display_primaries
as well, and the MDCV has no enumeration, it's all free parameters. The fixed list of image descriptions is insufficient to advertiseextended_target_volume
.This leads to one of two things:
- The compositor advertises
extended_target_volume
but ignores MDCV, or - the compositor makes windows-scRGB clients rely on undefined behavior by not advertising
extended_target_volume
.
Neither is good, but both are workable if you use only apps that expect gamescope specifically.
- The compositor advertises
- Resolved by Pekka Paalanen
mentioned in merge request !83 (merged)
368 368 used here for HLG assume a 1000 cd/m² display. 369 369 </description> 370 370 </entry> 371 <entry name="ext_srgb_linear" value="14"> 372 <description summary="linear display-referred scRGB color space"> 373 Transfer characteristics as defined by 374 - IEC 61966-2-2:2003 - Comment on lines +372 to +374
Does IEC 61966-2-2:2003 also define 1.0 = 80 cd/m²? Does it allow normalized values beyond [-0.5, 7.5]?
Maybe this should be named and explicitly defined as Windows (10? 11?) behavior of their scRGB? Maybe Microsoft even has a freely accessible spec?
I'm getting the feeling that IEC 61966-2-2:2003 and Windows are two different scRGB specs.
That "color space" is incorrect in the description, this is a transfer function.
mentioned in merge request !84 (merged)
376 The expected mapping is such that a color value of (1.0, 1.0, 1.0) 377 corresponds to a luminance level of 80 nits on a standardized studio 378 monitor. 379 As the color value per channel goes beyond 1.0 and up to 125.0, the 380 corresponding luminance levels also increase linearly to 381 a maximum of 10000 nits. 382 383 Equivalent to EGL_EXT_gl_colorspace_scrgb_linear in OpenGL and 384 VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT in Vulkan. 385 386 This TF implies these default luminances 387 - primary color volume minimum: 0 cd/m² 388 - primary color volume maximum: 80 cd/m² 389 - reference white: 80 cd/m² 390 </description> 391 </entry> 371 <entry name="ext_srgb_linear" value="14"> 372 <description summary="linear display-referred scRGB color space"> 373 Transfer characteristics as defined by 374 - IEC 61966-2-2:2003 375 376 The expected mapping is such that a color value of (1.0, 1.0, 1.0) 377 corresponds to a luminance level of 80 nits on a standardized studio 378 monitor. 379 As the color value per channel goes beyond 1.0 and up to 125.0, the 380 corresponding luminance levels also increase linearly to 381 a maximum of 10000 nits. 382 383 Equivalent to EGL_EXT_gl_colorspace_scrgb_linear in OpenGL and 384 VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT in Vulkan. 385 386 This TF implies these default luminances 387 - primary color volume minimum: 0 cd/m² 388 - primary color volume maximum: 80 cd/m² 389 - reference white: 80 cd/m² 390 </description> 391 </entry> 371 <entry name="ext_linear_80" value="14"> 372 <description summary="extended linear TF with fixed luminance"> 373 This is the linear transfer function with extended domain, 374 defined over all finite real values, negative included. 375 376 The expected mapping is such that a color value of (1.0, 1.0, 1.0) 377 corresponds to a luminance level of 80 nits on a standardized studio 378 monitor. 379 As the color value per channel goes beyond 1.0 and up to 125.0, the 380 corresponding luminance levels also increase linearly to 381 a maximum of 10000 nits. 382 This is intended to be equivalent to the Windows 10 definition of 383 the linear transfer characteristic for scRGB. 384 385 Equivalent to EGL_EXT_gl_colorspace_scrgb_linear in OpenGL and 386 VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT in Vulkan. 387 388 This TF implies these default luminances 389 - primary color volume minimum: 0 cd/m² 390 - primary color volume maximum: 80 cd/m² 391 - reference white: 80 cd/m² 392 </description> 393 </entry> I propose the name
ext_linear_80
to put this apart fromlinear
andext_linear
which do not define 0.0 = 0 cd/m² and 1.0 = 80 cd/m².The EGL ext spec refers to IEC 61966-2-2:2003 for "details on scRGB color space". Since we are defining a transfer characteristic, the primaries and the white point do not matter. As I don't currently have access to IEC 61966-2-2:2003 I'm not sure what it defines. Wikipedia claims it uses the range [-0.5, 7.5), so it does not go up to 125.0. I also doubt it specifies 1.0 = 80 cd/m². These conventions that are in the core of a transfer characteristic are defined elsewhere, so I propose to drop the reference to IEC 61966-2-2:2003.
From IRC on Oct 10-11:
< swick[m]> pq: with ext_linear_80 would you then still want linear to have a different default luminance of 0?
That is another discussion.
< swick[m]> I also still don't get how I'm supposed to understand infinite contrast
< swick[m]> you can argue that only a subset should be used via the mastering luminances but they are not required
When MDCV luminances are not given, they are defaulted to those of the primary color volume.
< swick[m]> Windows maps that to PQ which means you could probably use the PQ black level here to get the right semantics?
Where is PQ black level defined? I have only seen BT.2100 saying the display black level should be less or equal to 0.005 cd/m².
@Zamundaaa told me that some displays, when taking the minimum luminance from EDID, converting that to PQ code point and sending it to display, will result in significantly brighter pixels than the said minimum luminance. This is contrary to what I assumed how PQ with its "absoluteness" works.
< swick[m]> but then again IIRC, the 80 from there gets mapped to 203(?) in PQ so that doesn't really make sense either
< swick[m]> maybe it makes sense to put the black level at (PQ black level) * (203/80) so code value 0 in ext_linear_80 gets mapped to the PQ black level when 80 nits in ext_linear_80 gets mapped to 203 nits in PQ
< swick[m]> eh, (PQ black level) * (80/203)
< swick[m]> which is ~0.002 instead of the 0.005 from PQ
< zamundaaa[m]> <swick[m]> "but then again IIRC, the 80 from..." <- No, nothing gets mapped on Windows
< zamundaaa[m]> 1 nit encoded in scRGB means that it outputs 1 nit in PQ to the screen
< swick[m]> ah well, then just define it to be PQ black level
< swick[m]> that makes it easier
< swick[m]> pq: and why is reference white at 80 when that maps to pq 80 on windows and there 203 is the reference white?
Because windows maps 1.0 to 80 cd/m², hence reference white must equal primary color volume max luminance and both must equal 80 cd/m². This is the point of having
ext_linear_80
.@Zamundaaa, that brings us back to !78 (comment 2561733) .
I guess I was mislead by the mapping of sRGB to scRGB, where sRGB reference white is at 1.0. IOW, when Windows maps sRGB to scRGB for HDR display, it will multiply the optical sRGB values by RW/80 rather than taking them as scRGB directly (RW = reference white cd/m²)?
Do I understand correctly that
ext_linear_80
needs to explicitly say that the reference white is unknown? Or set it to 203 cd/m² with a note that it is a guess that may be incorrect? Or that Windows passes these luminance values as-is to a BT.2100/PQ sink?linear
ext_linear
ext_linear_80
domain [0, 1] real numbers real numbers min cd/m² 0.2 0 0 max cd/m² 80 80 80 ref cd/m² 80 80 unknown Is this what we need?
Curiously,
EGL_EXT_gl_colorspace_scrgb_linear
!= Windows scRGB. But you also don't use EGL on Windows, you use WGL instead? So up to Wine to map this correctly.I didn't find Vulkan or Khronos Data Format Specification saying anything towards Windows scRGB, so I presume they match
EGL_EXT_gl_colorspace_scrgb_linear
instead. This raises the question of how doesVK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
work on Windows.I guess I was mislead by the mapping of sRGB to scRGB, where sRGB reference white is at 1.0. IOW, when Windows maps sRGB to scRGB for HDR display, it will multiply the optical sRGB values by RW/80 rather than taking them as scRGB directly (RW = reference white cd/m²)?
Yes.
Do I understand correctly that
ext_linear_80
needs to explicitly say that the reference white is unknown? Or set it to 203 cd/m² with a note that it is a guess that may be incorrect? Or that Windows passes these luminance values as-is to a BT.2100/PQ sink?Yeah, I think we should just have a
ext_windows_scrgb
with the reference luminance specified as unknown, and 203 cd/m² as a recommendation for how compositors can deal with it.Curiously,
EGL_EXT_gl_colorspace_scrgb_linear
!= Windows scRGB. But you also don't use EGL on Windows, you use WGL instead? So up to Wine to map this correctly.I would be surprised if it behaved any different depending on the API, it'll all map down to the same Windows API.
I didn't find Vulkan or Khronos Data Format Specification saying anything towards Windows scRGB, so I presume they match
EGL_EXT_gl_colorspace_scrgb_linear
instead. This raises the question of how doesVK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
work on Windows.It works the same way as what we've been discussing this entire time - it just ignores the reference luminance and re-encodes the whole thing with PQ for the screen.
It does raise the question for what Mesa should do, emulate the Windows behavior or do proper scRGB... but on the protocol level we really just have to offer the choice and let Mesa and Wine deal with it.
Right. I'm still caught on the inconsistency.
EGL_EXT_gl_colorspace_scrgb_linear
says:For each color channel, the floating-point values of 0.0 and 1.0 still correspond to sRGB chromaticities and luminance levels. [...] The expected mapping is such that a color value of (1.0, 1.0, 1.0) corresponds to a luminance level of 80 nits on a standardized studio monitor.
Presumably the "standardized studio monitor" is in a standardized viewing environment where that 80 cd/m² applies literally.
If scRGB is taken to PQ as-is, but sRGB is first multiplied by RW/80, then it is impossible to "correspond to sRGB [...] luminance levels" unless RW = 80.
Ok, I think I'm starting to understand what this is about. That's the difference we want to represent: relative vs. PQ-absolute luminance:
- Relative luminance systems have the reference white at optical code point (1.0, 1.0, 1.0), and the reference white is monitor and environment dependent. The window system can apply the reference levels when converting to a PQ monitor signal.
- PQ-absolute luminance (Windows) systems pass the signal as-is to a monitor. The reference levels are set in the application and never communicated to the window system, hence a translation layer like Wine cannot forward the luminance levels from the app, nor can it correctly guess or assume them.
The application set reference levels may be non-optimal for the monitor and the environment, and the end user may or may not want to have a global adjustment to them. Separating the two cases into different TFs lets compositors handle them differently as necessary:
- A normal contrast setting changing the reference white level of all relative luminance content.
- In addition to above or alternatively, a PQ contrast setting for all PQ-absolute luminance content.
Another potential difference in handling them is linear vs. logarithmic scaling (multiplier vs. gamma correction), maybe depending on how close to Windows behavior a compositor wants to be.
FTR, from IRC today, @swick strongly disagrees with this. He says the handling of the unknown (reference white level) should not be dumped to the compositors, and that everything a compositor might do can already be done at the client side by crafting a different image description by the help of
set_luminances
.He believes that if some use cases really cannot be implemented well without compositor support, he would very much prefer them to be contained to Wine (e.g. via the wine shell wayland protocol idea).
Further pondering on whether
ext_linear_80
or windows-scRGB special case should exist at all...I would like to draw equivalence between windows-scRGB and PQ encoded contents in terms of luminance levels, but @swick pointed out that while PQ encoded content can usually be assumed to be PQ reference viewing conditions referred, windows-scRGB might be that or display-at-hand referred or neither. So another way to pose the dilemma, that also encompasses PQ, is to ask "referred to which display"?
That question is supposed to be approximately answered by
set_luminances
request. It has two issues:- I hear that not everyone wants to implement
set_luminances
: gamescope generates all transformations at start-up, so cannot yet support free parameters. They want the possible values enumerated instead, and the proposal here is using the TF enum for that purpose. - Indicating display-at-hand referred luminances is complicated. One would need to get the luminance levels from the output or surface-preferred image description, and set them in one's own.(*) The reference white level cannot currently be set to "unknown" as a shorthand for this.
(*) Getting the actual luminance levels would be the right thing to do, as one cannot render for it otherwise. However, as said before, Windows games tend to ignore that and offer their own settings instead. However, I do think the client (Wine, Proton, SDL, etc.) should strive to do this, even if the game ignores the value.
Display-at-hand referred content has a fundamental problem of its own: since the content is said to be rendered for the display at hand, compositor contrast settings would have no effect on it. Yet, I hear that compositor settings should apply regardless. That's a conflict by definition. The solution is to never claim display-at-hand reference if compositor settings should apply. Claim reference to some other display instead, adjust the application settings to render for that display, and let the compositor translate the image to the display-at-hand. Which other display? BT.2100/PQ reference viewing conditions seem like a good bet. They are used with PQ encoded content, and Windows transcodes windows-scRGB to PQ signal as-is.
Now I've circled back to setting reference white at 203 cd/m² for windows-scRGB, and trusting that any discrepancy between that and the app can be fixed in app settings, and any discrepancy between that and the display-at-hand is globally fixed in the compositor. However, it's not exactly back to square one: a compositor can still have separate contrast settings for relative and PQ-absolute luminance contents. We don't need a new TF code to differentiate between them. If someone wants PQ content to be sent to monitor as-is, they only need to adjust the PQ-absolute contrast accordingly, once.
The new TF code would be just for an enumeration of supported
set_luminances
parameters. And only for gamescope?I think a minimum viable implementation of
set_luminances
would be a single multiplier in optical space. Black-point compensation would remove the need of applying an offset. OTOH, that does not help if one wants to use a pre-computed LUT for electrical-to-electrical transformation.
Compromise proposition (again):
Define
ext_linear_80
with default reference white equal to BT.2100/PQ viewing conditions. Do not allow unknown reference levels.Would that be acceptable?
- I hear that not everyone wants to implement
FTR, now I do think this proposal is good to have, and is not replaced by e.g. !84 (merged) . What to do with the other linear variants are other discussions.
I'm starting to think that the initial phrasing "linear display-referred scRGB color space" in the TF enumeration was actually intended to convey all of
- linear TF
- windows-scRGB luminances
- windows-scRGB target color volume (MDCV)
It doesn't fit the parametric API design. The TF was meant to be just a TF. Luminance defaults kind of can be counted in, because PQ is TF with luminance defined. But MDCV has nothing to do with a TF.
Do we want to hack windows-scRGB in the parametric API like this?
Or should we have a third factory API: enumerated image descriptions, where windows-scRGB as a whole is defined with a single enum entry?
Or should we introduce enumerated target color volumes in the parametric API?
!89 (merged) is my proposal to tackle this, and make it clearly a separate definition without complicating the parametric factory.
mentioned in commit pq/wayland-protocols@a70c8529
mentioned in commit pq/wayland-protocols@7bb40689
mentioned in merge request !89 (merged)
mentioned in commit pq/wayland-protocols@b14bb437
Closing as !89 (merged) landed.