Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Typedefs | Enumerations | Functions
ScalarTest.cpp File Reference
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkFloatBits.h"
#include "tests/Test.h"
#include <array>
#include <cmath>
#include <cstddef>
#include <cstdint>

Go to the source code of this file.

Classes

struct  PointSet
 

Typedefs

typedef bool(* IsFiniteProc1) (float)
 
typedef bool(* IsFiniteProc2) (float, float, IsFiniteProc1)
 

Enumerations

enum  FloatClass { kFinite , kInfinite , kNaN }
 

Functions

static void test_roundtoint (skiatest::Reporter *reporter)
 
static void test_isRectFinite (skiatest::Reporter *reporter)
 
static bool isFinite_int (float x)
 
static bool isFinite_float (float x)
 
static bool isFinite_mulzero (float x)
 
static bool isFinite2_and (float x, float y, IsFiniteProc1 proc)
 
static bool isFinite2_mulzeroadd (float x, float y, IsFiniteProc1 proc)
 
static void test_floatclass (skiatest::Reporter *reporter, float value, FloatClass fc)
 
static void test_isfinite (skiatest::Reporter *reporter)
 
 DEF_TEST (Scalar, reporter)
 

Typedef Documentation

◆ IsFiniteProc1

typedef bool(* IsFiniteProc1) (float)

Definition at line 109 of file ScalarTest.cpp.

◆ IsFiniteProc2

typedef bool(* IsFiniteProc2) (float, float, IsFiniteProc1)

Definition at line 120 of file ScalarTest.cpp.

Enumeration Type Documentation

◆ FloatClass

enum FloatClass
Enumerator
kFinite 
kInfinite 
kNaN 

Definition at line 122 of file ScalarTest.cpp.

122 {
123 kFinite,
124 kInfinite,
125 kNaN
126};
@ kFinite
@ kInfinite
@ kNaN

Function Documentation

◆ DEF_TEST()

DEF_TEST ( Scalar  ,
reporter   
)

Definition at line 217 of file ScalarTest.cpp.

217 {
220}
reporter
static void test_roundtoint(skiatest::Reporter *reporter)
static void test_isfinite(skiatest::Reporter *reporter)

◆ isFinite2_and()

static bool isFinite2_and ( float  x,
float  y,
IsFiniteProc1  proc 
)
static

Definition at line 111 of file ScalarTest.cpp.

111 {
112 return proc(x) && proc(y);
113}
double y
double x

◆ isFinite2_mulzeroadd()

static bool isFinite2_mulzeroadd ( float  x,
float  y,
IsFiniteProc1  proc 
)
static

Definition at line 115 of file ScalarTest.cpp.

115 {
116 return proc(x * 0 + y * 0);
117}

◆ isFinite_float()

static bool isFinite_float ( float  x)
static

Definition at line 99 of file ScalarTest.cpp.

99 {
100 return SkToBool(SkIsFinite(x));
101}
static bool SkIsFinite(T x, Pack... values)
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35

◆ isFinite_int()

static bool isFinite_int ( float  x)
static

Definition at line 93 of file ScalarTest.cpp.

93 {
94 uint32_t bits = SkFloat2Bits(x); // need unsigned for our shifts
95 int exponent = bits << 1 >> 24;
96 return exponent != 0xFF;
97}
static uint32_t SkFloat2Bits(float value)
Definition SkFloatBits.h:41

◆ isFinite_mulzero()

static bool isFinite_mulzero ( float  x)
static

Definition at line 103 of file ScalarTest.cpp.

103 {
104 float y = x * 0;
105 return y == y;
106}

◆ test_floatclass()

static void test_floatclass ( skiatest::Reporter reporter,
float  value,
FloatClass  fc 
)
static

Definition at line 128 of file ScalarTest.cpp.

128 {
129 // our sk_float_is... function may return int instead of bool,
130 // hence the double ! to turn it into a bool
131 REPORTER_ASSERT(reporter, !!SkIsFinite(value) == (fc == kFinite));
132 REPORTER_ASSERT(reporter, !!std::isinf(value) == (fc == kInfinite));
133 REPORTER_ASSERT(reporter, !!SkIsNaN(value) == (fc == kNaN));
134}
static bool SkIsNaN(T x)
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286

◆ test_isfinite()

static void test_isfinite ( skiatest::Reporter reporter)
static

Definition at line 143 of file ScalarTest.cpp.

143 {
144 struct Rec {
145 float fValue;
146 bool fIsFinite;
147 };
148
149 float max = 3.402823466e+38f;
150 float inf = max * max;
151 float nan = inf * 0;
152
160
161 const Rec data[] = {
162 { 0, true },
163 { 1, true },
164 { -1, true },
165 { max * 0.75f, true },
166 { max, true },
167 { -max * 0.75f, true },
168 { -max, true },
169 { inf, false },
170 { -inf, false },
171 { nan, false },
172 };
173
174 const IsFiniteProc1 gProc1[] = {
178 };
179 const IsFiniteProc2 gProc2[] = {
182 };
183
184 size_t i, n = std::size(data);
185
186 for (i = 0; i < n; ++i) {
187 for (size_t k = 0; k < std::size(gProc1); ++k) {
188 const Rec& rec = data[i];
189 bool finite = gProc1[k](rec.fValue);
190 REPORTER_ASSERT(reporter, rec.fIsFinite == finite);
191 }
192 }
193
194 for (i = 0; i < n; ++i) {
195 const Rec& rec0 = data[i];
196 for (size_t j = 0; j < n; ++j) {
197 const Rec& rec1 = data[j];
198 for (size_t k = 0; k < std::size(gProc1); ++k) {
199 IsFiniteProc1 proc1 = gProc1[k];
200
201 for (size_t m = 0; m < std::size(gProc2); ++m) {
202 bool finite = gProc2[m](rec0.fValue, rec1.fValue, proc1);
203 bool finite2 = rec0.fIsFinite && rec1.fIsFinite;
204 REPORTER_ASSERT(reporter, finite2 == finite);
205 }
206 }
207 }
208 }
209
211}
static bool isFinite_mulzero(float x)
static bool isFinite2_and(float x, float y, IsFiniteProc1 proc)
bool(* IsFiniteProc2)(float, float, IsFiniteProc1)
static void test_isRectFinite(skiatest::Reporter *reporter)
static bool isFinite_int(float x)
static void test_floatclass(skiatest::Reporter *reporter, float value, FloatClass fc)
static bool isFinite2_mulzeroadd(float x, float y, IsFiniteProc1 proc)
bool(* IsFiniteProc1)(float)
static bool isFinite_float(float x)
static float max(float r, float g, float b)
Definition hsl.cpp:49
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41

◆ test_isRectFinite()

static void test_isRectFinite ( skiatest::Reporter reporter)
static

Definition at line 50 of file ScalarTest.cpp.

50 {
51 static const SkPoint gF0[] = {
52 { 0, 0 }, { 1, 1 }
53 };
54 static const SkPoint gF1[] = {
55 { 0, 0 }, { 1, 1 }, { 99.234f, -42342 }
56 };
57
58 static const SkPoint gI0[] = {
59 { 0, 0 }, { 1, 1 }, { 99.234f, -42342 }, { SK_ScalarNaN, 3 }, { 2, 3 },
60 };
61 static const SkPoint gI1[] = {
62 { 0, 0 }, { 1, 1 }, { 99.234f, -42342 }, { 3, SK_ScalarNaN }, { 2, 3 },
63 };
64 static const SkPoint gI2[] = {
65 { 0, 0 }, { 1, 1 }, { 99.234f, -42342 }, { SK_ScalarInfinity, 3 }, { 2, 3 },
66 };
67 static const SkPoint gI3[] = {
68 { 0, 0 }, { 1, 1 }, { 99.234f, -42342 }, { 3, SK_ScalarInfinity }, { 2, 3 },
69 };
70
71 static const struct {
72 const SkPoint* fPts;
73 int fCount;
74 bool fIsFinite;
75 } gSets[] = {
76 { gF0, std::size(gF0), true },
77 { gF1, std::size(gF1), true },
78
79 { gI0, std::size(gI0), false },
80 { gI1, std::size(gI1), false },
81 { gI2, std::size(gI2), false },
82 { gI3, std::size(gI3), false },
83 };
84
85 for (size_t i = 0; i < std::size(gSets); ++i) {
86 SkRect r;
87 r.setBounds(gSets[i].fPts, gSets[i].fCount);
88 bool rectIsFinite = !r.isEmpty();
89 REPORTER_ASSERT(reporter, gSets[i].fIsFinite == rectIsFinite);
90 }
91}
SkPoint fPts[2]
#define SK_ScalarNaN
Definition SkScalar.h:28
#define SK_ScalarInfinity
Definition SkScalar.h:26
void setBounds(const SkPoint pts[], int count)
Definition SkRect.h:881
bool isEmpty() const
Definition SkRect.h:693

◆ test_roundtoint()

static void test_roundtoint ( skiatest::Reporter reporter)
static

Definition at line 22 of file ScalarTest.cpp.

22 {
23 SkScalar x = 0.49999997f;
24 int ix = SkScalarRoundToInt(x);
25 int badIx = (int) floorf(x + 0.5f);
26 // We should get 0, since x < 0.5, but we wouldn't if SkScalarRoundToInt uses the commonly
27 // recommended approach shown in 'badIx' due to float addition rounding up the low
28 // bit after adding 0.5.
29 REPORTER_ASSERT(reporter, 0 == ix);
30 REPORTER_ASSERT(reporter, 1 == badIx);
31
32 // Additionally, when the float value is between (2^23,2^24], it's precision is equal to
33 // 1 integral value. Adding 0.5f rounds up automatically *before* the floor, so naive
34 // rounding is also incorrect. Float values <= 2^23 and > 2^24 don't have this problem
35 // because either the sum can be represented sufficiently for floor() to do the right thing,
36 // or the sum will always round down to the integer multiple.
37 x = 8388609.f;
39 badIx = (int) floorf(x + 0.5f);
40 REPORTER_ASSERT(reporter, 8388609 == ix);
41 REPORTER_ASSERT(reporter, 8388610 == badIx);
42}
#define SkScalarRoundToInt(x)
Definition SkScalar.h:37
Type::kYUV Type::kRGBA() int(0.7 *637)
float SkScalar
Definition extension.cpp:12