Flutter Engine
The Flutter Engine
PointTest.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
14#include "tests/Test.h"
15
16#include <cfloat>
17#include <cstdint>
18#include <cstring>
19#include <string>
20
22 SkPoint p = { 0, 0 };
23 SkRect r = { 0, 0, 0, 0 };
24
25 const SkScalar* pPtr = reinterpret_cast<const SkScalar*>(&p);
26 const SkScalar* rPtr = reinterpret_cast<const SkScalar*>(&r);
27
30}
31
32// Tests SkPoint::Normalize() for this (x,y)
35 SkPoint point;
36 point.set(x, y);
37 SkScalar oldLength = point.length();
38 SkScalar returned = SkPoint::Normalize(&point);
39 SkScalar newLength = point.length();
40 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(returned, oldLength));
42}
43
45 const SkScalar values[] = { 1, 1e18f, 1e20f, 1e38f, SK_ScalarInfinity, SK_ScalarNaN };
46
47 for (SkScalar val : values) {
48 const SkScalar variants[] = { val, -val, SkScalarInvert(val), -SkScalarInvert(val) };
49
50 for (SkScalar v : variants) {
51 const SkPoint pts[] = { { 0, v }, { v, 0 }, { 1, v }, { v, 1 }, { v, v } };
52
53 for (SkPoint p : pts) {
54 bool can = SkPointPriv::CanNormalize(p.fX, p.fY);
55 bool nor = p.normalize();
56 REPORTER_ASSERT(reporter, can == nor);
57 }
58 }
59 }
60}
61
62// Tests that SkPoint::length() and SkPoint::Length() both return
63// approximately expectedLength for this (x,y).
65 SkScalar expectedLength) {
66 SkPoint point;
67 point.set(x, y);
68 SkScalar s1 = point.length();
70 //The following should be exactly the same, but need not be.
71 //See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323
73 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(s1, expectedLength));
74
76}
77
78// Ugh. Windows compiler can dive into other .cpp files, and sometimes
79// notices that I will generate an overflow... which is exactly the point
80// of this test!
81//
82// To avoid this warning, I need to convince the compiler that I might not
83// use that big value, hence this hacky helper function: reporter is
84// ALWAYS non-null. (shhhhhh, don't tell the compiler that).
85template <typename T> T get_value(skiatest::Reporter* reporter, T value) {
86 return reporter ? value : 0;
87}
88
89// On linux gcc, 32bit, we are seeing the compiler propagate up the value
90// of SkPoint::length() as a double (which we use sometimes to avoid overflow
91// during the computation), even though the signature says float (SkScalar).
92//
93// force_as_float is meant to capture our latest technique (horrible as
94// it is) to force the value to be a float, so we can test whether it was
95// finite or not.
97 uint32_t storage;
98 memcpy(&storage, &value, 4);
99 // even the pair of memcpy calls are not sufficient, since those seem to
100 // be no-op'd, so we add a runtime tests (just like get_value) to force
101 // the compiler to give us an actual float.
102 if (nullptr == reporter) {
103 storage = ~storage;
104 }
105 memcpy(&value, &storage, 4);
106 return value;
107}
108
109// test that we handle very large values correctly. i.e. that we can
110// successfully normalize something whose mag overflows a float.
112 SkScalar bigFloat = get_value(reporter, 3.4e38f);
113 SkPoint pt = { bigFloat, bigFloat };
114
115 SkScalar length = pt.length();
117
118 // expect this to be non-finite, but dump the results if not.
119 if (SkIsFinite(length)) {
120 SkDebugf("length(%g, %g) == %g\n", pt.fX, pt.fY, length);
122 }
123
124 // this should succeed, even though we can't represent length
126
127 // now that pt is normalized, we check its length
128 length = pt.length();
130}
131
134
135 static const struct {
136 SkScalar fX;
137 SkScalar fY;
138 SkScalar fLength;
139 } gRec[] = {
141 { 0.6f, 0.8f, SK_Scalar1 },
142 };
143
144 for (size_t i = 0; i < std::size(gRec); ++i) {
145 test_length(reporter, gRec[i].fX, gRec[i].fY, gRec[i].fLength);
146 }
147
150}
151
152DEF_TEST(Point_setLengthFast, reporter) {
153 // Scale a (1,1) point to a bunch of different lengths,
154 // making sure the slow and fast paths are within 0.1%.
155 const float tests[] = { 1.0f, 0.0f, 1.0e-37f, 3.4e38f, 42.0f, 0.00012f };
156
157 const SkPoint kOne = {1.0f, 1.0f};
158 for (unsigned i = 0; i < std::size(tests); i++) {
159 SkPoint slow = kOne, fast = kOne;
160
161 slow.setLength(tests[i]);
163
164 if (slow.length() < FLT_MIN && fast.length() < FLT_MIN) continue;
165
166 SkScalar ratio = slow.length() / fast.length();
167 REPORTER_ASSERT(reporter, ratio > 0.999f);
168 REPORTER_ASSERT(reporter, ratio < 1.001f);
169 }
170}
static BlurTest tests[]
Definition: BlurTest.cpp:84
static const struct @223 gRec[]
reporter
Definition: FontMgrTest.cpp:39
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static bool SkIsFinite(T x, Pack... values)
#define SkScalarInvert(x)
Definition: SkScalar.h:73
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
#define SK_Scalar1
Definition: SkScalar.h:18
#define SK_ScalarNaN
Definition: SkScalar.h:28
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define SK_ScalarInfinity
Definition: SkScalar.h:26
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
static const SkScalar * AsScalars(const SkPoint &pt)
Definition: SkPointPriv.h:26
static bool SetLengthFast(SkPoint *pt, float length)
Definition: SkPoint.cpp:94
static bool CanNormalize(SkScalar dx, SkScalar dy)
Definition: SkPointPriv.h:28
float SkScalar
Definition: extension.cpp:12
uint8_t value
size_t length
DEF_TEST(BO_PointBasic, reporter)
Definition: PointTest.cpp:9
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
TPoint< Scalar > Point
Definition: point.h:322
#define T
Definition: precompiler.cc:65
bool setLength(float length)
Definition: SkPoint.cpp:30
float fX
x-axis value
Definition: SkPoint_impl.h:164
static float Normalize(SkVector *vec)
Definition: SkPoint.cpp:71
void set(float x, float y)
Definition: SkPoint_impl.h:200
static float Length(float x, float y)
Definition: SkPoint.cpp:79
float length() const
Definition: SkPoint_impl.h:282
float fY
y-axis value
Definition: SkPoint_impl.h:165
const float * asScalars() const
Definition: SkRect.h:1340
static void test_overflow(skiatest::Reporter *reporter)
Definition: PointTest.cpp:111
static void test_normalize_cannormalize_consistent(skiatest::Reporter *reporter)
Definition: PointTest.cpp:44
static void test_length(skiatest::Reporter *reporter, SkScalar x, SkScalar y, SkScalar expectedLength)
Definition: PointTest.cpp:64
T get_value(skiatest::Reporter *reporter, T value)
Definition: PointTest.cpp:85
static float force_as_float(skiatest::Reporter *reporter, float value)
Definition: PointTest.cpp:96
static void test_casts(skiatest::Reporter *reporter)
Definition: PointTest.cpp:21
static void test_Normalize(skiatest::Reporter *reporter, SkScalar x, SkScalar y)
Definition: PointTest.cpp:33