Commit c7eb73ac authored by hubbe's avatar hubbe Committed by Commit bot

First cut at making HDR content viewable on SDR display with color management.

Without this, HDR10 content is almost entirely black when color management is
turned on.

Review-Url: https://codereview.chromium.org/2300813002
Cr-Commit-Position: refs/heads/master@{#416374}
parent e3184756
...@@ -74,8 +74,13 @@ class GFX_EXPORT ColorSpace { ...@@ -74,8 +74,13 @@ class GFX_EXPORT ColorSpace {
// Chrome-specific values start at 1000. // Chrome-specific values start at 1000.
GAMMA24 = 1000, GAMMA24 = 1000,
// This is an ad-hoc transfer function that decodes SMPTE 2084 content
// into a 0-1 range more or less suitable for viewing on a non-hdr
// display.
SMPTEST2084_NON_HDR,
// TODO(hubbe): Need to store an approximation of the gamma function(s). // TODO(hubbe): Need to store an approximation of the gamma function(s).
CUSTOM = 1001, CUSTOM,
LAST = CUSTOM, LAST = CUSTOM,
}; };
......
...@@ -398,9 +398,39 @@ GFX_EXPORT float ToLinear(ColorSpace::TransferID id, float v) { ...@@ -398,9 +398,39 @@ GFX_EXPORT float ToLinear(ColorSpace::TransferID id, float v) {
case ColorSpace::TransferID::GAMMA24: case ColorSpace::TransferID::GAMMA24:
v = fmax(0.0f, v); v = fmax(0.0f, v);
return powf(v, 2.4f); return powf(v, 2.4f);
case ColorSpace::TransferID::SMPTEST2084_NON_HDR:
v = fmax(0.0f, v);
return fmin(2.3f * pow(v, 2.8f), v / 5.0f + 0.8f);
} }
} }
namespace {
// Assumes bt2020
float Luma(const ColorTransform::TriStim& c) {
return c.x() * 0.2627f + c.y() * 0.6780f + c.z() * 0.0593f;
}
};
GFX_EXPORT ColorTransform::TriStim ToLinear(ColorSpace::TransferID id,
ColorTransform::TriStim color) {
ColorTransform::TriStim ret(ToLinear(id, color.x()), ToLinear(id, color.y()),
ToLinear(id, color.z()));
if (id == ColorSpace::TransferID::SMPTEST2084_NON_HDR) {
if (Luma(ret) > 0.0) {
ColorTransform::TriStim smpte2084(
ToLinear(ColorSpace::TransferID::SMPTEST2084, color.x()),
ToLinear(ColorSpace::TransferID::SMPTEST2084, color.y()),
ToLinear(ColorSpace::TransferID::SMPTEST2084, color.z()));
smpte2084.Scale(Luma(ret) / Luma(smpte2084));
ret = smpte2084;
}
}
return ret;
}
GFX_EXPORT Transform GetTransferMatrix(ColorSpace::MatrixID id) { GFX_EXPORT Transform GetTransferMatrix(ColorSpace::MatrixID id) {
float Kr = 0.0f, Kb = 0.0f; float Kr = 0.0f, Kb = 0.0f;
switch (id) { switch (id) {
...@@ -509,6 +539,12 @@ class ColorSpaceToColorSpaceTransform : public ColorTransform { ...@@ -509,6 +539,12 @@ class ColorSpaceToColorSpaceTransform : public ColorTransform {
from_.transfer_ = ColorSpace::TransferID::GAMMA24; from_.transfer_ = ColorSpace::TransferID::GAMMA24;
break; break;
case ColorSpace::TransferID::SMPTEST2084:
// We don't have an HDR display, so replace SMPTE 2084 with something
// that returns ranges more or less suitable for a normal display.
from_.transfer_ = ColorSpace::TransferID::SMPTEST2084_NON_HDR;
break;
default: // Do nothing default: // Do nothing
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment