w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.44k stars 657 forks source link

[css-color-hdr] Add interpolation between multiple values of dynamic-range-limit #10271

Open ccameron-chromium opened 4 months ago

ccameron-chromium commented 4 months ago

This came up when writing WPT tests for dynamic-range-limit.

The dynamic-range-limit specification allows for interpolation between two dynamic-range-limit values by the dynamic-range-limit-mix function. It was pointed out that interpolation between multiple different values may happen implicitly during animation.

The syntax chosen in the spec lends itself to fixing this issue fairly simply. The current syntax is

  dynamic-range-limit-mix() = dynamic-range-limit-mix( [ <ident> && <percentage [0,100]>? ]#{2})

The suggestion that I was given was to change this to

  dynamic-range-limit-mix() = dynamic-range-limit-mix( [ <ident> && <percentage [0,100]> ]+)

Example: Halfway between standard and high.

  dynamic-range-limit-mix(standard 50%, high 50%)

This is the same as the existing syntax.

Example: One-fifth between constrained-high and dynamic-range-limit-mix(standard 40%, high 60%):

  dynamic-range-limit-mix(constrained-high 20%,  dynamic-range-limit-mix(standard 40%, high 60%) 80%)

this simplifies to

  dynamic-range-limit-mix(standard 32%, high 48%, constrained-high 20%)

Notes

In the syntax we didn't allow percentages to be omitted (cause it can get a bit difficult to define more than one unspecified value, unlike color-mix which has natural definitions).

If the sum of the arguments' percentages is 0%, then the function fails.

The arguments' percentages are normalized so that they add to 100%.

The percent for standard, high, and constrained-high is computed as the of the weighted sum of its percents in each argument.

I'll try to put together a patch that does this.

tabatkins commented 4 months ago

Actually, I think it would be preferable to switch the dynamic-range-limit-mix() function's grammar to match that of the mix-*() family of functions (and ideally switch the name order as well, to mix-dynamic-range-limit()).

In other words:


mix-dynamic-range-limit( <progress>, <'dynamic-range-limit'>, <'dynamic-range-limit'> )
sboukortt commented 4 months ago

Actually, I think it would be preferable to switch the dynamic-range-limit-mix() function's grammar to match that of the mix-*() family of functions (and ideally switch the name order as well, to mix-dynamic-range-limit()).

In other words:

mix-dynamic-range-limit( <progress>, <'dynamic-range-limit'>, <'dynamic-range-limit'> )

Thank you for the feedback. Out of curiosity, may I ask about the name change? calc-mix, color-mix, etc. seem to have the -mix at the end – would we change those as well?

ccameron-chromium commented 4 months ago

I think the hard part is is defining what is the computed value for this sort of thing:

    mix-dynamic-range-limit(
        40%,
        mix-dynamic-range-limit(20%, standard, high),
        mix-dynamic-range-limit(30%, standard, constrained-high));

The math of this is: 0.6*(0.8*standard + 0.2*high) + 0.4*(0.7*standard + 0.3*constrained-high)). If we have a two-argument functional, then we need to somehow nest these together, and it starts to feel a bit messy.

The syntax that @svgeesus suggested extends well to handle this, by just allowing one to say that that evaluates to:

    mix-dynamic-range(standard 76%, high 12%, constrained-high 12%)
gregbenz commented 2 months ago

Is there a way this might be implemented to allow absolute HDR headroom limits which would affect the rendering, yet still keep the source site blind to the output in order to ensure anti-fingerprinting objectives are met?

For example, it may be ideal to allow up to 2 stops of headroom for HDR content alongside SDR. The other proposed mechanisms would either cause unnecessary limitations below that target, or may allow brighter results if the display has an unusually large amount of headroom (which could apply now with certain Windows SDR brightness slider settings, or with future brighter displays).

svgeesus commented 2 months ago

Thank you for the feedback. Out of curiosity, may I ask about the name change? calc-mix, color-mix, etc. seem to have the -mix at the end – would we change those as well?

No, color-mix() is widely implemented and changing the name would be a pointless waste of time at this stage

it would be preferable to switch the dynamic-range-limit-mix() function's grammar to match that of the mix-*() family of functions (and ideally switch the name order as well, to mix-dynamic-range-limit()).

I note that, following the link, this is still called calc-mix() so I guess we do have consistency again.

tabatkins commented 1 month ago

Yes, the current naming convention is indeed *-mix(). I guess I'd just misremembered when I made that comment.