Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b658b15c authored by Sally Qi's avatar Sally Qi
Browse files

[Lut shader] Fix gamma correction

to avoid color conversion, we de-gamma the image without changing the
primaries, after lut(s) shader being applied, we need to re-gamma it
back.

Bug: 329472856
Test: luts cts cases
Flag: android.hardware.flags.luts_api
Change-Id: I8c8a3b6d445d11efab4115c097d7eeb91d1be384
parent 44d6fff4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -544,7 +544,8 @@ sk_sp<SkShader> SkiaRenderEngine::createRuntimeEffectShader(
    }

    if (graphicBuffer && parameters.layer.luts) {
        shader = mLutShader.lutShader(shader, parameters.layer.luts);
        shader = mLutShader.lutShader(shader, parameters.layer.luts,
                                      toSkColorSpace(parameters.outputDataSpace));
    }

    if (parameters.requiresLinearEffect) {
+10 −19
Original line number Diff line number Diff line
@@ -169,7 +169,8 @@ sk_sp<SkShader> LutShader::generateLutShader(sk_sp<SkShader> input,
}

sk_sp<SkShader> LutShader::lutShader(sk_sp<SkShader>& input,
                                     std::shared_ptr<gui::DisplayLuts> displayLuts) {
                                     std::shared_ptr<gui::DisplayLuts> displayLuts,
                                     sk_sp<SkColorSpace> outColorSpace) {
    if (mBuilder == nullptr) {
        const static SkRuntimeEffect::Result instance = SkRuntimeEffect::MakeForShader(kShader);
        mBuilder = std::make_unique<SkRuntimeShaderBuilder>(instance.effect);
@@ -179,14 +180,11 @@ sk_sp<SkShader> LutShader::lutShader(sk_sp<SkShader>& input,
    if (fd.ok()) {
        // de-gamma the image without changing the primaries
        SkImage* baseImage = input->isAImage((SkMatrix*)nullptr, (SkTileMode*)nullptr);
        if (baseImage) {
            sk_sp<SkColorSpace> baseColorSpace =
                    baseImage->colorSpace() ? baseImage->refColorSpace() : SkColorSpace::MakeSRGB();
            sk_sp<SkColorSpace> gainmapMathColorSpace = baseColorSpace->makeLinearGamma();
            auto colorXformSdrToGainmap =
                    SkColorFilterPriv::MakeColorSpaceXform(baseColorSpace, gainmapMathColorSpace);
            input = input->makeWithColorFilter(colorXformSdrToGainmap);
        }
        sk_sp<SkColorSpace> baseColorSpace = baseImage && baseImage->colorSpace()
                ? baseImage->refColorSpace()
                : SkColorSpace::MakeSRGB();
        sk_sp<SkColorSpace> lutMathColorSpace = baseColorSpace->makeLinearGamma();
        input = input->makeWithWorkingColorSpace(lutMathColorSpace);

        auto& offsets = displayLuts->offsets;
        auto& lutProperties = displayLuts->lutProperties;
@@ -223,16 +221,9 @@ sk_sp<SkShader> LutShader::lutShader(sk_sp<SkShader>& input,
                                      lutProperties[i].samplingKey);
        }

        // re-gamma
        baseImage = input->isAImage((SkMatrix*)nullptr, (SkTileMode*)nullptr);
        if (baseImage) {
            sk_sp<SkColorSpace> baseColorSpace =
                    baseImage->colorSpace() ? baseImage->refColorSpace() : SkColorSpace::MakeSRGB();
            sk_sp<SkColorSpace> gainmapMathColorSpace = baseColorSpace->makeLinearGamma();
            auto colorXformGainmapToDst =
                    SkColorFilterPriv::MakeColorSpaceXform(gainmapMathColorSpace, baseColorSpace);
            input = input->makeWithColorFilter(colorXformGainmapToDst);
        }
        auto colorXformLutToDst =
                SkColorFilterPriv::MakeColorSpaceXform(lutMathColorSpace, outColorSpace);
        input = input->makeWithColorFilter(colorXformLutToDst);
    }
    return input;
}
+2 −2
Original line number Diff line number Diff line
@@ -28,8 +28,8 @@ namespace skia {

class LutShader {
public:
    sk_sp<SkShader> lutShader(sk_sp<SkShader>& input,
                              std::shared_ptr<gui::DisplayLuts> displayLuts);
    sk_sp<SkShader> lutShader(sk_sp<SkShader>& input, std::shared_ptr<gui::DisplayLuts> displayLuts,
                              sk_sp<SkColorSpace> outColorSpace);

private:
    sk_sp<SkShader> generateLutShader(sk_sp<SkShader> input, const std::vector<float>& buffers,