Loading libs/renderengine/Android.bp +5 −1 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,10 @@ cc_defaults { "libui", "libui", "libutils", "libutils", ], ], static_libs: [ "libtonemap", ], local_include_dirs: ["include"], local_include_dirs: ["include"], export_include_dirs: ["include"], export_include_dirs: ["include"], } } Loading Loading @@ -97,7 +101,7 @@ filegroup { "skia/filters/GaussianBlurFilter.cpp", "skia/filters/GaussianBlurFilter.cpp", "skia/filters/KawaseBlurFilter.cpp", "skia/filters/KawaseBlurFilter.cpp", "skia/filters/LinearEffect.cpp", "skia/filters/LinearEffect.cpp", "skia/filters/StretchShaderFactory.cpp" "skia/filters/StretchShaderFactory.cpp", ], ], } } Loading libs/renderengine/benchmark/Android.bp +6 −2 Original line number Original line Diff line number Diff line Loading @@ -23,7 +23,10 @@ package { cc_benchmark { cc_benchmark { name: "librenderengine_bench", name: "librenderengine_bench", defaults: ["skia_deps", "surfaceflinger_defaults"], defaults: [ "skia_deps", "surfaceflinger_defaults", ], srcs: [ srcs: [ "main.cpp", "main.cpp", "Codec.cpp", "Codec.cpp", Loading @@ -32,6 +35,7 @@ cc_benchmark { ], ], static_libs: [ static_libs: [ "librenderengine", "librenderengine", "libtonemap", ], ], cflags: [ cflags: [ "-DLOG_TAG=\"RenderEngineBench\"", "-DLOG_TAG=\"RenderEngineBench\"", Loading libs/renderengine/skia/filters/LinearEffect.cpp +36 −162 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <SkString.h> #include <SkString.h> #include <tonemap/tonemap.h> #include <utils/Trace.h> #include <utils/Trace.h> #include <optional> #include <optional> Loading @@ -32,6 +33,11 @@ namespace android { namespace renderengine { namespace renderengine { namespace skia { namespace skia { static aidl::android::hardware::graphics::common::Dataspace toAidlDataspace( ui::Dataspace dataspace) { return static_cast<aidl::android::hardware::graphics::common::Dataspace>(dataspace); } static void generateEOTF(ui::Dataspace dataspace, SkString& shader) { static void generateEOTF(ui::Dataspace dataspace, SkString& shader) { switch (dataspace & HAL_DATASPACE_TRANSFER_MASK) { switch (dataspace & HAL_DATASPACE_TRANSFER_MASK) { case HAL_DATASPACE_TRANSFER_ST2084: case HAL_DATASPACE_TRANSFER_ST2084: Loading Loading @@ -127,156 +133,10 @@ static void generateLuminanceScalesForOOTF(ui::Dataspace inputDataspace, SkStrin default: default: shader.append(R"( shader.append(R"( float3 ScaleLuminance(float3 xyz) { float3 ScaleLuminance(float3 xyz) { return xyz * in_inputMaxLuminance; return xyz * in_libtonemap_inputMaxLuminance; } )"); break; } } static void generateToneMapInterpolation(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace, SkString& shader) { switch (inputDataspace & HAL_DATASPACE_TRANSFER_MASK) { case HAL_DATASPACE_TRANSFER_ST2084: case HAL_DATASPACE_TRANSFER_HLG: switch (outputDataspace & HAL_DATASPACE_TRANSFER_MASK) { case HAL_DATASPACE_TRANSFER_ST2084: shader.append(R"( float3 ToneMap(float3 xyz) { return xyz; } )"); break; case HAL_DATASPACE_TRANSFER_HLG: // PQ has a wider luminance range (10,000 nits vs. 1,000 nits) than HLG, so // we'll clamp the luminance range in case we're mapping from PQ input to HLG // output. shader.append(R"( float3 ToneMap(float3 xyz) { return clamp(xyz, 0.0, 1000.0); } )"); break; default: // Here we're mapping from HDR to SDR content, so interpolate using a Hermitian // polynomial onto the smaller luminance range. shader.append(R"( float3 ToneMap(float3 xyz) { float maxInLumi = in_inputMaxLuminance; float maxOutLumi = in_displayMaxLuminance; float nits = xyz.y; // if the max input luminance is less than what we can output then // no tone mapping is needed as all color values will be in range. if (maxInLumi <= maxOutLumi) { return xyz; } else { // three control points const float x0 = 10.0; const float y0 = 17.0; float x1 = maxOutLumi * 0.75; float y1 = x1; float x2 = x1 + (maxInLumi - x1) / 2.0; float y2 = y1 + (maxOutLumi - y1) * 0.75; // horizontal distances between the last three control points float h12 = x2 - x1; float h23 = maxInLumi - x2; // tangents at the last three control points float m1 = (y2 - y1) / h12; float m3 = (maxOutLumi - y2) / h23; float m2 = (m1 + m3) / 2.0; if (nits < x0) { // scale [0.0, x0] to [0.0, y0] linearly float slope = y0 / x0; return xyz * slope; } else if (nits < x1) { // scale [x0, x1] to [y0, y1] linearly float slope = (y1 - y0) / (x1 - x0); nits = y0 + (nits - x0) * slope; } else if (nits < x2) { // scale [x1, x2] to [y1, y2] using Hermite interp float t = (nits - x1) / h12; nits = (y1 * (1.0 + 2.0 * t) + h12 * m1 * t) * (1.0 - t) * (1.0 - t) + (y2 * (3.0 - 2.0 * t) + h12 * m2 * (t - 1.0)) * t * t; } else { // scale [x2, maxInLumi] to [y2, maxOutLumi] using Hermite interp float t = (nits - x2) / h23; nits = (y2 * (1.0 + 2.0 * t) + h23 * m2 * t) * (1.0 - t) * (1.0 - t) + (maxOutLumi * (3.0 - 2.0 * t) + h23 * m3 * (t - 1.0)) * t * t; } } // color.y is greater than x0 and is thus non-zero return xyz * (nits / xyz.y); } )"); break; } break; default: switch (outputDataspace & HAL_DATASPACE_TRANSFER_MASK) { case HAL_DATASPACE_TRANSFER_ST2084: case HAL_DATASPACE_TRANSFER_HLG: // Map from SDR onto an HDR output buffer // Here we use a polynomial curve to map from [0, displayMaxLuminance] onto // [0, maxOutLumi] which is hard-coded to be 3000 nits. shader.append(R"( float3 ToneMap(float3 xyz) { const float maxOutLumi = 3000.0; const float x0 = 5.0; const float y0 = 2.5; float x1 = in_displayMaxLuminance * 0.7; float y1 = maxOutLumi * 0.15; float x2 = in_displayMaxLuminance * 0.9; float y2 = maxOutLumi * 0.45; float x3 = in_displayMaxLuminance; float y3 = maxOutLumi; float c1 = y1 / 3.0; float c2 = y2 / 2.0; float c3 = y3 / 1.5; float nits = xyz.y; if (nits <= x0) { // scale [0.0, x0] to [0.0, y0] linearly float slope = y0 / x0; return xyz * 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; } // xyz.y is greater than x0 and is thus non-zero return xyz * (nits / xyz.y); } } )"); )"); break; break; default: // For completeness, this is tone-mapping from SDR to SDR, where this is just a // no-op. shader.append(R"( float3 ToneMap(float3 xyz) { return xyz; } )"); break; } break; } } } } Loading @@ -300,7 +160,7 @@ static void generateLuminanceNormalizationForOOTF(ui::Dataspace outputDataspace, default: default: shader.append(R"( shader.append(R"( float3 NormalizeLuminance(float3 xyz) { float3 NormalizeLuminance(float3 xyz) { return xyz / in_displayMaxLuminance; return xyz / in_libtonemap_displayMaxLuminance; } } )"); )"); break; break; Loading @@ -309,19 +169,22 @@ static void generateLuminanceNormalizationForOOTF(ui::Dataspace outputDataspace, static void generateOOTF(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace, static void generateOOTF(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace, SkString& shader) { SkString& shader) { // Input uniforms shader.append(tonemap::getToneMapper() shader.append(R"( ->generateTonemapGainShaderSkSL(toAidlDataspace(inputDataspace), uniform float in_displayMaxLuminance; toAidlDataspace(outputDataspace)) uniform float in_inputMaxLuminance; .c_str()); )"); generateLuminanceScalesForOOTF(inputDataspace, shader); generateLuminanceScalesForOOTF(inputDataspace, shader); generateToneMapInterpolation(inputDataspace, outputDataspace, shader); generateLuminanceNormalizationForOOTF(outputDataspace, shader); generateLuminanceNormalizationForOOTF(outputDataspace, shader); shader.append(R"( shader.append(R"( float3 OOTF(float3 xyz) { float3 OOTF(float3 linearRGB, float3 xyz) { return NormalizeLuminance(ToneMap(ScaleLuminance(xyz))); float3 scaledLinearRGB = ScaleLuminance(linearRGB); float3 scaledXYZ = ScaleLuminance(xyz); float gain = libtonemap_LookupTonemapGain(scaledLinearRGB, scaledXYZ); return NormalizeLuminance(scaledXYZ * gain); } } )"); )"); } } Loading Loading @@ -399,7 +262,9 @@ static void generateEffectiveOOTF(bool undoPremultipliedAlpha, SkString& shader) )"); )"); } } shader.append(R"( shader.append(R"( c.rgb = OETF(ToRGB(OOTF(ToXYZ(EOTF(c.rgb))))); float3 linearRGB = EOTF(c.rgb); float3 xyz = ToXYZ(linearRGB); c.rgb = OETF(ToRGB(OOTF(linearRGB, xyz))); )"); )"); if (undoPremultipliedAlpha) { if (undoPremultipliedAlpha) { shader.append(R"( shader.append(R"( Loading Loading @@ -465,11 +330,20 @@ sk_sp<SkShader> createLinearEffectShader(sk_sp<SkShader> shader, const LinearEff colorTransform * mat4(outputColorSpace.getXYZtoRGB()); colorTransform * mat4(outputColorSpace.getXYZtoRGB()); } } effectBuilder.uniform("in_displayMaxLuminance") = maxDisplayLuminance; tonemap::Metadata metadata{.displayMaxLuminance = maxDisplayLuminance, // If the input luminance is unknown, use display luminance (aka, no-op any luminance changes) // If the input luminance is unknown, use display luminance (aka, // This will be the case for eg screenshots in addition to uncalibrated displays // no-op any luminance changes) effectBuilder.uniform("in_inputMaxLuminance") = // This will be the case for eg screenshots in addition to maxLuminance > 0 ? maxLuminance : maxDisplayLuminance; // uncalibrated displays .contentMaxLuminance = maxLuminance > 0 ? maxLuminance : maxDisplayLuminance}; const auto uniforms = tonemap::getToneMapper()->generateShaderSkSLUniforms(metadata); for (const auto& uniform : uniforms) { effectBuilder.uniform(uniform.name.c_str()).set(uniform.value.data(), uniform.value.size()); } return effectBuilder.makeShader(nullptr, false); return effectBuilder.makeShader(nullptr, false); } } Loading libs/renderengine/tests/Android.bp +5 −1 Original line number Original line Diff line number Diff line Loading @@ -23,7 +23,10 @@ package { cc_test { cc_test { name: "librenderengine_test", name: "librenderengine_test", defaults: ["skia_deps", "surfaceflinger_defaults"], defaults: [ "skia_deps", "surfaceflinger_defaults", ], test_suites: ["device-tests"], test_suites: ["device-tests"], srcs: [ srcs: [ "RenderEngineTest.cpp", "RenderEngineTest.cpp", Loading @@ -36,6 +39,7 @@ cc_test { "libgmock", "libgmock", "librenderengine", "librenderengine", "librenderengine_mocks", "librenderengine_mocks", "libtonemap", ], ], shared_libs: [ shared_libs: [ Loading libs/tonemap/Android.bp 0 → 100644 +37 −0 Original line number Original line Diff line number Diff line // Copyright 2021 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package { // See: http://go/android-license-faq // A large-scale-change added 'default_applicable_licenses' to import // all of the 'license_kinds' from "frameworks_native_license" // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], } cc_library_static { name: "libtonemap", vendor_available: true, export_include_dirs: ["include"], local_include_dirs: ["include"], shared_libs: [ "android.hardware.graphics.common-V3-ndk", ], srcs: [ "tonemap.cpp", ], } Loading
libs/renderengine/Android.bp +5 −1 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,10 @@ cc_defaults { "libui", "libui", "libutils", "libutils", ], ], static_libs: [ "libtonemap", ], local_include_dirs: ["include"], local_include_dirs: ["include"], export_include_dirs: ["include"], export_include_dirs: ["include"], } } Loading Loading @@ -97,7 +101,7 @@ filegroup { "skia/filters/GaussianBlurFilter.cpp", "skia/filters/GaussianBlurFilter.cpp", "skia/filters/KawaseBlurFilter.cpp", "skia/filters/KawaseBlurFilter.cpp", "skia/filters/LinearEffect.cpp", "skia/filters/LinearEffect.cpp", "skia/filters/StretchShaderFactory.cpp" "skia/filters/StretchShaderFactory.cpp", ], ], } } Loading
libs/renderengine/benchmark/Android.bp +6 −2 Original line number Original line Diff line number Diff line Loading @@ -23,7 +23,10 @@ package { cc_benchmark { cc_benchmark { name: "librenderengine_bench", name: "librenderengine_bench", defaults: ["skia_deps", "surfaceflinger_defaults"], defaults: [ "skia_deps", "surfaceflinger_defaults", ], srcs: [ srcs: [ "main.cpp", "main.cpp", "Codec.cpp", "Codec.cpp", Loading @@ -32,6 +35,7 @@ cc_benchmark { ], ], static_libs: [ static_libs: [ "librenderengine", "librenderengine", "libtonemap", ], ], cflags: [ cflags: [ "-DLOG_TAG=\"RenderEngineBench\"", "-DLOG_TAG=\"RenderEngineBench\"", Loading
libs/renderengine/skia/filters/LinearEffect.cpp +36 −162 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <SkString.h> #include <SkString.h> #include <tonemap/tonemap.h> #include <utils/Trace.h> #include <utils/Trace.h> #include <optional> #include <optional> Loading @@ -32,6 +33,11 @@ namespace android { namespace renderengine { namespace renderengine { namespace skia { namespace skia { static aidl::android::hardware::graphics::common::Dataspace toAidlDataspace( ui::Dataspace dataspace) { return static_cast<aidl::android::hardware::graphics::common::Dataspace>(dataspace); } static void generateEOTF(ui::Dataspace dataspace, SkString& shader) { static void generateEOTF(ui::Dataspace dataspace, SkString& shader) { switch (dataspace & HAL_DATASPACE_TRANSFER_MASK) { switch (dataspace & HAL_DATASPACE_TRANSFER_MASK) { case HAL_DATASPACE_TRANSFER_ST2084: case HAL_DATASPACE_TRANSFER_ST2084: Loading Loading @@ -127,156 +133,10 @@ static void generateLuminanceScalesForOOTF(ui::Dataspace inputDataspace, SkStrin default: default: shader.append(R"( shader.append(R"( float3 ScaleLuminance(float3 xyz) { float3 ScaleLuminance(float3 xyz) { return xyz * in_inputMaxLuminance; return xyz * in_libtonemap_inputMaxLuminance; } )"); break; } } static void generateToneMapInterpolation(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace, SkString& shader) { switch (inputDataspace & HAL_DATASPACE_TRANSFER_MASK) { case HAL_DATASPACE_TRANSFER_ST2084: case HAL_DATASPACE_TRANSFER_HLG: switch (outputDataspace & HAL_DATASPACE_TRANSFER_MASK) { case HAL_DATASPACE_TRANSFER_ST2084: shader.append(R"( float3 ToneMap(float3 xyz) { return xyz; } )"); break; case HAL_DATASPACE_TRANSFER_HLG: // PQ has a wider luminance range (10,000 nits vs. 1,000 nits) than HLG, so // we'll clamp the luminance range in case we're mapping from PQ input to HLG // output. shader.append(R"( float3 ToneMap(float3 xyz) { return clamp(xyz, 0.0, 1000.0); } )"); break; default: // Here we're mapping from HDR to SDR content, so interpolate using a Hermitian // polynomial onto the smaller luminance range. shader.append(R"( float3 ToneMap(float3 xyz) { float maxInLumi = in_inputMaxLuminance; float maxOutLumi = in_displayMaxLuminance; float nits = xyz.y; // if the max input luminance is less than what we can output then // no tone mapping is needed as all color values will be in range. if (maxInLumi <= maxOutLumi) { return xyz; } else { // three control points const float x0 = 10.0; const float y0 = 17.0; float x1 = maxOutLumi * 0.75; float y1 = x1; float x2 = x1 + (maxInLumi - x1) / 2.0; float y2 = y1 + (maxOutLumi - y1) * 0.75; // horizontal distances between the last three control points float h12 = x2 - x1; float h23 = maxInLumi - x2; // tangents at the last three control points float m1 = (y2 - y1) / h12; float m3 = (maxOutLumi - y2) / h23; float m2 = (m1 + m3) / 2.0; if (nits < x0) { // scale [0.0, x0] to [0.0, y0] linearly float slope = y0 / x0; return xyz * slope; } else if (nits < x1) { // scale [x0, x1] to [y0, y1] linearly float slope = (y1 - y0) / (x1 - x0); nits = y0 + (nits - x0) * slope; } else if (nits < x2) { // scale [x1, x2] to [y1, y2] using Hermite interp float t = (nits - x1) / h12; nits = (y1 * (1.0 + 2.0 * t) + h12 * m1 * t) * (1.0 - t) * (1.0 - t) + (y2 * (3.0 - 2.0 * t) + h12 * m2 * (t - 1.0)) * t * t; } else { // scale [x2, maxInLumi] to [y2, maxOutLumi] using Hermite interp float t = (nits - x2) / h23; nits = (y2 * (1.0 + 2.0 * t) + h23 * m2 * t) * (1.0 - t) * (1.0 - t) + (maxOutLumi * (3.0 - 2.0 * t) + h23 * m3 * (t - 1.0)) * t * t; } } // color.y is greater than x0 and is thus non-zero return xyz * (nits / xyz.y); } )"); break; } break; default: switch (outputDataspace & HAL_DATASPACE_TRANSFER_MASK) { case HAL_DATASPACE_TRANSFER_ST2084: case HAL_DATASPACE_TRANSFER_HLG: // Map from SDR onto an HDR output buffer // Here we use a polynomial curve to map from [0, displayMaxLuminance] onto // [0, maxOutLumi] which is hard-coded to be 3000 nits. shader.append(R"( float3 ToneMap(float3 xyz) { const float maxOutLumi = 3000.0; const float x0 = 5.0; const float y0 = 2.5; float x1 = in_displayMaxLuminance * 0.7; float y1 = maxOutLumi * 0.15; float x2 = in_displayMaxLuminance * 0.9; float y2 = maxOutLumi * 0.45; float x3 = in_displayMaxLuminance; float y3 = maxOutLumi; float c1 = y1 / 3.0; float c2 = y2 / 2.0; float c3 = y3 / 1.5; float nits = xyz.y; if (nits <= x0) { // scale [0.0, x0] to [0.0, y0] linearly float slope = y0 / x0; return xyz * 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; } // xyz.y is greater than x0 and is thus non-zero return xyz * (nits / xyz.y); } } )"); )"); break; break; default: // For completeness, this is tone-mapping from SDR to SDR, where this is just a // no-op. shader.append(R"( float3 ToneMap(float3 xyz) { return xyz; } )"); break; } break; } } } } Loading @@ -300,7 +160,7 @@ static void generateLuminanceNormalizationForOOTF(ui::Dataspace outputDataspace, default: default: shader.append(R"( shader.append(R"( float3 NormalizeLuminance(float3 xyz) { float3 NormalizeLuminance(float3 xyz) { return xyz / in_displayMaxLuminance; return xyz / in_libtonemap_displayMaxLuminance; } } )"); )"); break; break; Loading @@ -309,19 +169,22 @@ static void generateLuminanceNormalizationForOOTF(ui::Dataspace outputDataspace, static void generateOOTF(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace, static void generateOOTF(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace, SkString& shader) { SkString& shader) { // Input uniforms shader.append(tonemap::getToneMapper() shader.append(R"( ->generateTonemapGainShaderSkSL(toAidlDataspace(inputDataspace), uniform float in_displayMaxLuminance; toAidlDataspace(outputDataspace)) uniform float in_inputMaxLuminance; .c_str()); )"); generateLuminanceScalesForOOTF(inputDataspace, shader); generateLuminanceScalesForOOTF(inputDataspace, shader); generateToneMapInterpolation(inputDataspace, outputDataspace, shader); generateLuminanceNormalizationForOOTF(outputDataspace, shader); generateLuminanceNormalizationForOOTF(outputDataspace, shader); shader.append(R"( shader.append(R"( float3 OOTF(float3 xyz) { float3 OOTF(float3 linearRGB, float3 xyz) { return NormalizeLuminance(ToneMap(ScaleLuminance(xyz))); float3 scaledLinearRGB = ScaleLuminance(linearRGB); float3 scaledXYZ = ScaleLuminance(xyz); float gain = libtonemap_LookupTonemapGain(scaledLinearRGB, scaledXYZ); return NormalizeLuminance(scaledXYZ * gain); } } )"); )"); } } Loading Loading @@ -399,7 +262,9 @@ static void generateEffectiveOOTF(bool undoPremultipliedAlpha, SkString& shader) )"); )"); } } shader.append(R"( shader.append(R"( c.rgb = OETF(ToRGB(OOTF(ToXYZ(EOTF(c.rgb))))); float3 linearRGB = EOTF(c.rgb); float3 xyz = ToXYZ(linearRGB); c.rgb = OETF(ToRGB(OOTF(linearRGB, xyz))); )"); )"); if (undoPremultipliedAlpha) { if (undoPremultipliedAlpha) { shader.append(R"( shader.append(R"( Loading Loading @@ -465,11 +330,20 @@ sk_sp<SkShader> createLinearEffectShader(sk_sp<SkShader> shader, const LinearEff colorTransform * mat4(outputColorSpace.getXYZtoRGB()); colorTransform * mat4(outputColorSpace.getXYZtoRGB()); } } effectBuilder.uniform("in_displayMaxLuminance") = maxDisplayLuminance; tonemap::Metadata metadata{.displayMaxLuminance = maxDisplayLuminance, // If the input luminance is unknown, use display luminance (aka, no-op any luminance changes) // If the input luminance is unknown, use display luminance (aka, // This will be the case for eg screenshots in addition to uncalibrated displays // no-op any luminance changes) effectBuilder.uniform("in_inputMaxLuminance") = // This will be the case for eg screenshots in addition to maxLuminance > 0 ? maxLuminance : maxDisplayLuminance; // uncalibrated displays .contentMaxLuminance = maxLuminance > 0 ? maxLuminance : maxDisplayLuminance}; const auto uniforms = tonemap::getToneMapper()->generateShaderSkSLUniforms(metadata); for (const auto& uniform : uniforms) { effectBuilder.uniform(uniform.name.c_str()).set(uniform.value.data(), uniform.value.size()); } return effectBuilder.makeShader(nullptr, false); return effectBuilder.makeShader(nullptr, false); } } Loading
libs/renderengine/tests/Android.bp +5 −1 Original line number Original line Diff line number Diff line Loading @@ -23,7 +23,10 @@ package { cc_test { cc_test { name: "librenderengine_test", name: "librenderengine_test", defaults: ["skia_deps", "surfaceflinger_defaults"], defaults: [ "skia_deps", "surfaceflinger_defaults", ], test_suites: ["device-tests"], test_suites: ["device-tests"], srcs: [ srcs: [ "RenderEngineTest.cpp", "RenderEngineTest.cpp", Loading @@ -36,6 +39,7 @@ cc_test { "libgmock", "libgmock", "librenderengine", "librenderengine", "librenderengine_mocks", "librenderengine_mocks", "libtonemap", ], ], shared_libs: [ shared_libs: [ Loading
libs/tonemap/Android.bp 0 → 100644 +37 −0 Original line number Original line Diff line number Diff line // Copyright 2021 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package { // See: http://go/android-license-faq // A large-scale-change added 'default_applicable_licenses' to import // all of the 'license_kinds' from "frameworks_native_license" // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], } cc_library_static { name: "libtonemap", vendor_available: true, export_include_dirs: ["include"], local_include_dirs: ["include"], shared_libs: [ "android.hardware.graphics.common-V3-ndk", ], srcs: [ "tonemap.cpp", ], }