Flutter Engine
The Flutter Engine
PathCoverageTest.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
12#include "src/base/SkMathPriv.h"
14#include "tests/Test.h"
15
16#include <algorithm>
17#include <array>
18#include <cstdint>
19
20/*
21 Duplicates lots of code from gpu/src/GrPathUtils.cpp
22 It'd be nice not to do so, but that code's set up currently to only have
23 a single implementation.
24*/
25
26// Sk uses 6, Gr (implicitly) used 10, both apparently arbitrarily.
27#define MAX_COEFF_SHIFT 6
28static const uint32_t MAX_POINTS_PER_CURVE = 1 << MAX_COEFF_SHIFT;
29
30// max + 0.5 min has error [0.0, 0.12]
31// max + 0.375 min has error [-.03, 0.07]
32// 0.96043387 max + 0.397824735 min has error [-.06, +.05]
33// For determining the maximum possible number of points to use in
34// drawing a quadratic, we want to err on the high side.
35static inline int cheap_distance(SkScalar dx, SkScalar dy) {
36 int idx = SkAbs32(SkScalarRoundToInt(dx));
37 int idy = SkAbs32(SkScalarRoundToInt(dy));
38 if (idx > idy) {
39 idx += idy >> 1;
40 } else {
41 idx = idy + (idx >> 1);
42 }
43 return idx;
44}
45
46static inline int estimate_distance(const SkPoint points[]) {
47 return cheap_distance(points[1].fX * 2 - points[2].fX - points[0].fX,
48 points[1].fY * 2 - points[2].fY - points[0].fY);
49}
50
51static inline SkScalar compute_distance(const SkPoint points[]) {
53}
54
55static inline uint32_t estimate_pointCount(int distance) {
56 // Includes -2 bias because this estimator runs 4x high?
57 int shift = 30 - SkCLZ(distance);
58 // Clamp to zero if above subtraction went negative.
59 shift &= ~(shift>>31);
60 if (shift > MAX_COEFF_SHIFT) {
61 shift = MAX_COEFF_SHIFT;
62 }
63 return 1 << shift;
64}
65
66static inline uint32_t compute_pointCount(SkScalar d, SkScalar tol) {
67 if (d < tol) {
68 return 1;
69 } else {
70 int temp = SkScalarCeilToInt(SkScalarSqrt(d / tol));
71 uint32_t count = std::min<uint32_t>(SkNextPow2(temp), MAX_POINTS_PER_CURVE);
72 return count;
73 }
74}
75
76static uint32_t quadraticPointCount_EE(const SkPoint points[]) {
79}
80
81static uint32_t quadraticPointCount_EC(const SkPoint points[], SkScalar tol) {
84}
85
86static uint32_t quadraticPointCount_CE(const SkPoint points[]) {
89}
90
91static uint32_t quadraticPointCount_CC(const SkPoint points[], SkScalar tol) {
93 return compute_pointCount(distance, tol);
94}
95
96// Curve from samplecode/SampleSlides.cpp
97static const int gXY[] = {
98 4, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4
99};
100
101static const int gSawtooth[] = {
102 0, 0, 10, 10, 20, 20, 30, 10, 40, 0, 50, -10, 60, -20, 70, -10, 80, 0
103};
104
105static const int gOvalish[] = {
106 0, 0, 5, 15, 20, 20, 35, 15, 40, 0
107};
108
109static const int gSharpSawtooth[] = {
110 0, 0, 1, 10, 2, 0, 3, -10, 4, 0
111};
112
113// Curve crosses back over itself around 0,10
114static const int gRibbon[] = {
115 -4, 0, 4, 20, 0, 25, -4, 20, 4, 0
116};
117
118static bool one_d_pe(const int* array, const unsigned int count,
120 SkPoint path [3];
121 path[1] = SkPoint::Make(SkIntToScalar(array[0]), SkIntToScalar(array[1]));
122 path[2] = SkPoint::Make(SkIntToScalar(array[2]), SkIntToScalar(array[3]));
123 int numErrors = 0;
124 for (unsigned i = 4; i < count; i += 2) {
125 path[0] = path[1];
126 path[1] = path[2];
127 path[2] = SkPoint::Make(SkIntToScalar(array[i]),
128 SkIntToScalar(array[i+1]));
129 uint32_t computedCount =
131 uint32_t estimatedCount =
133
134 if ((false)) { // avoid bit rot, suppress warning
135 computedCount = quadraticPointCount_EC(path, SkIntToScalar(1));
136 estimatedCount = quadraticPointCount_CE(path);
137 }
138 // Allow estimated to be high by a factor of two, but no less than
139 // the computed value.
140 bool isAccurate = (estimatedCount >= computedCount) &&
141 (estimatedCount <= 2 * computedCount);
142
143 if (!isAccurate) {
144 ERRORF(reporter, "Curve from %.2f %.2f through %.2f %.2f to "
145 "%.2f %.2f computes %u, estimates %u\n",
146 path[0].fX, path[0].fY, path[1].fX, path[1].fY,
147 path[2].fX, path[2].fY, computedCount, estimatedCount);
148 numErrors++;
149 }
150 }
151
152 return (numErrors == 0);
153}
154
155
156
163}
164
165DEF_TEST(PathCoverage, reporter) {
167
168}
reporter
Definition: FontMgrTest.cpp:39
int count
Definition: FontMgrTest.cpp:50
static const int points[]
static uint32_t quadraticPointCount_EC(const SkPoint points[], SkScalar tol)
static uint32_t quadraticPointCount_CC(const SkPoint points[], SkScalar tol)
static const int gOvalish[]
static const int gSawtooth[]
static const int gRibbon[]
static const uint32_t MAX_POINTS_PER_CURVE
static int estimate_distance(const SkPoint points[])
static int cheap_distance(SkScalar dx, SkScalar dy)
static uint32_t estimate_pointCount(int distance)
static uint32_t compute_pointCount(SkScalar d, SkScalar tol)
static uint32_t quadraticPointCount_EE(const SkPoint points[])
#define MAX_COEFF_SHIFT
static SkScalar compute_distance(const SkPoint points[])
static const int gXY[]
static uint32_t quadraticPointCount_CE(const SkPoint points[])
static void TestQuadPointCount(skiatest::Reporter *reporter)
DEF_TEST(PathCoverage, reporter)
static const int gSharpSawtooth[]
static bool one_d_pe(const int *array, const unsigned int count, skiatest::Reporter *reporter)
static int SkCLZ(uint32_t mask)
Definition: SkMathPriv.h:186
static int SkNextPow2(int value)
Definition: SkMathPriv.h:272
static int32_t SkAbs32(int32_t value)
Definition: SkSafe32.h:41
#define SkScalarRoundToInt(x)
Definition: SkScalar.h:37
#define SkScalarCeilToInt(x)
Definition: SkScalar.h:36
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define SkScalarSqrt(x)
Definition: SkScalar.h:42
#define ERRORF(r,...)
Definition: Test.h:293
static SkScalar DistanceToLineSegmentBetween(const SkPoint &pt, const SkPoint &a, const SkPoint &b)
Definition: SkPointPriv.h:43
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
float SkScalar
Definition: extension.cpp:12
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
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
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173