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

Commit 0d83185e authored by Alec Mouri's avatar Alec Mouri
Browse files

Short circuit the gainmap shader if we would not apply the gainmap

This is needed for correctness when authoring to a PDF. The gainmap
shader otherwise manually de-gammas into a working space to do the
gainmap math, then uses toLinearSrgb to re-gamma to the destination
space.

But, SkPicture records commands while being colorspace agnostic, so
manually de-gammaing means we never re-gamma, which has the effect over
crushing the resulting image.

This is probably also nice for performance too, because we avoid
sampling the gainmap and a bunch of math operations.

Bug: 341006313
Test: Photos > 1up > Print
Flag: EXEMPT low risk bug fix
Change-Id: Id2de97b112a8eff8ef56a802a3f44d83abdd6d41
parent 328a9f17
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ void DrawGainmapBitmap(SkCanvas* c, const sk_sp<const SkImage>& image, const SkR
#ifdef __ANDROID__

static constexpr char gGainmapSKSL[] = R"SKSL(
    uniform shader linearBase;
    uniform shader base;
    uniform shader gainmap;
    uniform colorFilter workingSpaceToLinearSrgb;
@@ -117,7 +118,11 @@ static constexpr char gGainmapSKSL[] = R"SKSL(
    }

    half4 main(float2 coord) {
        half4 S = base.eval(coord);
        if (W == 0.0) {
            return base.eval(coord);
        }

        half4 S = linearBase.eval(coord);
        half4 G = gainmap.eval(coord);
        if (gainmapIsAlpha == 1) {
            G = half4(G.a, G.a, G.a, 1.0);
@@ -186,9 +191,11 @@ private:
                SkColorFilterPriv::MakeColorSpaceXform(baseColorSpace, gainmapMathColorSpace);

        // The base image shader will convert into the color space in which the gainmap is applied.
        auto baseImageShader = baseImage->makeRawShader(tileModeX, tileModeY, samplingOptions)
        auto linearBaseImageShader = baseImage->makeRawShader(tileModeX, tileModeY, samplingOptions)
                                             ->makeWithColorFilter(colorXformSdrToGainmap);

        auto baseImageShader = baseImage->makeShader(tileModeX, tileModeY, samplingOptions);

        // The gainmap image shader will ignore any color space that the gainmap has.
        const SkMatrix gainmapRectToDstRect =
                SkMatrix::RectToRect(SkRect::MakeWH(gainmapImage->width(), gainmapImage->height()),
@@ -201,6 +208,7 @@ private:
        auto colorXformGainmapToDst = SkColorFilterPriv::MakeColorSpaceXform(
                gainmapMathColorSpace, SkColorSpace::MakeSRGBLinear());

        mBuilder.child("linearBase") = std::move(linearBaseImageShader);
        mBuilder.child("base") = std::move(baseImageShader);
        mBuilder.child("gainmap") = std::move(gainmapImageShader);
        mBuilder.child("workingSpaceToLinearSrgb") = std::move(colorXformGainmapToDst);