Flutter Engine
The Flutter Engine
ScalarTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
15#include "tests/Test.h"
16
17#include <array>
18#include <cmath>
19#include <cstddef>
20#include <cstdint>
21
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}
43
44struct PointSet {
45 const SkPoint* fPts;
46 size_t fCount;
48};
49
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}
92
93static bool isFinite_int(float x) {
94 uint32_t bits = SkFloat2Bits(x); // need unsigned for our shifts
95 int exponent = bits << 1 >> 24;
96 return exponent != 0xFF;
97}
98
99static bool isFinite_float(float x) {
100 return SkToBool(SkIsFinite(x));
101}
102
103static bool isFinite_mulzero(float x) {
104 float y = x * 0;
105 return y == y;
106}
107
108// return true if the float is finite
109typedef bool (*IsFiniteProc1)(float);
110
111static bool isFinite2_and(float x, float y, IsFiniteProc1 proc) {
112 return proc(x) && proc(y);
113}
114
115static bool isFinite2_mulzeroadd(float x, float y, IsFiniteProc1 proc) {
116 return proc(x * 0 + y * 0);
117}
118
119// return true if both floats are finite
121
125 kNaN
127
129 // our sk_float_is... function may return int instead of bool,
130 // hence the double ! to turn it into a bool
132 REPORTER_ASSERT(reporter, !!std::isinf(value) == (fc == kInfinite));
133 REPORTER_ASSERT(reporter, !!SkIsNaN(value) == (fc == kNaN));
134}
135
136#if defined _WIN32
137#pragma warning(push)
138// we are intentionally causing an overflow here
139// (warning C4756: overflow in constant arithmetic)
140#pragma warning(disable : 4756)
141#endif
142
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}
212
213#if defined _WIN32
214#pragma warning ( pop )
215#endif
216
220}
SkPoint fPts[2]
reporter
Definition: FontMgrTest.cpp:39
static bool isFinite_mulzero(float x)
Definition: ScalarTest.cpp:103
static bool isFinite2_and(float x, float y, IsFiniteProc1 proc)
Definition: ScalarTest.cpp:111
bool(* IsFiniteProc2)(float, float, IsFiniteProc1)
Definition: ScalarTest.cpp:120
static void test_isRectFinite(skiatest::Reporter *reporter)
Definition: ScalarTest.cpp:50
DEF_TEST(Scalar, reporter)
Definition: ScalarTest.cpp:217
static bool isFinite_int(float x)
Definition: ScalarTest.cpp:93
static void test_floatclass(skiatest::Reporter *reporter, float value, FloatClass fc)
Definition: ScalarTest.cpp:128
static void test_roundtoint(skiatest::Reporter *reporter)
Definition: ScalarTest.cpp:22
FloatClass
Definition: ScalarTest.cpp:122
@ kFinite
Definition: ScalarTest.cpp:123
@ kInfinite
Definition: ScalarTest.cpp:124
@ kNaN
Definition: ScalarTest.cpp:125
static void test_isfinite(skiatest::Reporter *reporter)
Definition: ScalarTest.cpp:143
static bool isFinite2_mulzeroadd(float x, float y, IsFiniteProc1 proc)
Definition: ScalarTest.cpp:115
bool(* IsFiniteProc1)(float)
Definition: ScalarTest.cpp:109
static bool isFinite_float(float x)
Definition: ScalarTest.cpp:99
static uint32_t SkFloat2Bits(float value)
Definition: SkFloatBits.h:41
static constexpr bool SkIsNaN(T x)
static bool SkIsFinite(T x, Pack... values)
#define SK_ScalarNaN
Definition: SkScalar.h:28
#define SkScalarRoundToInt(x)
Definition: SkScalar.h:37
#define SK_ScalarInfinity
Definition: SkScalar.h:26
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
float SkScalar
Definition: extension.cpp:12
uint8_t value
static float max(float r, float g, float b)
Definition: hsl.cpp:49
double y
double x
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
float Scalar
Definition: scalar.h:18
const SkPoint * fPts
Definition: ScalarTest.cpp:45
bool fIsFinite
Definition: ScalarTest.cpp:47
size_t fCount
Definition: ScalarTest.cpp:46
void setBounds(const SkPoint pts[], int count)
Definition: SkRect.h:881
bool isEmpty() const
Definition: SkRect.h:693
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63