Flutter Engine
The Flutter Engine
Functions
GainmapShaderTest.cpp File Reference
#include <cmath>
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkShader.h"
#include "include/private/SkGainmapInfo.h"
#include "include/private/SkGainmapShader.h"
#include "tests/Test.h"

Go to the source code of this file.

Functions

static bool approx_equal (const SkColor4f &a, const SkColor4f &b)
 
static sk_sp< SkImagemake_1x1_image (sk_sp< SkColorSpace > imageColorSpace, SkAlphaType imageAlphaType, SkColor4f imageColor, sk_sp< SkColorSpace > imageColorColorSpace=SkColorSpace::MakeSRGBLinear())
 
static SkGainmapInfo simple_gainmap_info (float hdrRatioMax)
 
static SkColor4f draw_1x1_gainmap (sk_sp< SkImage > baseImage, sk_sp< SkImage > gainmapImage, const SkGainmapInfo &gainmapInfo, float dstRatio, sk_sp< SkColorSpace > dstColorSpace=SkColorSpace::MakeSRGB())
 
 DEF_TEST (GainmapShader_rects, r)
 
 DEF_TEST (GainmapShader_baseImageIsHdr, r)
 
 DEF_TEST (GainmapShader_colorSpace, r)
 
 DEF_TEST (GainmapShader_apple, r)
 

Function Documentation

◆ approx_equal()

static bool approx_equal ( const SkColor4f a,
const SkColor4f b 
)
static

Definition at line 27 of file GainmapShaderTest.cpp.

27 {
28 constexpr float kEpsilon = 1e-3f;
29 return std::abs(a.fR - b.fR) < kEpsilon && std::abs(a.fG - b.fG) < kEpsilon &&
30 std::abs(a.fB - b.fB) < kEpsilon && std::abs(a.fA - b.fA) < kEpsilon;
31}
static constexpr double kEpsilon
static bool b
struct MyStruct a[10]
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition: SkVx.h:707

◆ DEF_TEST() [1/4]

DEF_TEST ( GainmapShader_apple  ,
 
)

Definition at line 320 of file GainmapShaderTest.cpp.

320 {
321 constexpr SkColor4f kSdrColor = {0.25f, 0.5f, 1.f, 1.f};
322 const SkColor4f kGainmapColor = {0.0f, // The R channel will have a linear value of 0.0.
323 0.702250f, // The G channel will have a linear value of 0.5.
324 1.0f, // The B channel will have a linear value 0f 1.0.
325 1.f};
326
327 // Set the HDR headroom to 5.0.
328 const float kH = 5.f;
329
330 const SkColor4f kExpectedColor = {0.25f * (1 + (kH - 1) * 0.0f), // 0.25,
331 0.50f * (1 + (kH - 1) * 0.5f), // 0.5,
332 1.00f * (1 + (kH - 1) * 1.0f), // 5.0,
333 1.f};
334
335 auto sdrImage = make_1x1_image(SkColorSpace::MakeSRGB(), kOpaque_SkAlphaType, kSdrColor);
336 auto gainmapImage = make_1x1_image(nullptr, kOpaque_SkAlphaType, kGainmapColor);
337 SkGainmapInfo gainmapInfo = simple_gainmap_info(kH);
339
340 auto color = draw_1x1_gainmap(
341 sdrImage, gainmapImage, gainmapInfo, kH, SkColorSpace::MakeSRGBLinear());
342
343 // Note that (0.250, 1.548, 5.000) is *not* an acceptable answer here (even though it's sort-of
344 // close). That number is the result of not using the the Apple-compatible math.
345 REPORTER_ASSERT(r, approx_equal(color, kExpectedColor));
346}
static bool approx_equal(const SkColor4f &a, const SkColor4f &b)
static SkColor4f draw_1x1_gainmap(sk_sp< SkImage > baseImage, sk_sp< SkImage > gainmapImage, const SkGainmapInfo &gainmapInfo, float dstRatio, sk_sp< SkColorSpace > dstColorSpace=SkColorSpace::MakeSRGB())
static sk_sp< SkImage > make_1x1_image(sk_sp< SkColorSpace > imageColorSpace, SkAlphaType imageAlphaType, SkColor4f imageColor, sk_sp< SkColorSpace > imageColorColorSpace=SkColorSpace::MakeSRGBLinear())
static SkGainmapInfo simple_gainmap_info(float hdrRatioMax)
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
constexpr int kH
static sk_sp< SkColorSpace > MakeSRGB()
static sk_sp< SkColorSpace > MakeSRGBLinear()
DlColor color

◆ DEF_TEST() [2/4]

DEF_TEST ( GainmapShader_baseImageIsHdr  ,
 
)

Definition at line 190 of file GainmapShaderTest.cpp.

190 {
191 SkColor4f hdrColors[4][2] = {
192 {{1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 0.5f, 1.0f}},
193 {{1.0f, 0.5f, 1.0f, 1.0f}, {1.0f, 0.5f, 0.5f, 1.0f}},
194 {{0.5f, 1.0f, 1.0f, 1.0f}, {0.5f, 1.0f, 0.5f, 1.0f}},
195 {{0.5f, 0.5f, 1.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}},
196 };
198 hdrColors,
199 2 * sizeof(SkColor4f));
200 auto hdrImage = SkImages::RasterFromPixmap(hdrPixmap, nullptr, nullptr);
201 const auto hdrImageRect = SkRect::MakeXYWH(0.f, 0.f, 2.f, 4.f);
202
203 // The top pixel indicates to gain only red, and the bottom pixel indicates to gain everything
204 // except red.
205 SkColor4f gainmapColors[2][1] = {
206 {{1.0f, 0.0f, 0.0f, 1.f}},
207 {{0.0f, 1.0f, 1.0f, 1.f}},
208 };
210 gainmapColors,
211 1 * sizeof(SkColor4f));
212 auto gainmapImage = SkImages::RasterFromPixmap(gainmapPixmap, nullptr, nullptr);
213 const auto gainmapImageRect = SkRect::MakeXYWH(0.f, 0.f, 1.f, 2.f);
214 SkGainmapInfo gainmapInfo = simple_gainmap_info(2.f);
216 gainmapInfo.fEpsilonSdr[0] = 0.1f;
217
218 SkImageInfo canvasInfo = SkImageInfo::Make(
220 SkBitmap canvasBitmap;
221 canvasBitmap.allocPixels(canvasInfo);
222 canvasBitmap.eraseColor(SK_ColorTRANSPARENT);
223 const auto canvasRect = SkRect::MakeXYWH(0.f, 0.f, 2.f, 4.f);
224
225 sk_sp<SkShader> shader = SkGainmapShader::Make(hdrImage,
226 hdrImageRect,
228 gainmapImage,
229 gainmapImageRect,
231 gainmapInfo,
232 canvasRect,
233 gainmapInfo.fDisplayRatioSdr,
234 canvasInfo.refColorSpace());
236 paint.setShader(shader);
237 SkCanvas canvas(canvasBitmap);
238 canvas.drawRect(canvasRect, paint);
239
240 // Compute and compare the expected colors.
241 // This is linearToSRGB(srgbToLinear(1.0)*0.5) = linearToSRGB(0.5).
242 constexpr float k10G = 0.7353569830524495f;
243 // This is linearToSRGB(srgbToLinear(0.5)*0.5)
244 constexpr float k05G = 0.3607802138332792f;
245 // The 'R' component also has a fEpsilonSdr set.
246 // This is linearToSRGB(srgbToLinear(1.0)*0.5-0.1) = linearToSRGB(0.4).
247 constexpr float kR10G = 0.6651850846308363f;
248 // This is linearToSRGB(srgbToLinear(0.5)-0.1)
249 // The gain map is 0.f (no gain), but there are still affectd by the offset.
250 constexpr float kR05G = 0.371934685412575f;
251 SkColor4f expectedColors[4][2] = {
252 {{kR10G, 1.0f, 1.0f, 1.0f}, {kR10G, 1.0f, 0.5f, 1.0f}},
253 {{kR10G, 0.5f, 1.0f, 1.0f}, {kR10G, 0.5f, 0.5f, 1.0f}},
254 {{kR05G, k10G, k10G, 1.0f}, {kR05G, k10G, k05G, 1.0f}},
255 {{kR05G, k05G, k10G, 1.0f}, {kR05G, k05G, k05G, 1.0f}},
256 };
257 for (int y = 0; y < 4; ++y) {
258 for (int x = 0; x < 2; ++x) {
259 const auto color = canvasBitmap.getColor4f(x, y);
260 const auto& expected = expectedColors[y][x];
262 approx_equal(color, expected),
263 "color (%.3f %.3f %.3f %.3f) does not match expected color (%.3f %.3f "
264 "%.3f %.3f) at "
265 "pixel (%d, %d)",
266 color.fR,
267 color.fG,
268 color.fB,
269 color.fA,
270 expected.fR,
271 expected.fG,
272 expected.fB,
273 expected.fA,
274 x,
275 y);
276 }
277 }
278}
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
@ kRGBA_F32_SkColorType
pixel using C float for red, green, blue, alpha; in 128-bit word
Definition: SkColorType.h:40
constexpr SkColor SK_ColorTRANSPARENT
Definition: SkColor.h:99
void allocPixels(const SkImageInfo &info, size_t rowBytes)
Definition: SkBitmap.cpp:258
SkColor4f getColor4f(int x, int y) const
Definition: SkBitmap.h:893
void eraseColor(SkColor4f) const
Definition: SkBitmap.cpp:442
static sk_sp< SkShader > 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)
const Paint & paint
Definition: color_source.cc:38
double y
double x
SK_API sk_sp< SkImage > RasterFromPixmap(const SkPixmap &pixmap, RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext)
SkSamplingOptions(SkFilterMode::kLinear))
SkColor4f fEpsilonSdr
Definition: SkGainmapInfo.h:55
BaseImageType fBaseImageType
Definition: SkGainmapInfo.h:75
float fDisplayRatioSdr
Definition: SkGainmapInfo.h:65
sk_sp< SkColorSpace > refColorSpace() const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659

◆ DEF_TEST() [3/4]

DEF_TEST ( GainmapShader_colorSpace  ,
 
)

Definition at line 282 of file GainmapShaderTest.cpp.

282 {
283 auto sdrColorSpace =
287
288 constexpr SkColor4f kSdrColor = {0.25f, 0.5f, 1.f, 1.f};
289 constexpr SkColor4f kGainmapColor = {
290 0.0f, // The sRGB G channel will have a exp2(0.0)=1.000 gain.
291 0.5f, // The sRGB B channel will have a exp2(0.5)=1.414 gain.
292 1.0f, // The sRGB R channel will have a exp2(1.0)=2.000 gain.
293 1.f};
294 constexpr SkColor4f kExpectedColor = {0.5f, 0.5f, 1.414f, 1.f};
295
296 auto sdrImage = make_1x1_image(sdrColorSpace, kOpaque_SkAlphaType, kSdrColor);
297 auto gainmapImage = make_1x1_image(
298 gainmapColorSpace, kOpaque_SkAlphaType, kGainmapColor, gainmapColorSpace);
299 SkGainmapInfo gainmapInfo = simple_gainmap_info(2.f);
300
301 auto color = draw_1x1_gainmap(
302 sdrImage, gainmapImage, gainmapInfo, gainmapInfo.fDisplayRatioHdr, dstColorSpace);
303 REPORTER_ASSERT(r, approx_equal(color, kExpectedColor));
304
305 // Setting fGainmapMathColorSpace to the base image's color space does not change the result.
306 gainmapInfo.fGainmapMathColorSpace = sdrColorSpace;
308 sdrImage, gainmapImage, gainmapInfo, gainmapInfo.fDisplayRatioHdr, dstColorSpace);
309 REPORTER_ASSERT(r, approx_equal(color, kExpectedColor));
310
311 // Setting fGainmapMathColorSpace ot a different color space does change the result.
312 gainmapInfo.fGainmapMathColorSpace =
315 sdrImage, gainmapImage, gainmapInfo, gainmapInfo.fDisplayRatioHdr, dstColorSpace);
316 REPORTER_ASSERT(r, !approx_equal(color, kExpectedColor));
317}
sk_sp< SkColorSpace > makeColorSpin() const
static sk_sp< SkColorSpace > MakeRGB(const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
static constexpr skcms_Matrix3x3 kSRGB
Definition: SkColorSpace.h:67
static constexpr skcms_Matrix3x3 kRec2020
Definition: SkColorSpace.h:93
static constexpr skcms_Matrix3x3 kDisplayP3
Definition: SkColorSpace.h:87
static constexpr skcms_TransferFunction k2Dot2
Definition: SkColorSpace.h:48
static constexpr skcms_TransferFunction kHLG
Definition: SkColorSpace.h:60
static constexpr skcms_TransferFunction kPQ
Definition: SkColorSpace.h:57
sk_sp< SkColorSpace > fGainmapMathColorSpace
Definition: SkGainmapInfo.h:95
float fDisplayRatioHdr
Definition: SkGainmapInfo.h:66

◆ DEF_TEST() [4/4]

DEF_TEST ( GainmapShader_rects  ,
 
)

Definition at line 100 of file GainmapShaderTest.cpp.

100 {
101 SkColor4f sdrColors[5][2] = {
102 {{-1.f, -1.f, -1.f, 1.0f}, {-1.f, -1.f, -1.f, 1.0f}},
103 {{1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 0.5f, 1.0f}},
104 {{1.0f, 0.5f, 1.0f, 1.0f}, {1.0f, 0.5f, 0.5f, 1.0f}},
105 {{0.5f, 1.0f, 1.0f, 1.0f}, {0.5f, 1.0f, 0.5f, 1.0f}},
106 {{0.5f, 0.5f, 1.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}},
107 };
109 sdrColors,
110 2 * sizeof(SkColor4f));
111 auto sdrImage = SkImages::RasterFromPixmap(sdrPixmap, nullptr, nullptr);
112 const auto sdrImageRect = SkRect::MakeXYWH(0.f, 1.f, 2.f, 4.f);
113
114 // The top pixel indicates to gain only red, and the bottom pixel indicates to gain everything
115 // except red.
116 SkColor4f gainmapColors[2][2] = {
117 {{-1.f, -1.f, -1.f, 1.f}, {1.0f, 0.0f, 0.0f, 1.f}},
118 {{-1.f, -1.f, -1.f, 1.f}, {0.0f, 1.0f, 1.0f, 1.f}},
119 };
121 gainmapColors,
122 2 * sizeof(SkColor4f));
123 auto gainmapImage = SkImages::RasterFromPixmap(gainmapPixmap, nullptr, nullptr);
124 const auto gainmapImageRect = SkRect::MakeXYWH(1.f, 0.f, 1.f, 2.f);
125 SkGainmapInfo gainmapInfo = simple_gainmap_info(2.f);
126 gainmapInfo.fEpsilonHdr[0] = 0.1f;
127
128 SkImageInfo canvasInfo = SkImageInfo::Make(
130 SkBitmap canvasBitmap;
131 canvasBitmap.allocPixels(canvasInfo);
132 canvasBitmap.eraseColor(SK_ColorTRANSPARENT);
133 const auto canvasRect = SkRect::MakeXYWH(1.f, 1.f, 2.f, 4.f);
134
135 sk_sp<SkShader> shader = SkGainmapShader::Make(sdrImage,
136 sdrImageRect,
138 gainmapImage,
139 gainmapImageRect,
141 gainmapInfo,
142 canvasRect,
143 gainmapInfo.fDisplayRatioHdr,
144 canvasInfo.refColorSpace());
146 paint.setShader(shader);
147 SkCanvas canvas(canvasBitmap);
148 canvas.drawRect(canvasRect, paint);
149
150 // Compute and compare the expected colors.
151 // This is linearToSRGB(srgbToLinear(1.0)*2.0) = linearToSRGB(2.0).
152 constexpr float k10G = 1.353256028586302f;
153 // This is linearToSRGB(srgbToLinear(0.5)*2.0)
154 constexpr float k05G = 0.6858361015012847f;
155 // The 'R' component also has a fEpsilonHdr set.
156 // This is linearToSRGB(srgbToLinear(1.0)*2.0-0.1) = linearToSRGB(1.9).
157 constexpr float kR10G = 1.3234778541409058f;
158 // This is linearToSRGB(srgbToLinear(0.5)-0.1)
159 // The gain map is 0.f (no gain), but there are still affectd by the offset.
160 constexpr float kR05G = 0.371934685412575f;
161 SkColor4f expectedColors[4][2] = {
162 {{kR10G, 1.0f, 1.0f, 1.0f}, {kR10G, 1.0f, 0.5f, 1.0f}},
163 {{kR10G, 0.5f, 1.0f, 1.0f}, {kR10G, 0.5f, 0.5f, 1.0f}},
164 {{kR05G, k10G, k10G, 1.0f}, {kR05G, k10G, k05G, 1.0f}},
165 {{kR05G, k05G, k10G, 1.0f}, {kR05G, k05G, k05G, 1.0f}},
166 };
167 for (int y = 0; y < 4; ++y) {
168 for (int x = 0; x < 2; ++x) {
169 const auto color = canvasBitmap.getColor4f(x + 1, y + 1);
170 const auto& expected = expectedColors[y][x];
172 approx_equal(color, expected),
173 "color (%.3f %.3f %.3f %.3f) does not match expected color (%.3f %.3f "
174 "%.3f %.3f) at "
175 "pixel (%d, %d)",
176 color.fR,
177 color.fG,
178 color.fB,
179 color.fA,
180 expected.fR,
181 expected.fG,
182 expected.fB,
183 expected.fA,
184 x,
185 y);
186 }
187 }
188}
SkColor4f fEpsilonHdr
Definition: SkGainmapInfo.h:56

◆ draw_1x1_gainmap()

static SkColor4f draw_1x1_gainmap ( sk_sp< SkImage baseImage,
sk_sp< SkImage gainmapImage,
const SkGainmapInfo gainmapInfo,
float  dstRatio,
sk_sp< SkColorSpace dstColorSpace = SkColorSpace::MakeSRGB() 
)
static

Definition at line 65 of file GainmapShaderTest.cpp.

69 {
70 constexpr auto kRect = SkRect::MakeWH(1.f, 1.f);
71 SkImageInfo canvasInfo =
73 SkBitmap canvasBitmap;
74 canvasBitmap.allocPixels(canvasInfo);
75 canvasBitmap.eraseColor(SK_ColorTRANSPARENT);
76
77 sk_sp<SkShader> shader = SkGainmapShader::Make(baseImage,
78 kRect,
80 gainmapImage,
81 kRect,
83 gainmapInfo,
84 kRect,
85 dstRatio,
86 dstColorSpace);
88 paint.setShader(shader);
89 SkCanvas canvas(canvasBitmap);
90 canvas.drawRect(kRect, paint);
91
92 SkColor4f result = {0.f, 0.f, 0.f, 0.f};
93 SkImageInfo readPixelsInfo = SkImageInfo::Make(
95 canvas.readPixels(readPixelsInfo, &result, sizeof(result), 0, 0);
96 return result;
97}
kUnpremul_SkAlphaType
GAsyncResult * result
constexpr std::array< std::array< float, 2 >, 2 > kRect
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609

◆ make_1x1_image()

static sk_sp< SkImage > make_1x1_image ( sk_sp< SkColorSpace imageColorSpace,
SkAlphaType  imageAlphaType,
SkColor4f  imageColor,
sk_sp< SkColorSpace imageColorColorSpace = SkColorSpace::MakeSRGBLinear() 
)
static

Definition at line 34 of file GainmapShaderTest.cpp.

38 {
39 SkImageInfo bmInfo =
40 SkImageInfo::Make(1, 1, kRGBA_F32_SkColorType, imageAlphaType, imageColorSpace);
41 SkBitmap bm;
42 bm.allocPixels(bmInfo);
43
44 SkImageInfo writePixelsInfo = SkImageInfo::Make(
45 1, 1, kRGBA_F32_SkColorType, kUnpremul_SkAlphaType, imageColorColorSpace);
46 SkPixmap writePixelsPixmap(writePixelsInfo, &imageColor, writePixelsInfo.minRowBytes());
47 bm.writePixels(writePixelsPixmap, 0, 0);
49}
bool writePixels(const SkPixmap &src, int dstX, int dstY)
Definition: SkBitmap.cpp:501
SK_API sk_sp< SkImage > RasterFromBitmap(const SkBitmap &bitmap)
size_t minRowBytes() const
Definition: SkImageInfo.h:517

◆ simple_gainmap_info()

static SkGainmapInfo simple_gainmap_info ( float  hdrRatioMax)
static

Definition at line 52 of file GainmapShaderTest.cpp.

52 {
53 SkGainmapInfo gainmapInfo;
54 gainmapInfo.fDisplayRatioSdr = 1.f;
55 gainmapInfo.fDisplayRatioHdr = hdrRatioMax;
56 gainmapInfo.fEpsilonSdr = {0.f, 0.f, 0.f, 1.f};
57 gainmapInfo.fEpsilonHdr = {0.f, 0.f, 0.f, 1.f};
58 gainmapInfo.fGainmapRatioMin = {1.f, 1.f, 1.f, 1.f};
59 gainmapInfo.fGainmapRatioMax = {hdrRatioMax, hdrRatioMax, hdrRatioMax, 1.f};
60 return gainmapInfo;
61}
SkColor4f fGainmapRatioMax
Definition: SkGainmapInfo.h:49
SkColor4f fGainmapRatioMin
Definition: SkGainmapInfo.h:48