summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Peiyong Lin <lpy@google.com> 2018-03-21 19:14:35 -0700
committer Peiyong Lin <lpy@google.com> 2018-03-23 21:35:20 +0000
commit7c4d1286ca62db617f8f50b82ea692baf03bda1f (patch)
treec43b16b2d56ea5e4960b7c9a58381ae9465b293d
parent14c461a47806524f7bb51273df7d45fb8648b4b7 (diff)
[SurfaceFlinger] Fix HDR tone mapping.
Previously we tone mapped for all color channels, however, the correct way is to convert to XYZ color space, and only tone map the Y channel. BUG: 76220266 Test: Test with modified Youtube apk Change-Id: Ia00ab32b9d5d9f1d1128d57305ceabbdb68fffcd
-rw-r--r--services/surfaceflinger/RenderEngine/ProgramCache.cpp21
1 files changed, 13 insertions, 8 deletions
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 7a43ea92bd..6a34981174 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -305,15 +305,24 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) {
if (needs.hasToneMapping()) {
fs << R"__SHADER__(
- float ToneMapChannel(const float color) {
+ float CalculateY(const vec3 color) {
+ // BT2020 standard uses the unadjusted KR = 0.2627,
+ // KB = 0.0593 luminance interpretation for RGB conversion.
+ return color.r * 0.262700 + color.g * 0.677998 +
+ color.b * 0.059302;
+ }
+ vec3 ToneMap(const vec3 color) {
const float maxLumi = 10000.0;
const float maxMasteringLumi = 1000.0;
const float maxContentLumi = 1000.0;
const float maxInLumi = min(maxMasteringLumi, maxContentLumi);
const float maxOutLumi = 500.0;
+ // Calculate Y value in XYZ color space.
+ float colorY = CalculateY(color);
+
// convert to nits first
- float nits = color * maxLumi;
+ float nits = colorY * maxLumi;
// clamp to max input luminance
nits = clamp(nits, 0.0, maxInLumi);
@@ -360,12 +369,8 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) {
}
// convert back to [0.0, 1.0]
- return nits / maxOutLumi;
- }
-
- vec3 ToneMap(const vec3 color) {
- return vec3(ToneMapChannel(color.r), ToneMapChannel(color.g),
- ToneMapChannel(color.b));
+ float targetY = nits / maxOutLumi;
+ return color * (targetY / max(1e-6, colorY));
}
)__SHADER__";
} else {