diff options
author | Peiyong Lin <lpy@google.com> | 2018-05-23 16:52:29 -0700 |
---|---|---|
committer | Chia-I Wu <olv@google.com> | 2018-05-25 12:50:18 -0700 |
commit | 9a1b65566d8cfcd46b56c26ecda307d0266ad26a (patch) | |
tree | 9a0a5ef83932709162805e74e081d73a55cb0396 | |
parent | c61c0c1193d493f97f3a8657b75c5256a70aea3a (diff) | |
download | native-9a1b65566d8cfcd46b56c26ecda307d0266ad26a.tar.gz |
[RenderEngine] Add inverse tone mapper.
This patch inverse the tone mapping process from hardware composer to make sure
we have minimum brightness change when HDR video is being played.
BUG: 73825729
Test: Build, flash, watch Youtube HDR
Change-Id: I6dd73d520d316e2ae4a890211b7282053d9b8568
-rw-r--r-- | services/surfaceflinger/RenderEngine/ProgramCache.cpp | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp index 2808a1a912..5b61db9fbd 100644 --- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp +++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp @@ -345,11 +345,46 @@ void ProgramCache::generateToneMappingProcess(Formatter& fs, const Key& needs) { } break; default: - // TODO(73825729) We need to revert the tone mapping in - // hardware composer properly. + // inverse tone map; the output luminance can be up to maxOutLumi. fs << R"__SHADER__( highp vec3 ToneMap(highp vec3 color) { - return color; + const float maxOutLumi = 3000.0; + + const float x0 = 5.0; + const float y0 = 2.5; + float x1 = displayMaxLuminance * 0.7; + float y1 = maxOutLumi * 0.15; + float x2 = displayMaxLuminance * 0.9; + float y2 = maxOutLumi * 0.45; + float x3 = displayMaxLuminance; + float y3 = maxOutLumi; + + float c1 = y1 / 3.0; + float c2 = y2 / 2.0; + float c3 = y3 / 1.5; + + float nits = color.y; + + float scale; + if (nits <= x0) { + // scale [0.0, x0] to [0.0, y0] linearly + const float slope = y0 / x0; + nits *= slope; + } else if (nits <= x1) { + // scale [x0, x1] to [y0, y1] using a curve + float t = (nits - x0) / (x1 - x0); + nits = (1.0 - t) * (1.0 - t) * y0 + 2.0 * (1.0 - t) * t * c1 + t * t * y1; + } else if (nits <= x2) { + // scale [x1, x2] to [y1, y2] using a curve + float t = (nits - x1) / (x2 - x1); + nits = (1.0 - t) * (1.0 - t) * y1 + 2.0 * (1.0 - t) * t * c2 + t * t * y2; + } else { + // scale [x2, x3] to [y2, y3] using a curve + float t = (nits - x2) / (x3 - x2); + nits = (1.0 - t) * (1.0 - t) * y2 + 2.0 * (1.0 - t) * t * c3 + t * t * y3; + } + + return color * (nits / max(1e-6, color.y)); } )__SHADER__"; break; |