diff options
author | 2024-06-04 03:28:39 +0000 | |
---|---|---|
committer | 2024-06-05 19:07:28 +0000 | |
commit | 0d83185e4bc75d2c3163d066ba26f111ea0da0e8 (patch) | |
tree | d40e9faaa082801b446cca593dc4373a21628d29 | |
parent | 328a9f17435ca5908b0063011315ee0a246c76ff (diff) |
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
-rw-r--r-- | libs/hwui/effects/GainmapRenderer.cpp | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/libs/hwui/effects/GainmapRenderer.cpp b/libs/hwui/effects/GainmapRenderer.cpp index 0a30c6c14c4c..eac03609d72f 100644 --- a/libs/hwui/effects/GainmapRenderer.cpp +++ b/libs/hwui/effects/GainmapRenderer.cpp @@ -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,8 +191,10 @@ 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) - ->makeWithColorFilter(colorXformSdrToGainmap); + 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 = @@ -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); |