Flutter Engine
The Flutter Engine
SkPathOpsTypes.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 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 */
8
13
14#include <algorithm>
15#include <cstdint>
16#include <cstring>
17
18static bool arguments_denormalized(float a, float b, int epsilon) {
19 float denormalizedCheck = FLT_EPSILON * epsilon / 2;
20 return fabsf(a) <= denormalizedCheck && fabsf(b) <= denormalizedCheck;
21}
22
23// from http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
24// FIXME: move to SkFloatBits.h
25static bool equal_ulps(float a, float b, int epsilon, int depsilon) {
26 if (arguments_denormalized(a, b, depsilon)) {
27 return true;
28 }
29 int aBits = SkFloatAs2sCompliment(a);
30 int bBits = SkFloatAs2sCompliment(b);
31 // Find the difference in ULPs.
32 return aBits < bBits + epsilon && bBits < aBits + epsilon;
33}
34
35static bool equal_ulps_no_normal_check(float a, float b, int epsilon, int depsilon) {
36 int aBits = SkFloatAs2sCompliment(a);
37 int bBits = SkFloatAs2sCompliment(b);
38 // Find the difference in ULPs.
39 return aBits < bBits + epsilon && bBits < aBits + epsilon;
40}
41
42static bool equal_ulps_pin(float a, float b, int epsilon, int depsilon) {
43 if (!SkIsFinite(a, b)) {
44 return false;
45 }
46 if (arguments_denormalized(a, b, depsilon)) {
47 return true;
48 }
49 int aBits = SkFloatAs2sCompliment(a);
50 int bBits = SkFloatAs2sCompliment(b);
51 // Find the difference in ULPs.
52 return aBits < bBits + epsilon && bBits < aBits + epsilon;
53}
54
55static bool d_equal_ulps(float a, float b, int epsilon) {
56 int aBits = SkFloatAs2sCompliment(a);
57 int bBits = SkFloatAs2sCompliment(b);
58 // Find the difference in ULPs.
59 return aBits < bBits + epsilon && bBits < aBits + epsilon;
60}
61
62static bool not_equal_ulps(float a, float b, int epsilon) {
63 if (arguments_denormalized(a, b, epsilon)) {
64 return false;
65 }
66 int aBits = SkFloatAs2sCompliment(a);
67 int bBits = SkFloatAs2sCompliment(b);
68 // Find the difference in ULPs.
69 return aBits >= bBits + epsilon || bBits >= aBits + epsilon;
70}
71
72static bool not_equal_ulps_pin(float a, float b, int epsilon) {
73 if (!SkIsFinite(a, b)) {
74 return false;
75 }
76 if (arguments_denormalized(a, b, epsilon)) {
77 return false;
78 }
79 int aBits = SkFloatAs2sCompliment(a);
80 int bBits = SkFloatAs2sCompliment(b);
81 // Find the difference in ULPs.
82 return aBits >= bBits + epsilon || bBits >= aBits + epsilon;
83}
84
85static bool d_not_equal_ulps(float a, float b, int epsilon) {
86 int aBits = SkFloatAs2sCompliment(a);
87 int bBits = SkFloatAs2sCompliment(b);
88 // Find the difference in ULPs.
89 return aBits >= bBits + epsilon || bBits >= aBits + epsilon;
90}
91
92static bool less_ulps(float a, float b, int epsilon) {
93 if (arguments_denormalized(a, b, epsilon)) {
94 return a <= b - FLT_EPSILON * epsilon;
95 }
96 int aBits = SkFloatAs2sCompliment(a);
97 int bBits = SkFloatAs2sCompliment(b);
98 // Find the difference in ULPs.
99 return aBits <= bBits - epsilon;
100}
101
102static bool less_or_equal_ulps(float a, float b, int epsilon) {
103 if (arguments_denormalized(a, b, epsilon)) {
104 return a < b + FLT_EPSILON * epsilon;
105 }
106 int aBits = SkFloatAs2sCompliment(a);
107 int bBits = SkFloatAs2sCompliment(b);
108 // Find the difference in ULPs.
109 return aBits < bBits + epsilon;
110}
111
112// equality using the same error term as between
113bool AlmostBequalUlps(float a, float b) {
114 const int UlpsEpsilon = 2;
115 return equal_ulps(a, b, UlpsEpsilon, UlpsEpsilon);
116}
117
118bool AlmostPequalUlps(float a, float b) {
119 const int UlpsEpsilon = 8;
120 return equal_ulps(a, b, UlpsEpsilon, UlpsEpsilon);
121}
122
123bool AlmostDequalUlps(float a, float b) {
124 const int UlpsEpsilon = 16;
125 return d_equal_ulps(a, b, UlpsEpsilon);
126}
127
128bool AlmostDequalUlps(double a, double b) {
129 if (fabs(a) < SK_ScalarMax && fabs(b) < SK_ScalarMax) {
131 }
132 // We allow divide-by-zero here. It only happens if one of a,b is zero, and the other is NaN.
133 // (Otherwise, we'd hit the condition above). Thus, if std::max returns 0, we compute NaN / 0,
134 // which will produce NaN. The comparison will return false, which is the correct answer.
135 return sk_ieee_double_divide(fabs(a - b), std::max(fabs(a), fabs(b))) < FLT_EPSILON * 16;
136}
137
138bool AlmostEqualUlps(float a, float b) {
139 const int UlpsEpsilon = 16;
140 return equal_ulps(a, b, UlpsEpsilon, UlpsEpsilon);
141}
142
143bool AlmostEqualUlpsNoNormalCheck(float a, float b) {
144 const int UlpsEpsilon = 16;
145 return equal_ulps_no_normal_check(a, b, UlpsEpsilon, UlpsEpsilon);
146}
147
148bool AlmostEqualUlps_Pin(float a, float b) {
149 const int UlpsEpsilon = 16;
150 return equal_ulps_pin(a, b, UlpsEpsilon, UlpsEpsilon);
151}
152
153bool NotAlmostEqualUlps(float a, float b) {
154 const int UlpsEpsilon = 16;
155 return not_equal_ulps(a, b, UlpsEpsilon);
156}
157
158bool NotAlmostEqualUlps_Pin(float a, float b) {
159 const int UlpsEpsilon = 16;
160 return not_equal_ulps_pin(a, b, UlpsEpsilon);
161}
162
163bool NotAlmostDequalUlps(float a, float b) {
164 const int UlpsEpsilon = 16;
165 return d_not_equal_ulps(a, b, UlpsEpsilon);
166}
167
168bool RoughlyEqualUlps(float a, float b) {
169 const int UlpsEpsilon = 256;
170 const int DUlpsEpsilon = 1024;
171 return equal_ulps(a, b, UlpsEpsilon, DUlpsEpsilon);
172}
173
174bool AlmostBetweenUlps(float a, float b, float c) {
175 const int UlpsEpsilon = 2;
176 return a <= c ? less_or_equal_ulps(a, b, UlpsEpsilon) && less_or_equal_ulps(b, c, UlpsEpsilon)
177 : less_or_equal_ulps(b, a, UlpsEpsilon) && less_or_equal_ulps(c, b, UlpsEpsilon);
178}
179
180bool AlmostLessUlps(float a, float b) {
181 const int UlpsEpsilon = 16;
182 return less_ulps(a, b, UlpsEpsilon);
183}
184
185bool AlmostLessOrEqualUlps(float a, float b) {
186 const int UlpsEpsilon = 16;
187 return less_or_equal_ulps(a, b, UlpsEpsilon);
188}
189
190int UlpsDistance(float a, float b) {
191 int32_t floatIntA, floatIntB;
192 memcpy(&floatIntA, &a, sizeof(int32_t));
193 memcpy(&floatIntB, &b, sizeof(int32_t));
194 // Different signs means they do not match.
195 if ((floatIntA < 0) != (floatIntB < 0)) {
196 // Check for equality to make sure +0 == -0
197 return a == b ? 0 : SK_MaxS32;
198 }
199 // Find the difference in ULPs.
200 return SkTAbs(floatIntA - floatIntB);
201}
202
204 SkArenaAlloc* allocator
205 SkDEBUGPARAMS(bool debugSkipAssert)
206 SkDEBUGPARAMS(const char* testName))
207 : fAllocator(allocator)
208 , fCoincidence(nullptr)
209 , fContourHead(head)
210 , fNested(0)
211 , fWindingFailed(false)
213 SkDEBUGPARAMS(fDebugTestName(testName))
214 SkDEBUGPARAMS(fAngleID(0))
215 SkDEBUGPARAMS(fCoinID(0))
216 SkDEBUGPARAMS(fContourID(0))
217 SkDEBUGPARAMS(fPtTID(0))
218 SkDEBUGPARAMS(fSegmentID(0))
219 SkDEBUGPARAMS(fSpanID(0))
220 SkDEBUGPARAMS(fDebugSkipAssert(debugSkipAssert)) {
221#if DEBUG_T_SECT_LOOP_COUNT
222 debugResetLoopCounts();
223#endif
224#if DEBUG_COIN
225 fPreviousFuncName = nullptr;
226#endif
227}
SkScalar fPhase
Definition: DashOp.cpp:189
static int32_t SkFloatAs2sCompliment(float x)
Definition: SkFloatBits.h:59
static bool SkIsFinite(T x, Pack... values)
static constexpr double sk_ieee_double_divide(double numer, double denom)
static constexpr int32_t SK_MaxS32
Definition: SkMath.h:21
#define SkDEBUGPARAMS(...)
static bool less_ulps(float a, float b, int epsilon)
bool RoughlyEqualUlps(float a, float b)
static bool arguments_denormalized(float a, float b, int epsilon)
static bool d_equal_ulps(float a, float b, int epsilon)
static bool not_equal_ulps(float a, float b, int epsilon)
bool AlmostPequalUlps(float a, float b)
static bool equal_ulps_pin(float a, float b, int epsilon, int depsilon)
static bool d_not_equal_ulps(float a, float b, int epsilon)
static bool equal_ulps(float a, float b, int epsilon, int depsilon)
bool AlmostEqualUlps_Pin(float a, float b)
static bool less_or_equal_ulps(float a, float b, int epsilon)
bool AlmostEqualUlps(float a, float b)
bool AlmostBequalUlps(float a, float b)
int UlpsDistance(float a, float b)
bool NotAlmostEqualUlps_Pin(float a, float b)
bool NotAlmostDequalUlps(float a, float b)
static bool not_equal_ulps_pin(float a, float b, int epsilon)
bool NotAlmostEqualUlps(float a, float b)
bool AlmostDequalUlps(float a, float b)
bool AlmostLessOrEqualUlps(float a, float b)
bool AlmostBetweenUlps(float a, float b, float c)
bool AlmostEqualUlpsNoNormalCheck(float a, float b)
bool AlmostLessUlps(float a, float b)
static bool equal_ulps_no_normal_check(float a, float b, int epsilon, int depsilon)
SkOpPhase
#define SK_ScalarMax
Definition: SkScalar.h:24
#define SkDoubleToScalar(x)
Definition: SkScalar.h:64
static T SkTAbs(T value)
Definition: SkTemplates.h:43
SkOpGlobalState(SkOpContourHead *head, SkArenaAlloc *allocator SkDEBUGPARAMS(bool debugSkipAssert) SkDEBUGPARAMS(const char *testName))
static bool b
struct MyStruct a[10]
static float max(float r, float g, float b)
Definition: hsl.cpp:49