Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Static Public Member Functions | List of all members
SkGainmapShader Class Reference

#include <SkGainmapShader.h>

Static Public Member Functions

static sk_sp< SkShaderMake (const sk_sp< const SkImage > &baseImage, const SkRect &baseRect, const SkSamplingOptions &baseSamplingOptions, const sk_sp< const SkImage > &gainmapImage, const SkRect &gainmapRect, const SkSamplingOptions &gainmapSamplingOptions, const SkGainmapInfo &gainmapInfo, const SkRect &dstRect, float dstHdrRatio, sk_sp< SkColorSpace > dstColorSpace)
 

Detailed Description

A gainmap shader will apply a gainmap to an base image using the math described alongside the definition of SkGainmapInfo.

Definition at line 25 of file SkGainmapShader.h.

Member Function Documentation

◆ Make()

sk_sp< SkShader > SkGainmapShader::Make ( const sk_sp< const SkImage > &  baseImage,
const SkRect baseRect,
const SkSamplingOptions baseSamplingOptions,
const sk_sp< const SkImage > &  gainmapImage,
const SkRect gainmapRect,
const SkSamplingOptions gainmapSamplingOptions,
const SkGainmapInfo gainmapInfo,
const SkRect dstRect,
float  dstHdrRatio,
sk_sp< SkColorSpace dstColorSpace 
)
static

Make a gainmap shader.

When sampling the base image baseImage, the rectangle baseRect will be sampled to map to the rectangle dstRect. Sampling will be done according to baseSamplingOptions.

When sampling the gainmap image gainmapImage, the rectangle gainmapRect will be sampled to map to the rectangle dstRect. Sampling will be done according to gainmapSamplingOptions.

The gainmap will be applied according to the HDR to SDR ratio specified in dstHdrRatio.

This shader must know the color space of the canvas that it will be rendered to. This color space must be specified in dstColorSpace. TODO(ccameron): Remove the need for dstColorSpace.

Definition at line 81 of file SkGainmapShader.cpp.

90 {
91 sk_sp<SkColorSpace> baseColorSpace =
92 baseImage->colorSpace() ? baseImage->refColorSpace() : SkColorSpace::MakeSRGB();
93
94 // Determine the color space in which the gainmap math is to be applied.
95 sk_sp<SkColorSpace> gainmapMathColorSpace =
96 gainmapInfo.fGainmapMathColorSpace
98 : baseColorSpace->makeLinearGamma();
99 if (!dstColorSpace) {
100 dstColorSpace = SkColorSpace::MakeSRGB();
101 }
102
103 // Compute the sampling transformation matrices.
104 const SkMatrix baseRectToDstRect = SkMatrix::RectToRect(baseRect, dstRect);
105 const SkMatrix gainmapRectToDstRect = SkMatrix::RectToRect(gainmapRect, dstRect);
106
107 // Compute the weight parameter that will be used to blend between the images.
108 float W = 0.f;
109 if (dstHdrRatio > gainmapInfo.fDisplayRatioSdr) {
110 if (dstHdrRatio < gainmapInfo.fDisplayRatioHdr) {
111 W = (std::log(dstHdrRatio) - std::log(gainmapInfo.fDisplayRatioSdr)) /
112 (std::log(gainmapInfo.fDisplayRatioHdr) -
113 std::log(gainmapInfo.fDisplayRatioSdr));
114 } else {
115 W = 1.f;
116 }
117 }
118
119 const bool baseImageIsHdr = (gainmapInfo.fBaseImageType == SkGainmapInfo::BaseImageType::kHDR);
120 if (baseImageIsHdr) {
121 W -= 1.f;
122 }
123
124 // Return the base image directly if the gainmap will not be applied at all.
125 if (W == 0.f) {
126 return baseImage->makeShader(baseSamplingOptions, &baseRectToDstRect);
127 }
128
129 // Create a color filter to transform from the base image's color space to the color space in
130 // which the gainmap is to be applied.
131 auto colorXformSdrToGainmap =
132 SkColorFilterPriv::MakeColorSpaceXform(baseColorSpace, gainmapMathColorSpace);
133
134 // Create a color filter to transform from the color space in which the gainmap is applied to
135 // the destination color space.
136 auto colorXformGainmapToDst =
137 SkColorFilterPriv::MakeColorSpaceXform(gainmapMathColorSpace, dstColorSpace);
138
139 // The base image shader will convert into the color space in which the gainmap is applied.
140 auto baseImageShader = baseImage->makeRawShader(baseSamplingOptions, &baseRectToDstRect)
141 ->makeWithColorFilter(colorXformSdrToGainmap);
142
143 // The gainmap image shader will ignore any color space that the gainmap has.
144 auto gainmapImageShader =
145 gainmapImage->makeRawShader(gainmapSamplingOptions, &gainmapRectToDstRect);
146
147 // Create the shader to apply the gainmap.
148 sk_sp<SkShader> gainmapMathShader;
149 {
151 const SkColor4f logRatioMin({std::log(gainmapInfo.fGainmapRatioMin.fR),
152 std::log(gainmapInfo.fGainmapRatioMin.fG),
153 std::log(gainmapInfo.fGainmapRatioMin.fB),
154 1.f});
155 const SkColor4f logRatioMax({std::log(gainmapInfo.fGainmapRatioMax.fR),
156 std::log(gainmapInfo.fGainmapRatioMax.fG),
157 std::log(gainmapInfo.fGainmapRatioMax.fB),
158 1.f});
159 const int noGamma =
160 gainmapInfo.fGainmapGamma.fR == 1.f &&
161 gainmapInfo.fGainmapGamma.fG == 1.f &&
162 gainmapInfo.fGainmapGamma.fB == 1.f;
163 const uint32_t colorTypeFlags = SkColorTypeChannelFlags(gainmapImage->colorType());
164 const int gainmapIsAlpha = colorTypeFlags == kAlpha_SkColorChannelFlag;
165 const int gainmapIsRed = colorTypeFlags == kRed_SkColorChannelFlag;
166 const int singleChannel = all_channels_equal(gainmapInfo.fGainmapGamma) &&
169 (colorTypeFlags == kGray_SkColorChannelFlag ||
170 colorTypeFlags == kAlpha_SkColorChannelFlag ||
171 colorTypeFlags == kRed_SkColorChannelFlag);
172 const SkColor4f& epsilonBase =
173 baseImageIsHdr ? gainmapInfo.fEpsilonHdr : gainmapInfo.fEpsilonSdr;
174 const SkColor4f& epsilonOther =
175 baseImageIsHdr ? gainmapInfo.fEpsilonSdr : gainmapInfo.fEpsilonHdr;
176 builder.child("base") = baseImageShader;
177 builder.child("gainmap") = gainmapImageShader;
178 builder.uniform("logRatioMin") = logRatioMin;
179 builder.uniform("logRatioMax") = logRatioMax;
180 builder.uniform("gainmapGamma") = gainmapInfo.fGainmapGamma;
181 builder.uniform("epsilonBase") = epsilonBase;
182 builder.uniform("epsilonOther") = epsilonOther;
183 builder.uniform("noGamma") = noGamma;
184 builder.uniform("singleChannel") = singleChannel;
185 builder.uniform("gainmapIsAlpha") = gainmapIsAlpha;
186 builder.uniform("gainmapIsRed") = gainmapIsRed;
187 builder.uniform("W") = W;
188 gainmapMathShader = builder.makeShader();
189 SkASSERT(gainmapMathShader);
190 }
191
192 // Return a shader that will apply the gainmap and then convert to the destination color space.
193 return gainmapMathShader->makeWithColorFilter(colorXformGainmapToDst);
194}
#define SkASSERT(cond)
Definition SkAssert.h:116
@ kRed_SkColorChannelFlag
Definition SkColor.h:239
@ kAlpha_SkColorChannelFlag
Definition SkColor.h:242
@ kGray_SkColorChannelFlag
Definition SkColor.h:243
static bool all_channels_equal(const SkColor4f &c)
static sk_sp< SkRuntimeEffect > gainmap_apply_effect()
static uint32_t SkColorTypeChannelFlags(SkColorType ct)
#define W
Definition aaa.cpp:17
static sk_sp< SkColorFilter > MakeColorSpaceXform(sk_sp< SkColorSpace > src, sk_sp< SkColorSpace > dst)
sk_sp< SkColorSpace > makeLinearGamma() const
static sk_sp< SkColorSpace > MakeSRGB()
SkColorSpace * colorSpace() const
Definition SkImage.cpp:156
sk_sp< SkShader > makeRawShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition SkImage.cpp:207
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition SkImage.cpp:179
SkColorType colorType() const
Definition SkImage.cpp:152
sk_sp< SkColorSpace > refColorSpace() const
Definition SkImage.cpp:158
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
Definition SkMatrix.h:157
sk_sp< SkShader > makeWithColorFilter(sk_sp< SkColorFilter >) const
Definition SkShader.cpp:43
SkColor4f fGainmapRatioMax
SkColor4f fEpsilonSdr
SkColor4f fGainmapGamma
sk_sp< SkColorSpace > fGainmapMathColorSpace
SkColor4f fGainmapRatioMin
BaseImageType fBaseImageType
float fDisplayRatioSdr
SkColor4f fEpsilonHdr
float fDisplayRatioHdr

The documentation for this class was generated from the following files: