From f88929c43ab41f0964c796efb3abd2ffbb8f7166 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 12 Oct 2022 21:24:35 -0700 Subject: [PATCH 01/10] Add polyline benchmark with lots of cubics and quads --- ci/licenses_golden/licenses_flutter | 1 + impeller/geometry/BUILD.gn | 9 + impeller/geometry/geometry_benchmarks.cc | 376 +++++++++++++++++++++++ testing/benchmark/generate_metrics.sh | 2 +- testing/benchmark/upload_metrics.sh | 2 + testing/run_tests.py | 2 + 6 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 impeller/geometry/geometry_benchmarks.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 9c8de3cf5a534..212ce7e3b4883 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1294,6 +1294,7 @@ FILE: ../../../flutter/impeller/geometry/color.cc FILE: ../../../flutter/impeller/geometry/color.h FILE: ../../../flutter/impeller/geometry/constants.cc FILE: ../../../flutter/impeller/geometry/constants.h +FILE: ../../../flutter/impeller/geometry/geometry_benchmarks.cc FILE: ../../../flutter/impeller/geometry/geometry_unittests.cc FILE: ../../../flutter/impeller/geometry/geometry_unittests.h FILE: ../../../flutter/impeller/geometry/gradient.cc diff --git a/impeller/geometry/BUILD.gn b/impeller/geometry/BUILD.gn index f34e00ad1558a..f3bdf11b26e80 100644 --- a/impeller/geometry/BUILD.gn +++ b/impeller/geometry/BUILD.gn @@ -57,3 +57,12 @@ impeller_component("geometry_unittests") { "//flutter/testing", ] } + +executable("geometry_benchmarks") { + testonly = true + sources = [ "geometry_benchmarks.cc" ] + deps = [ + ":geometry", + "//flutter/benchmarking", + ] +} diff --git a/impeller/geometry/geometry_benchmarks.cc b/impeller/geometry/geometry_benchmarks.cc new file mode 100644 index 0000000000000..51852441c39a0 --- /dev/null +++ b/impeller/geometry/geometry_benchmarks.cc @@ -0,0 +1,376 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/benchmarking/benchmarking.h" + +#include "impeller/geometry/path.h" +#include "impeller/geometry/path_builder.h" + +namespace impeller { + +static void BM_ManyCubicPolyline(benchmark::State& state) { + Path path = + PathBuilder{} + .MoveTo({359.934, 96.6335}) + .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908}, + {354.673, 96.8895}) + .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016}, + {354.367, 96.9075}) + .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113}, + {349.259, 97.2355}) + .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678}, + {348.625, 97.2834}) + .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299}, + {343.789, 97.6722}) + .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402}, + {342.703, 97.7734}) + .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505}, + {338.246, 98.207}) + .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292}, + {336.612, 98.3894}) + .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837}, + {332.623, 98.8476}) + .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818}, + {332.237, 98.8982}) + .LineTo({332.237, 102.601}) + .LineTo({321.778, 102.601}) + .LineTo({321.778, 100.382}) + .CubicCurveTo({321.572, 100.413}, {321.367, 100.442}, + {321.161, 100.476}) + .CubicCurveTo({319.22, 100.79}, {317.277, 101.123}, + {315.332, 101.479}) + .CubicCurveTo({315.322, 101.481}, {315.311, 101.482}, + {315.301, 101.484}) + .LineTo({310.017, 105.94}) + .LineTo({309.779, 105.427}) + .LineTo({314.403, 101.651}) + .CubicCurveTo({314.391, 101.653}, {314.379, 101.656}, + {314.368, 101.658}) + .CubicCurveTo({312.528, 102.001}, {310.687, 102.366}, + {308.846, 102.748}) + .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4}) + .CubicCurveTo({305.048, 103.579}, {304.236, 103.75}, + {303.425, 103.936}) + .LineTo({299.105, 107.578}) + .LineTo({298.867, 107.065}) + .LineTo({302.394, 104.185}) + .LineTo({302.412, 104.171}) + .CubicCurveTo({301.388, 104.409}, {300.366, 104.67}, + {299.344, 104.921}) + .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455}) + .CubicCurveTo({295.262, 105.94}, {293.36, 106.445}, + {291.462, 106.979}) + .CubicCurveTo({291.132, 107.072}, {290.802, 107.163}, + {290.471, 107.257}) + .CubicCurveTo({289.463, 107.544}, {288.455, 107.839}, + {287.449, 108.139}) + .CubicCurveTo({286.476, 108.431}, {285.506, 108.73}, + {284.536, 109.035}) + .CubicCurveTo({283.674, 109.304}, {282.812, 109.579}, + {281.952, 109.859}) + .CubicCurveTo({281.177, 110.112}, {280.406, 110.377}, + {279.633, 110.638}) + .CubicCurveTo({278.458, 111.037}, {277.256, 111.449}, + {276.803, 111.607}) + .CubicCurveTo({276.76, 111.622}, {276.716, 111.637}, + {276.672, 111.653}) + .CubicCurveTo({275.017, 112.239}, {273.365, 112.836}, + {271.721, 113.463}) + .LineTo({271.717, 113.449}) + .CubicCurveTo({271.496, 113.496}, {271.238, 113.559}, + {270.963, 113.628}) + .CubicCurveTo({270.893, 113.645}, {270.822, 113.663}, + {270.748, 113.682}) + .CubicCurveTo({270.468, 113.755}, {270.169, 113.834}, + {269.839, 113.926}) + .CubicCurveTo({269.789, 113.94}, {269.732, 113.957}, + {269.681, 113.972}) + .CubicCurveTo({269.391, 114.053}, {269.081, 114.143}, + {268.756, 114.239}) + .CubicCurveTo({268.628, 114.276}, {268.5, 114.314}, + {268.367, 114.354}) + .CubicCurveTo({268.172, 114.412}, {267.959, 114.478}, + {267.752, 114.54}) + .CubicCurveTo({263.349, 115.964}, {258.058, 117.695}, + {253.564, 119.252}) + .CubicCurveTo({253.556, 119.255}, {253.547, 119.258}, + {253.538, 119.261}) + .CubicCurveTo({251.844, 119.849}, {250.056, 120.474}, + {248.189, 121.131}) + .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331}) + .CubicCurveTo({247.079, 121.522}, {246.531, 121.715}, + {245.975, 121.912}) + .CubicCurveTo({245.554, 122.06}, {245.126, 122.212}, + {244.698, 122.364}) + .CubicCurveTo({244.071, 122.586}, {243.437, 122.811}, + {242.794, 123.04}) + .CubicCurveTo({242.189, 123.255}, {241.58, 123.472}, + {240.961, 123.693}) + .CubicCurveTo({240.659, 123.801}, {240.357, 123.909}, + {240.052, 124.018}) + .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032}) + .LineTo({237.164, 125.003}) + .CubicCurveTo({236.709, 125.184}, {236.262, 125.358}, + {235.81, 125.538}) + .CubicCurveTo({235.413, 125.68}, {234.994, 125.832}, + {234.592, 125.977}) + .CubicCurveTo({234.592, 125.977}, {234.591, 125.977}, + {234.59, 125.977}) + .CubicCurveTo({222.206, 130.435}, {207.708, 135.753}, + {192.381, 141.429}) + .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160}) + .LineTo({360, 160}) + .LineTo({360, 119.256}) + .LineTo({360, 106.332}) + .LineTo({360, 96.6307}) + .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326}, + {359.934, 96.6335}) + .Close() + .MoveTo({337.336, 124.143}) + .CubicCurveTo({337.274, 122.359}, {338.903, 121.511}, + {338.903, 121.511}) + .CubicCurveTo({338.903, 121.511}, {338.96, 123.303}, + {337.336, 124.143}) + .Close() + .MoveTo({340.082, 121.849}) + .CubicCurveTo({340.074, 121.917}, {340.062, 121.992}, + {340.046, 122.075}) + .CubicCurveTo({340.039, 122.109}, {340.031, 122.142}, + {340.023, 122.177}) + .CubicCurveTo({340.005, 122.26}, {339.98, 122.346}, + {339.952, 122.437}) + .CubicCurveTo({339.941, 122.473}, {339.931, 122.507}, + {339.918, 122.544}) + .CubicCurveTo({339.873, 122.672}, {339.819, 122.804}, + {339.75, 122.938}) + .CubicCurveTo({339.747, 122.944}, {339.743, 122.949}, + {339.74, 122.955}) + .CubicCurveTo({339.674, 123.08}, {339.593, 123.205}, + {339.501, 123.328}) + .CubicCurveTo({339.473, 123.366}, {339.441, 123.401}, + {339.41, 123.438}) + .CubicCurveTo({339.332, 123.534}, {339.243, 123.625}, + {339.145, 123.714}) + .CubicCurveTo({339.105, 123.75}, {339.068, 123.786}, + {339.025, 123.821}) + .CubicCurveTo({338.881, 123.937}, {338.724, 124.048}, + {338.539, 124.143}) + .CubicCurveTo({338.532, 123.959}, {338.554, 123.79}, + {338.58, 123.626}) + .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625}) + .CubicCurveTo({338.607, 123.455}, {338.65, 123.299}, + {338.704, 123.151}) + .CubicCurveTo({338.708, 123.14}, {338.71, 123.127}, + {338.714, 123.117}) + .CubicCurveTo({338.769, 122.971}, {338.833, 122.838}, + {338.905, 122.712}) + .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001}, + {338.922, 122.682}) + .CubicCurveTo({338.996, 122.557}, {339.072, 122.444}, + {339.155, 122.34}) + .CubicCurveTo({339.161, 122.333}, {339.166, 122.326}, + {339.172, 122.319}) + .CubicCurveTo({339.256, 122.215}, {339.339, 122.12}, + {339.425, 122.037}) + .CubicCurveTo({339.428, 122.033}, {339.431, 122.03}, + {339.435, 122.027}) + .CubicCurveTo({339.785, 121.687}, {340.106, 121.511}, + {340.106, 121.511}) + .CubicCurveTo({340.106, 121.511}, {340.107, 121.645}, + {340.082, 121.849}) + .Close() + .MoveTo({340.678, 113.245}) + .CubicCurveTo({340.594, 113.488}, {340.356, 113.655}, + {340.135, 113.775}) + .CubicCurveTo({339.817, 113.948}, {339.465, 114.059}, + {339.115, 114.151}) + .CubicCurveTo({338.251, 114.379}, {337.34, 114.516}, + {336.448, 114.516}) + .CubicCurveTo({335.761, 114.516}, {335.072, 114.527}, + {334.384, 114.513}) + .CubicCurveTo({334.125, 114.508}, {333.862, 114.462}, + {333.605, 114.424}) + .CubicCurveTo({332.865, 114.318}, {332.096, 114.184}, + {331.41, 113.883}) + .CubicCurveTo({330.979, 113.695}, {330.442, 113.34}, + {330.672, 112.813}) + .CubicCurveTo({331.135, 111.755}, {333.219, 112.946}, + {334.526, 113.833}) + .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784}) + .CubicCurveTo({333.38, 112.708}, {331.749, 110.985}, + {332.76, 110.402}) + .CubicCurveTo({333.769, 109.82}, {334.713, 111.93}, + {335.228, 113.395}) + .CubicCurveTo({334.915, 111.889}, {334.59, 109.636}, + {335.661, 109.592}) + .CubicCurveTo({336.733, 109.636}, {336.408, 111.889}, + {336.07, 113.389}) + .CubicCurveTo({336.609, 111.93}, {337.553, 109.82}, + {338.563, 110.402}) + .CubicCurveTo({339.574, 110.984}, {337.942, 112.708}, + {336.753, 113.784}) + .CubicCurveTo({336.768, 113.8}, {336.782, 113.816}, + {336.796, 113.833}) + .CubicCurveTo({338.104, 112.946}, {340.187, 111.755}, + {340.65, 112.813}) + .CubicCurveTo({340.71, 112.95}, {340.728, 113.102}, + {340.678, 113.245}) + .Close() + .MoveTo({346.357, 106.771}) + .CubicCurveTo({346.295, 104.987}, {347.924, 104.139}, + {347.924, 104.139}) + .CubicCurveTo({347.924, 104.139}, {347.982, 105.931}, + {346.357, 106.771}) + .Close() + .MoveTo({347.56, 106.771}) + .CubicCurveTo({347.498, 104.987}, {349.127, 104.139}, + {349.127, 104.139}) + .CubicCurveTo({349.127, 104.139}, {349.185, 105.931}, + {347.56, 106.771}) + .Close() + .TakePath(); + while (state.KeepRunning()) { + path.CreatePolyline(); + } +} + +BENCHMARK(BM_ManyCubicPolyline); + +static void BM_ManyQuadPolyline(benchmark::State& state) { + Path path = PathBuilder{} + .MoveTo({359.934, 96.6335}) + .QuadraticCurveTo({358.189, 96.7055}, {354.673, 96.8895}) + .QuadraticCurveTo({354.571, 96.8953}, {354.367, 96.9075}) + .QuadraticCurveTo({352.672, 97.0038}, {349.259, 97.2355}) + .QuadraticCurveTo({349.048, 97.2506}, {348.625, 97.2834}) + .QuadraticCurveTo({347.019, 97.4014}, {343.789, 97.6722}) + .QuadraticCurveTo({343.428, 97.704}, {342.703, 97.7734}) + .QuadraticCurveTo({341.221, 97.9086}, {338.246, 98.207}) + .QuadraticCurveTo({337.702, 98.2642}, {336.612, 98.3894}) + .QuadraticCurveTo({335.284, 98.5356}, {332.623, 98.8476}) + .QuadraticCurveTo({332.495, 98.8635}, {332.237, 98.8982}) + .LineTo({332.237, 102.601}) + .LineTo({321.778, 102.601}) + .LineTo({321.778, 100.382}) + .QuadraticCurveTo({321.572, 100.413}, {321.161, 100.476}) + .QuadraticCurveTo({319.22, 100.79}, {315.332, 101.479}) + .QuadraticCurveTo({315.322, 101.481}, {315.301, 101.484}) + .LineTo({310.017, 105.94}) + .LineTo({309.779, 105.427}) + .LineTo({314.403, 101.651}) + .QuadraticCurveTo({314.391, 101.653}, {314.368, 101.658}) + .QuadraticCurveTo({312.528, 102.001}, {308.846, 102.748}) + .QuadraticCurveTo({307.85, 102.955}, {305.859, 103.4}) + .QuadraticCurveTo({305.048, 103.579}, {303.425, 103.936}) + .LineTo({299.105, 107.578}) + .LineTo({298.867, 107.065}) + .LineTo({302.394, 104.185}) + .LineTo({302.412, 104.171}) + .QuadraticCurveTo({301.388, 104.409}, {299.344, 104.921}) + .QuadraticCurveTo({298.618, 105.1}, {297.165, 105.455}) + .QuadraticCurveTo({295.262, 105.94}, {291.462, 106.979}) + .QuadraticCurveTo({291.132, 107.072}, {290.471, 107.257}) + .QuadraticCurveTo({289.463, 107.544}, {287.449, 108.139}) + .QuadraticCurveTo({286.476, 108.431}, {284.536, 109.035}) + .QuadraticCurveTo({283.674, 109.304}, {281.952, 109.859}) + .QuadraticCurveTo({281.177, 110.112}, {279.633, 110.638}) + .QuadraticCurveTo({278.458, 111.037}, {276.803, 111.607}) + .QuadraticCurveTo({276.76, 111.622}, {276.672, 111.653}) + .QuadraticCurveTo({275.017, 112.239}, {271.721, 113.463}) + .LineTo({271.717, 113.449}) + .QuadraticCurveTo({271.496, 113.496}, {270.963, 113.628}) + .QuadraticCurveTo({270.893, 113.645}, {270.748, 113.682}) + .QuadraticCurveTo({270.468, 113.755}, {269.839, 113.926}) + .QuadraticCurveTo({269.789, 113.94}, {269.681, 113.972}) + .QuadraticCurveTo({269.391, 114.053}, {268.756, 114.239}) + .QuadraticCurveTo({268.628, 114.276}, {268.367, 114.354}) + .QuadraticCurveTo({268.172, 114.412}, {267.752, 114.54}) + .QuadraticCurveTo({263.349, 115.964}, {253.564, 119.252}) + .QuadraticCurveTo({253.556, 119.255}, {253.538, 119.261}) + .QuadraticCurveTo({251.844, 119.849}, {248.189, 121.131}) + .QuadraticCurveTo({248, 121.197}, {247.621, 121.331}) + .QuadraticCurveTo({247.079, 121.522}, {245.975, 121.912}) + .QuadraticCurveTo({245.554, 122.06}, {244.698, 122.364}) + .QuadraticCurveTo({244.071, 122.586}, {242.794, 123.04}) + .QuadraticCurveTo({242.189, 123.255}, {240.961, 123.693}) + .QuadraticCurveTo({240.659, 123.801}, {240.052, 124.018}) + .QuadraticCurveTo({239.12, 124.351}, {237.22, 125.032}) + .LineTo({237.164, 125.003}) + .QuadraticCurveTo({236.709, 125.184}, {235.81, 125.538}) + .QuadraticCurveTo({235.413, 125.68}, {234.592, 125.977}) + .QuadraticCurveTo({234.592, 125.977}, {234.59, 125.977}) + .QuadraticCurveTo({222.206, 130.435}, {192.381, 141.429}) + .QuadraticCurveTo({162.77, 151.336}, {84.1123, 160}) + .LineTo({360, 160}) + .LineTo({360, 119.256}) + .LineTo({360, 106.332}) + .LineTo({360, 96.6307}) + .QuadraticCurveTo({359.978, 96.6317}, {359.934, 96.6335}) + .Close() + .MoveTo({337.336, 124.143}) + .QuadraticCurveTo({337.274, 122.359}, {338.903, 121.511}) + .QuadraticCurveTo({338.903, 121.511}, {337.336, 124.143}) + .Close() + .MoveTo({340.082, 121.849}) + .QuadraticCurveTo({340.074, 121.917}, {340.046, 122.075}) + .QuadraticCurveTo({340.039, 122.109}, {340.023, 122.177}) + .QuadraticCurveTo({340.005, 122.26}, {339.952, 122.437}) + .QuadraticCurveTo({339.941, 122.473}, {339.918, 122.544}) + .QuadraticCurveTo({339.873, 122.672}, {339.75, 122.938}) + .QuadraticCurveTo({339.747, 122.944}, {339.74, 122.955}) + .QuadraticCurveTo({339.674, 123.08}, {339.501, 123.328}) + .QuadraticCurveTo({339.473, 123.366}, {339.41, 123.438}) + .QuadraticCurveTo({339.332, 123.534}, {339.145, 123.714}) + .QuadraticCurveTo({339.105, 123.75}, {339.025, 123.821}) + .QuadraticCurveTo({338.881, 123.937}, {338.539, 124.143}) + .QuadraticCurveTo({338.532, 123.959}, {338.58, 123.626}) + .QuadraticCurveTo({338.58, 123.625}, {338.58, 123.625}) + .QuadraticCurveTo({338.607, 123.455}, {338.704, 123.151}) + .QuadraticCurveTo({338.708, 123.14}, {338.714, 123.117}) + .QuadraticCurveTo({338.769, 122.971}, {338.905, 122.712}) + .QuadraticCurveTo({338.911, 122.702}, {338.922, 122.682}) + .QuadraticCurveTo({338.996, 122.557}, {339.155, 122.34}) + .QuadraticCurveTo({339.161, 122.333}, {339.172, 122.319}) + .QuadraticCurveTo({339.256, 122.215}, {339.425, 122.037}) + .QuadraticCurveTo({339.428, 122.033}, {339.435, 122.027}) + .QuadraticCurveTo({339.785, 121.687}, {340.106, 121.511}) + .QuadraticCurveTo({340.106, 121.511}, {340.082, 121.849}) + .Close() + .MoveTo({340.678, 113.245}) + .QuadraticCurveTo({340.594, 113.488}, {340.135, 113.775}) + .QuadraticCurveTo({339.817, 113.948}, {339.115, 114.151}) + .QuadraticCurveTo({338.251, 114.379}, {336.448, 114.516}) + .QuadraticCurveTo({335.761, 114.516}, {334.384, 114.513}) + .QuadraticCurveTo({334.125, 114.508}, {333.605, 114.424}) + .QuadraticCurveTo({332.865, 114.318}, {331.41, 113.883}) + .QuadraticCurveTo({330.979, 113.695}, {330.672, 112.813}) + .QuadraticCurveTo({331.135, 111.755}, {334.526, 113.833}) + .QuadraticCurveTo({334.54, 113.816}, {334.569, 113.784}) + .QuadraticCurveTo({333.38, 112.708}, {332.76, 110.402}) + .QuadraticCurveTo({333.769, 109.82}, {335.228, 113.395}) + .QuadraticCurveTo({334.915, 111.889}, {335.661, 109.592}) + .QuadraticCurveTo({336.733, 109.636}, {336.07, 113.389}) + .QuadraticCurveTo({336.609, 111.93}, {338.563, 110.402}) + .QuadraticCurveTo({339.574, 110.984}, {336.753, 113.784}) + .QuadraticCurveTo({336.768, 113.8}, {336.796, 113.833}) + .QuadraticCurveTo({338.104, 112.946}, {340.65, 112.813}) + .QuadraticCurveTo({340.71, 112.95}, {340.678, 113.245}) + .Close() + .MoveTo({346.357, 106.771}) + .QuadraticCurveTo({346.295, 104.987}, {347.924, 104.139}) + .QuadraticCurveTo({347.924, 104.139}, {346.357, 106.771}) + .Close() + .MoveTo({347.56, 106.771}) + .QuadraticCurveTo({347.498, 104.987}, {349.127, 104.139}) + .QuadraticCurveTo({349.127, 104.139}, {347.56, 106.771}) + .Close() + .TakePath(); + while (state.KeepRunning()) { + path.CreatePolyline(); + } +} + +BENCHMARK(BM_ManyQuadPolyline); + +} // namespace impeller diff --git a/testing/benchmark/generate_metrics.sh b/testing/benchmark/generate_metrics.sh index 0ea0e590b29ed..3886c595870dc 100644 --- a/testing/benchmark/generate_metrics.sh +++ b/testing/benchmark/generate_metrics.sh @@ -14,4 +14,4 @@ set -ex ./shell_benchmarks --benchmark_format=json > shell_benchmarks.json ./ui_benchmarks --benchmark_format=json > ui_benchmarks.json ./display_list_builder_benchmarks --benchmark_format=json > display_list_builder_benchmarks.json - +./geometry_benchmarks --benchmark_format=json > geometry_benchmarks.json diff --git a/testing/benchmark/upload_metrics.sh b/testing/benchmark/upload_metrics.sh index e5b371bf23e30..a087c947df4be 100644 --- a/testing/benchmark/upload_metrics.sh +++ b/testing/benchmark/upload_metrics.sh @@ -46,3 +46,5 @@ cd "$SCRIPT_DIR" --json ../../../out/host_release/ui_benchmarks.json "$@" "$DART" --disable-dart-dev bin/parse_and_send.dart \ --json ../../../out/host_release/display_list_builder_benchmarks.json "$@" +"$DART" --disable-dart-dev bin/parse_and_send.dart \ + --json ../../../out/host_release/geometry_benchmarks.json "$@" diff --git a/testing/run_tests.py b/testing/run_tests.py index a954a991e859a..66799a5be9aa4 100755 --- a/testing/run_tests.py +++ b/testing/run_tests.py @@ -444,6 +444,8 @@ def RunEngineBenchmarks(build_dir, filter): build_dir, 'display_list_builder_benchmarks', filter, icu_flags ) + RunEngineExecutable(build_dir, 'geometry_benchmarks', filter, icu_flags) + if IsLinux(): RunEngineExecutable(build_dir, 'txt_benchmarks', filter, icu_flags) From 1399c982d08d225340c841bf06548f42e6c9af0f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 12 Oct 2022 21:40:08 -0700 Subject: [PATCH 02/10] Counters --- impeller/geometry/geometry_benchmarks.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/impeller/geometry/geometry_benchmarks.cc b/impeller/geometry/geometry_benchmarks.cc index 51852441c39a0..8d612d9d05846 100644 --- a/impeller/geometry/geometry_benchmarks.cc +++ b/impeller/geometry/geometry_benchmarks.cc @@ -230,9 +230,14 @@ static void BM_ManyCubicPolyline(benchmark::State& state) { {347.56, 106.771}) .Close() .TakePath(); + size_t point_count = 0u; + size_t single_point_count = 0u; while (state.KeepRunning()) { - path.CreatePolyline(); + single_point_count = path.CreatePolyline().points.size(); + point_count += single_point_count; } + state.counters["SinglePointCount"] = single_point_count; + state.counters["TotalPointCount"] = point_count; } BENCHMARK(BM_ManyCubicPolyline); @@ -366,9 +371,14 @@ static void BM_ManyQuadPolyline(benchmark::State& state) { .QuadraticCurveTo({349.127, 104.139}, {347.56, 106.771}) .Close() .TakePath(); + size_t point_count = 0u; + size_t single_point_count = 0u; while (state.KeepRunning()) { - path.CreatePolyline(); + single_point_count = path.CreatePolyline().points.size(); + point_count += single_point_count; } + state.counters["SinglePointCount"] = single_point_count; + state.counters["TotalPointCount"] = point_count; } BENCHMARK(BM_ManyQuadPolyline); From c570f08cda2cc5549e21dede63e11baa1ab006b2 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 12 Oct 2022 21:48:00 -0700 Subject: [PATCH 03/10] Update build file --- BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.gn b/BUILD.gn index 76f2dc2807cf4..23de5f02a861d 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -135,6 +135,7 @@ group("flutter") { "//flutter/display_list:display_list_benchmarks", "//flutter/display_list:display_list_builder_benchmarks", "//flutter/fml:fml_benchmarks", + "//flutter/impeller/geometry:geometry_benchmarks", "//flutter/lib/ui:ui_benchmarks", "//flutter/shell/common:shell_benchmarks", "//flutter/third_party/txt:txt_benchmarks", From 5cd28d7c92e60ffa384d6d85692adfb1680728e4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 13 Oct 2022 15:35:33 -0700 Subject: [PATCH 04/10] Tessellate too --- impeller/geometry/BUILD.gn | 1 + impeller/geometry/geometry_benchmarks.cc | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/impeller/geometry/BUILD.gn b/impeller/geometry/BUILD.gn index f3bdf11b26e80..e8d518950bdf0 100644 --- a/impeller/geometry/BUILD.gn +++ b/impeller/geometry/BUILD.gn @@ -63,6 +63,7 @@ executable("geometry_benchmarks") { sources = [ "geometry_benchmarks.cc" ] deps = [ ":geometry", + "../tessellator", "//flutter/benchmarking", ] } diff --git a/impeller/geometry/geometry_benchmarks.cc b/impeller/geometry/geometry_benchmarks.cc index 8d612d9d05846..e4fd2efcee372 100644 --- a/impeller/geometry/geometry_benchmarks.cc +++ b/impeller/geometry/geometry_benchmarks.cc @@ -6,6 +6,7 @@ #include "impeller/geometry/path.h" #include "impeller/geometry/path_builder.h" +#include "impeller/tessellator/tessellator.h" namespace impeller { @@ -232,9 +233,12 @@ static void BM_ManyCubicPolyline(benchmark::State& state) { .TakePath(); size_t point_count = 0u; size_t single_point_count = 0u; + Tessellator tess; while (state.KeepRunning()) { - single_point_count = path.CreatePolyline().points.size(); + auto polyline = path.CreatePolyline(); + single_point_count = polyline.points.size(); point_count += single_point_count; + tess.Tessellate(FillType::kNonZero, polyline, [](Point) {}); } state.counters["SinglePointCount"] = single_point_count; state.counters["TotalPointCount"] = point_count; @@ -373,9 +377,12 @@ static void BM_ManyQuadPolyline(benchmark::State& state) { .TakePath(); size_t point_count = 0u; size_t single_point_count = 0u; + Tessellator tess; while (state.KeepRunning()) { - single_point_count = path.CreatePolyline().points.size(); + auto polyline = path.CreatePolyline(); + single_point_count = polyline.points.size(); point_count += single_point_count; + tess.Tessellate(FillType::kNonZero, polyline, [](Point) {}); } state.counters["SinglePointCount"] = single_point_count; state.counters["TotalPointCount"] = point_count; From 3f9bc482f2e2af7815c48ef6bcf6800ecfbb396e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 13 Oct 2022 15:44:48 -0700 Subject: [PATCH 05/10] Optimize polyline generation for cubic and quadratic curves. The proposed approach has several advantages: - It is _much_ faster for quadratics, since we no longer have to elevate them to cubics. - It is slightly slower for cubics, but also produces fewer and more accurate points on average, which results in faster tessellation and a net decrease in CPU time. - The core of the algorithm is parallelizable, which should make it easier to use on the GPU without significant changes. I do not intend to land the changes to the benchmark in this patch, but it was helpful for local testing. Before landing this I will update/add appropriate benchmarks. --- impeller/entity/contents/clip_contents.cc | 3 +- .../contents/linear_gradient_contents.cc | 3 +- .../contents/radial_gradient_contents.cc | 3 +- .../entity/contents/solid_color_contents.cc | 3 +- .../entity/contents/solid_stroke_contents.cc | 38 +- .../entity/contents/solid_stroke_contents.h | 4 +- .../contents/sweep_gradient_contents.cc | 3 +- .../entity/contents/tiled_texture_contents.cc | 3 +- impeller/entity/contents/vertices_contents.cc | 3 +- impeller/entity/geometry.cc | 12 +- impeller/entity/geometry.h | 12 +- impeller/geometry/geometry_unittests.cc | 134 ++++++- impeller/geometry/path.cc | 7 +- impeller/geometry/path.h | 3 +- impeller/geometry/path_component.cc | 334 ++++++------------ impeller/geometry/path_component.h | 77 ++-- impeller/tessellator/c/tessellator.cc | 5 +- impeller/tessellator/c/tessellator.h | 3 +- 18 files changed, 326 insertions(+), 324 deletions(-) diff --git a/impeller/entity/contents/clip_contents.cc b/impeller/entity/contents/clip_contents.cc index 2497e4daa9c52..a7ba8e6ec7af6 100644 --- a/impeller/entity/contents/clip_contents.cc +++ b/impeller/entity/contents/clip_contents.cc @@ -121,7 +121,8 @@ bool ClipContents::Render(const ContentContext& renderer, auto allocator = renderer.GetContext()->GetResourceAllocator(); auto geometry_result = geometry_->GetPositionBuffer( allocator, host_buffer, renderer.GetTessellator(), - pass.GetRenderTargetSize()); + pass.GetRenderTargetSize(), + entity.GetTransformation().GetMaxBasisLength()); cmd.BindVertices(geometry_result.vertex_buffer); cmd.primitive_type = geometry_result.type; info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index eef7c5d42fd25..1b4d3a77e4dd9 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -80,7 +80,8 @@ bool LinearGradientContents::Render(const ContentContext& renderer, auto allocator = renderer.GetContext()->GetResourceAllocator(); auto geometry_result = GetGeometry()->GetPositionBuffer( allocator, host_buffer, renderer.GetTessellator(), - pass.GetRenderTargetSize()); + pass.GetRenderTargetSize(), + entity.GetTransformation().GetMaxBasisLength()); cmd.BindVertices(geometry_result.vertex_buffer); cmd.primitive_type = geometry_result.type; FS::BindGradientInfo( diff --git a/impeller/entity/contents/radial_gradient_contents.cc b/impeller/entity/contents/radial_gradient_contents.cc index e674ebce192b7..65352a56ce340 100644 --- a/impeller/entity/contents/radial_gradient_contents.cc +++ b/impeller/entity/contents/radial_gradient_contents.cc @@ -79,7 +79,8 @@ bool RadialGradientContents::Render(const ContentContext& renderer, auto allocator = renderer.GetContext()->GetResourceAllocator(); auto geometry_result = GetGeometry()->GetPositionBuffer( allocator, host_buffer, renderer.GetTessellator(), - pass.GetRenderTargetSize()); + pass.GetRenderTargetSize(), + entity.GetTransformation().GetMaxBasisLength()); cmd.BindVertices(geometry_result.vertex_buffer); cmd.primitive_type = geometry_result.type; FS::BindGradientInfo( diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index bae283cb42249..e16dc54b8dc18 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -63,7 +63,8 @@ bool SolidColorContents::Render(const ContentContext& renderer, auto allocator = renderer.GetContext()->GetResourceAllocator(); auto geometry_result = geometry_->GetPositionBuffer( allocator, host_buffer, renderer.GetTessellator(), - pass.GetRenderTargetSize()); + pass.GetRenderTargetSize(), + entity.GetTransformation().GetMaxBasisLength()); cmd.BindVertices(geometry_result.vertex_buffer); cmd.primitive_type = geometry_result.type; diff --git a/impeller/entity/contents/solid_stroke_contents.cc b/impeller/entity/contents/solid_stroke_contents.cc index 8ff982c667d14..bf66c5e2a5dee 100644 --- a/impeller/entity/contents/solid_stroke_contents.cc +++ b/impeller/entity/contents/solid_stroke_contents.cc @@ -72,7 +72,7 @@ static VertexBuffer CreateSolidStrokeVertices( const SolidStrokeContents::CapProc& cap_proc, const SolidStrokeContents::JoinProc& join_proc, Scalar miter_limit, - const SmoothingApproximation& smoothing) { + Scalar tolerance) { using VS = SolidFillVertexShader; VertexBufferBuilder vtx_builder; @@ -101,8 +101,8 @@ static VertexBuffer CreateSolidStrokeVertices( switch (contour_end_point_i - contour_start_point_i) { case 1: { Point p = polyline.points[contour_start_point_i]; - cap_proc(vtx_builder, p, {-stroke_width * 0.5f, 0}, smoothing); - cap_proc(vtx_builder, p, {stroke_width * 0.5f, 0}, smoothing); + cap_proc(vtx_builder, p, {-stroke_width * 0.5f, 0}, tolerance); + cap_proc(vtx_builder, p, {stroke_width * 0.5f, 0}, tolerance); continue; } case 0: @@ -140,7 +140,7 @@ static VertexBuffer CreateSolidStrokeVertices( // Generate start cap. if (!polyline.contours[contour_i].is_closed) { cap_proc(vtx_builder, polyline.points[contour_start_point_i], -offset, - smoothing); + tolerance); } // Generate contour geometry. @@ -162,7 +162,7 @@ static VertexBuffer CreateSolidStrokeVertices( // Generate join from the current line to the next line. join_proc(vtx_builder, polyline.points[point_i], previous_offset, - offset, miter_limit, smoothing); + offset, miter_limit, tolerance); } } } @@ -170,10 +170,10 @@ static VertexBuffer CreateSolidStrokeVertices( // Generate end cap or join. if (!polyline.contours[contour_i].is_closed) { cap_proc(vtx_builder, polyline.points[contour_end_point_i - 1], offset, - smoothing); + tolerance); } else { join_proc(vtx_builder, polyline.points[contour_start_point_i], offset, - contour_first_offset, miter_limit, smoothing); + contour_first_offset, miter_limit, tolerance); } } @@ -209,15 +209,15 @@ bool SolidStrokeContents::Render(const ContentContext& renderer, cmd.pipeline = renderer.GetSolidFillPipeline(options); cmd.stencil_reference = entity.GetStencilDepth(); - auto smoothing = SmoothingApproximation( - 60.0 / (stroke_size_ * entity.GetTransformation().GetMaxBasisLength()), - 0.0, 0.0); + auto tolerance = + kDefaultCurveTolerance / + (stroke_size_ * entity.GetTransformation().GetMaxBasisLength()); Scalar min_size = 1.0f / sqrt(std::abs(determinant)); Scalar stroke_width = std::max(stroke_size_, min_size); cmd.BindVertices(CreateSolidStrokeVertices( path_, pass.GetTransientsBuffer(), stroke_width, cap_proc_, join_proc_, - miter_limit_ * stroke_width * 0.5, smoothing)); + miter_limit_ * stroke_width * 0.5, tolerance)); VS::BindVertInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(vert_info)); FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); @@ -256,12 +256,12 @@ void SolidStrokeContents::SetStrokeCap(Cap cap) { case Cap::kButt: cap_proc_ = [](VertexBufferBuilder& vtx_builder, const Point& position, const Point& offset, - const SmoothingApproximation& smoothing) {}; + Scalar tolerance) {}; break; case Cap::kRound: cap_proc_ = [](VertexBufferBuilder& vtx_builder, const Point& position, const Point& offset, - const SmoothingApproximation& smoothing) { + Scalar tolerance) { VS::PerVertexData vtx; Point forward(offset.y, -offset.x); @@ -271,7 +271,7 @@ void SolidStrokeContents::SetStrokeCap(Cap cap) { CubicPathComponent( offset, offset + forward * PathBuilder::kArcApproximationMagic, forward + offset * PathBuilder::kArcApproximationMagic, forward) - .CreatePolyline(smoothing); + .CreatePolyline(tolerance); vtx.position = position + offset; vtx_builder.AppendVertex(vtx); @@ -288,7 +288,7 @@ void SolidStrokeContents::SetStrokeCap(Cap cap) { case Cap::kSquare: cap_proc_ = [](VertexBufferBuilder& vtx_builder, const Point& position, const Point& offset, - const SmoothingApproximation& smoothing) { + Scalar tolerance) { VS::PerVertexData vtx; vtx.position = position; @@ -337,7 +337,7 @@ void SolidStrokeContents::SetStrokeJoin(Join join) { join_proc_ = [](VertexBufferBuilder& vtx_builder, const Point& position, const Point& start_offset, const Point& end_offset, Scalar miter_limit, - const SmoothingApproximation& smoothing) { + Scalar tolerance) { CreateBevelAndGetDirection(vtx_builder, position, start_offset, end_offset); }; @@ -346,7 +346,7 @@ void SolidStrokeContents::SetStrokeJoin(Join join) { join_proc_ = [](VertexBufferBuilder& vtx_builder, const Point& position, const Point& start_offset, const Point& end_offset, Scalar miter_limit, - const SmoothingApproximation& smoothing) { + Scalar tolerance) { Point start_normal = start_offset.Normalize(); Point end_normal = end_offset.Normalize(); @@ -375,7 +375,7 @@ void SolidStrokeContents::SetStrokeJoin(Join join) { join_proc_ = [](VertexBufferBuilder& vtx_builder, const Point& position, const Point& start_offset, const Point& end_offset, Scalar miter_limit, - const SmoothingApproximation& smoothing) { + Scalar tolerance) { Point start_normal = start_offset.Normalize(); Point end_normal = end_offset.Normalize(); @@ -402,7 +402,7 @@ void SolidStrokeContents::SetStrokeJoin(Join join) { auto arc_points = CubicPathComponent(start_offset, start_handle, middle_handle, middle) - .CreatePolyline(smoothing); + .CreatePolyline(tolerance); VS::PerVertexData vtx; for (const auto& point : arc_points) { diff --git a/impeller/entity/contents/solid_stroke_contents.h b/impeller/entity/contents/solid_stroke_contents.h index 526d0d3c7d198..101daf616e2fb 100644 --- a/impeller/entity/contents/solid_stroke_contents.h +++ b/impeller/entity/contents/solid_stroke_contents.h @@ -40,14 +40,14 @@ class SolidStrokeContents final : public Contents { std::function& vtx_builder, const Point& position, const Point& offset, - const SmoothingApproximation& smoothing)>; + Scalar tolerance)>; using JoinProc = std::function& vtx_builder, const Point& position, const Point& start_offset, const Point& end_offset, Scalar miter_limit, - const SmoothingApproximation& smoothing)>; + Scalar tolerance)>; SolidStrokeContents(); diff --git a/impeller/entity/contents/sweep_gradient_contents.cc b/impeller/entity/contents/sweep_gradient_contents.cc index 2371b6ecfcdda..921c8fc967626 100644 --- a/impeller/entity/contents/sweep_gradient_contents.cc +++ b/impeller/entity/contents/sweep_gradient_contents.cc @@ -85,7 +85,8 @@ bool SweepGradientContents::Render(const ContentContext& renderer, auto allocator = renderer.GetContext()->GetResourceAllocator(); auto geometry_result = GetGeometry()->GetPositionBuffer( allocator, host_buffer, renderer.GetTessellator(), - pass.GetRenderTargetSize()); + pass.GetRenderTargetSize(), + entity.GetTransformation().GetMaxBasisLength()); cmd.BindVertices(geometry_result.vertex_buffer); cmd.primitive_type = geometry_result.type; FS::BindGradientInfo( diff --git a/impeller/entity/contents/tiled_texture_contents.cc b/impeller/entity/contents/tiled_texture_contents.cc index 58a535f7c3b6f..18c4691dac83f 100644 --- a/impeller/entity/contents/tiled_texture_contents.cc +++ b/impeller/entity/contents/tiled_texture_contents.cc @@ -70,7 +70,8 @@ bool TiledTextureContents::Render(const ContentContext& renderer, auto allocator = renderer.GetContext()->GetResourceAllocator(); auto geometry_result = GetGeometry()->GetPositionBuffer( allocator, host_buffer, renderer.GetTessellator(), - pass.GetRenderTargetSize()); + pass.GetRenderTargetSize(), + entity.GetTransformation().GetMaxBasisLength()); cmd.BindVertices(geometry_result.vertex_buffer); cmd.primitive_type = geometry_result.type; VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 31f1f48c5381e..e1a2f50fe934b 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -72,7 +72,8 @@ bool VerticesContents::Render(const ContentContext& renderer, auto geometry_result = geometry_->GetPositionBuffer( allocator, host_buffer, renderer.GetTessellator(), - pass.GetRenderTargetSize()); + pass.GetRenderTargetSize(), + entity.GetTransformation().GetMaxBasisLength()); cmd.pipeline = renderer.GetGeometryPositionPipeline( OptionsFromPassAndEntity(pass, entity)); cmd.primitive_type = geometry_result.type; diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc index 5cbaf2707e5d1..000872f30bfff 100644 --- a/impeller/entity/geometry.cc +++ b/impeller/entity/geometry.cc @@ -48,7 +48,8 @@ GeometryResult VerticesGeometry::GetPositionBuffer( std::shared_ptr device_allocator, HostBuffer& host_buffer, std::shared_ptr tessellator, - ISize render_target_size) { + ISize render_target_size, + Scalar max_basis_length) { if (!vertices_.IsValid()) { return {}; } @@ -182,10 +183,12 @@ GeometryResult PathGeometry::GetPositionBuffer( std::shared_ptr device_allocator, HostBuffer& host_buffer, std::shared_ptr tessellator, - ISize render_target_size) { + ISize render_target_size, + Scalar max_basis_length) { VertexBuffer vertex_buffer; auto tesselation_result = tessellator->TessellateBuilder( - path_.GetFillType(), path_.CreatePolyline(), + path_.GetFillType(), + path_.CreatePolyline(kDefaultCurveTolerance / max_basis_length), [&vertex_buffer, &host_buffer]( const float* vertices, size_t vertices_count, const uint16_t* indices, size_t indices_count) { @@ -244,7 +247,8 @@ GeometryResult CoverGeometry::GetPositionBuffer( std::shared_ptr device_allocator, HostBuffer& host_buffer, std::shared_ptr tessellator, - ISize render_target_size) { + ISize render_target_size, + Scalar max_basis_length) { auto rect = Rect(Size(render_target_size)); constexpr uint16_t kRectIndicies[4] = {0, 1, 2, 3}; return GeometryResult{ diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index 293140d2a20b3..666da614f6317 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -43,7 +43,8 @@ class Geometry { std::shared_ptr device_allocator, HostBuffer& host_buffer, std::shared_ptr tessellator, - ISize render_target_size) = 0; + ISize render_target_size, + Scalar max_basis_length) = 0; virtual GeometryResult GetPositionColorBuffer( std::shared_ptr device_allocator, @@ -75,7 +76,8 @@ class VerticesGeometry : public Geometry { GeometryResult GetPositionBuffer(std::shared_ptr device_allocator, HostBuffer& host_buffer, std::shared_ptr tessellator, - ISize render_target_size) override; + ISize render_target_size, + Scalar max_basis_length) override; // |Geometry| GeometryResult GetPositionColorBuffer( @@ -115,7 +117,8 @@ class PathGeometry : public Geometry { GeometryResult GetPositionBuffer(std::shared_ptr device_allocator, HostBuffer& host_buffer, std::shared_ptr tessellator, - ISize render_target_size) override; + ISize render_target_size, + Scalar max_basis_length) override; // |Geometry| GeometryResult GetPositionColorBuffer( @@ -156,7 +159,8 @@ class CoverGeometry : public Geometry { GeometryResult GetPositionBuffer(std::shared_ptr device_allocator, HostBuffer& host_buffer, std::shared_ptr tessellator, - ISize render_target_size) override; + ISize render_target_size, + Scalar max_basis_length) override; // |Geometry| GeometryResult GetPositionColorBuffer( diff --git a/impeller/geometry/geometry_unittests.cc b/impeller/geometry/geometry_unittests.cc index a199c689d77fd..0a227cb2e900c 100644 --- a/impeller/geometry/geometry_unittests.cc +++ b/impeller/geometry/geometry_unittests.cc @@ -17,6 +17,7 @@ #include "impeller/geometry/rect.h" #include "impeller/geometry/scalar.h" #include "impeller/geometry/size.h" +#include "path_component.h" namespace impeller { namespace testing { @@ -1426,8 +1427,7 @@ TEST(GeometryTest, RectGetPositive) { TEST(GeometryTest, CubicPathComponentPolylineDoesNotIncludePointOne) { CubicPathComponent component({10, 10}, {20, 35}, {35, 20}, {40, 40}); - SmoothingApproximation approximation; - auto polyline = component.CreatePolyline(approximation); + auto polyline = component.CreatePolyline(); ASSERT_NE(polyline.front().x, 10); ASSERT_NE(polyline.front().y, 10); ASSERT_EQ(polyline.back().x, 40); @@ -1713,5 +1713,135 @@ TEST(GeometryTest, Gradient) { } } +static void LogPoint(Point p, bool comma) { + if (comma) { + std::cout << "{x: " << p.x << ", y: " << p.y << "}," << std::endl; + } else { + std::cout << "{x: " << p.x << ", y: " << p.y << "}" << std::endl; + } +} + +static Scalar ApproximateParabolaIntegral(Scalar x) { + constexpr Scalar d = 0.67; + return x / (1.0 - d + sqrt(sqrt(pow(d, 4) + 0.25 * x * x))); +} + +static std::vector CreateQuadPolyline( + const QuadraticPathComponent& component) { + auto tolerance = .1f; + auto sqrt_tol = sqrt(tolerance); + + auto d01 = component.cp - component.p1; + auto d12 = component.p2 - component.cp; + auto dd = d01 - d12; + auto cross = (component.p2 - component.p1).Cross(dd); + auto x0 = d01.Dot(dd) * 1 / cross; + auto x2 = d12.Dot(dd) * 1 / cross; + auto scale = abs(cross / (hypot(dd.x, dd.y) * (x2 - x0))); + + auto a0 = ApproximateParabolaIntegral(x0); + auto a2 = ApproximateParabolaIntegral(x2); + Scalar val = 0.f; + if (isfinite(scale)) { + auto da = abs(a2 - a0); + auto sqrt_scale = sqrt(scale); + if ((x0 < 0 && x2 < 0) || (x0 >= 0 && x2 >= 0)) { + val = da * sqrt_scale; + } else { + // cusp case + auto xmin = sqrt_tol / sqrt_scale; + val = sqrt_tol * da / ApproximateParabolaIntegral(xmin); + } + } + auto u0 = ApproximateParabolaIntegral(a0); + auto u2 = ApproximateParabolaIntegral(a2); + auto uscale = 1 / (u2 - u0); + + auto line_count = ceil(0.5 * val / sqrt_tol); + auto step = 1 / line_count; + FML_LOG(ERROR) << "Line count: " << line_count; + for (size_t i = 1; i < line_count; i += 1) { + auto u = i * step; + auto a = a0 + (a2 - a0) * u; + auto t = (ApproximateParabolaIntegral(a) - u0) * uscale; + LogPoint(component.Solve(t), true); + } + LogPoint(component.p2, false); + + return {}; +} + +static std::vector CreateCubicPolyline( + const CubicPathComponent& component) { + FML_LOG(ERROR) << "New"; + + Scalar t = 0; + + CubicPathComponent current_component = component; + int count = 0; + while (t < 1.0) { + count += 1; + + auto v1 = current_component.cp1 - current_component.p1; + auto v2 = current_component.cp2 - current_component.p1; + + auto s = abs(v2.Cross(v1) / hypot(v1.x, v1.y)); + + if (s < kEhCloseEnough) { + break; + } + + constexpr Scalar f = 0.005; + t = 2 * sqrt(f / (3.f * s)); + + // P'1 + auto ab = current_component.p1 + + t * (current_component.cp1 - current_component.p1); + // P'2 + auto bc = current_component.cp1 + + t * (current_component.cp2 - current_component.cp1); + // P'3 + auto cd = current_component.cp2 + + t * (current_component.p2 - current_component.cp2); + + // P''1 + auto abc = ab + t * (bc - ab); + // P''2 + auto bcd = bc + t * (cd - bc); + + // P'''1 + auto abcd = abc + t * (bcd - abc); + + current_component = {abcd, bcd, cd, current_component.p2}; + LogPoint(abcd, true); + } + LogPoint(component.p2, false); + FML_LOG(ERROR) << count; + return {}; +} + +TEST(GeometryTest, NewPolylineAlgo) { + // CubicPathComponent component({10, 10}, {25, 12}, {40, 15}, {38, 24}); + CubicPathComponent component({100, 100}, {300, 200}, {200, 200}, {200, 100}); + auto points = component.CreatePolyline(); + LogPoint({100, 100}, true); + for (auto point : points) { + LogPoint(point, point != points.back()); + } + FML_LOG(ERROR) << points.size(); + CreateCubicPolyline(component); +} + +TEST(GeometryTest, NewQuadPolylineAlgo) { + QuadraticPathComponent component({100, 100}, {300, 200}, {200, 100}); + auto points = component.CreatePolyline(); + // LogPoint({100, 100}, true); + for (auto point : points) { + LogPoint(point, point != points.back()); + } + FML_LOG(ERROR) << points.size(); + CreateQuadPolyline(component); +} + } // namespace testing } // namespace impeller diff --git a/impeller/geometry/path.cc b/impeller/geometry/path.cc index 7e632d7287989..6b2ecf847b614 100644 --- a/impeller/geometry/path.cc +++ b/impeller/geometry/path.cc @@ -221,8 +221,7 @@ bool Path::UpdateContourComponentAtIndex(size_t index, return true; } -Path::Polyline Path::CreatePolyline( - const SmoothingApproximation& approximation) const { +Path::Polyline Path::CreatePolyline(Scalar tolerance) const { Polyline polyline; std::optional previous_contour_point; @@ -251,10 +250,10 @@ Path::Polyline Path::CreatePolyline( collect_points(linears_[component.index].CreatePolyline()); break; case ComponentType::kQuadratic: - collect_points(quads_[component.index].CreatePolyline(approximation)); + collect_points(quads_[component.index].CreatePolyline(tolerance)); break; case ComponentType::kCubic: - collect_points(cubics_[component.index].CreatePolyline(approximation)); + collect_points(cubics_[component.index].CreatePolyline(tolerance)); break; case ComponentType::kContour: if (component_i == components_.size() - 1) { diff --git a/impeller/geometry/path.h b/impeller/geometry/path.h index 77a20fda0ef6a..22879e5de3751 100644 --- a/impeller/geometry/path.h +++ b/impeller/geometry/path.h @@ -117,8 +117,7 @@ class Path { bool UpdateContourComponentAtIndex(size_t index, const ContourComponent& contour); - Polyline CreatePolyline( - const SmoothingApproximation& approximation = {}) const; + Polyline CreatePolyline(Scalar tolerance = kDefaultCurveTolerance) const; std::optional GetBoundingBox() const; diff --git a/impeller/geometry/path_component.cc b/impeller/geometry/path_component.cc index f9c208386e4a9..92eb1f6d1d9ad 100644 --- a/impeller/geometry/path_component.cc +++ b/impeller/geometry/path_component.cc @@ -8,10 +8,6 @@ namespace impeller { -static const size_t kRecursionLimit = 32; -static const Scalar kCurveCollinearityEpsilon = 1e-30; -static const Scalar kCurveAngleToleranceEpsilon = 0.01; - /* * Based on: https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Specific_cases */ @@ -85,10 +81,57 @@ Point QuadraticPathComponent::SolveDerivative(Scalar time) const { }; } +static Scalar ApproximateParabolaIntegral(Scalar x) { + constexpr Scalar d = 0.67; + return x / (1.0 - d + sqrt(sqrt(pow(d, 4) + 0.25 * x * x))); +} + std::vector QuadraticPathComponent::CreatePolyline( - const SmoothingApproximation& approximation) const { - CubicPathComponent elevated(*this); - return elevated.CreatePolyline(approximation); + Scalar tolerance) const { + std::vector points; + FillPointsForPolyline(points, tolerance); + return points; +} + +void QuadraticPathComponent::FillPointsForPolyline(std::vector& points, + Scalar tolerance) const { + auto sqrt_tolerance = sqrt(tolerance); + + auto d01 = cp - p1; + auto d12 = p2 - cp; + auto dd = d01 - d12; + auto cross = (p2 - p1).Cross(dd); + auto x0 = d01.Dot(dd) * 1 / cross; + auto x2 = d12.Dot(dd) * 1 / cross; + auto scale = abs(cross / (hypot(dd.x, dd.y) * (x2 - x0))); + + auto a0 = ApproximateParabolaIntegral(x0); + auto a2 = ApproximateParabolaIntegral(x2); + Scalar val = 0.f; + if (isfinite(scale)) { + auto da = abs(a2 - a0); + auto sqrt_scale = sqrt(scale); + if ((x0 < 0 && x2 < 0) || (x0 >= 0 && x2 >= 0)) { + val = da * sqrt_scale; + } else { + // cusp case + auto xmin = sqrt_tolerance / sqrt_scale; + val = sqrt_tolerance * da / ApproximateParabolaIntegral(xmin); + } + } + auto u0 = ApproximateParabolaIntegral(a0); + auto u2 = ApproximateParabolaIntegral(a2); + auto uscale = 1 / (u2 - u0); + + auto line_count = std::max(1., ceil(0.5 * val / sqrt_tolerance)); + auto step = 1 / line_count; + for (size_t i = 1; i < line_count; i += 1) { + auto u = i * step; + auto a = a0 + (a2 - a0) * u; + auto t = (ApproximateParabolaIntegral(a) - u0) * uscale; + points.emplace_back(Solve(t)); + } + points.emplace_back(p2); } std::vector QuadraticPathComponent::Extrema() const { @@ -110,238 +153,61 @@ Point CubicPathComponent::SolveDerivative(Scalar time) const { }; } -/* - * Paul de Casteljau's subdivision with modifications as described in - * http://agg.sourceforge.net/antigrain.com/research/adaptive_bezier/index.html. - * Refer to the diagram on that page for a description of the points. - */ -static void CubicPathSmoothenRecursive(const SmoothingApproximation& approx, - std::vector& points, - Point p1, - Point p2, - Point p3, - Point p4, - size_t level) { - if (level >= kRecursionLimit) { - return; +std::vector CubicPathComponent::CreatePolyline(Scalar tolerance) const { + auto quads = ToQuadratics(.1); + std::vector points; + for (const auto& quad : quads) { + quad.FillPointsForPolyline(points, tolerance); } + return points; +} - /* - * Find all midpoints. - */ - auto p12 = (p1 + p2) / 2.0; - auto p23 = (p2 + p3) / 2.0; - auto p34 = (p3 + p4) / 2.0; - - auto p123 = (p12 + p23) / 2.0; - auto p234 = (p23 + p34) / 2.0; - - auto p1234 = (p123 + p234) / 2.0; - - /* - * Attempt approximation using single straight line. - */ - auto d = p4 - p1; - Scalar d2 = fabs(((p2.x - p4.x) * d.y - (p2.y - p4.y) * d.x)); - Scalar d3 = fabs(((p3.x - p4.x) * d.y - (p3.y - p4.y) * d.x)); - - Scalar da1 = 0; - Scalar da2 = 0; - Scalar k = 0; - - switch ((static_cast(d2 > kCurveCollinearityEpsilon) << 1) + - static_cast(d3 > kCurveCollinearityEpsilon)) { - case 0: - /* - * All collinear OR p1 == p4. - */ - k = d.x * d.x + d.y * d.y; - if (k == 0) { - d2 = p1.GetDistanceSquared(p2); - d3 = p4.GetDistanceSquared(p3); - } else { - k = 1.0 / k; - da1 = p2.x - p1.x; - da2 = p2.y - p1.y; - d2 = k * (da1 * d.x + da2 * d.y); - da1 = p3.x - p1.x; - da2 = p3.y - p1.y; - d3 = k * (da1 * d.x + da2 * d.y); - - if (d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1) { - /* - * Simple collinear case, 1---2---3---4. Leave just two endpoints. - */ - return; - } - - if (d2 <= 0) { - d2 = p2.GetDistanceSquared(p1); - } else if (d2 >= 1) { - d2 = p2.GetDistanceSquared(p4); - } else { - d2 = p2.GetDistanceSquared({p1.x + d2 * d.x, p1.y + d2 * d.y}); - } - - if (d3 <= 0) { - d3 = p3.GetDistanceSquared(p1); - } else if (d3 >= 1) { - d3 = p3.GetDistanceSquared(p4); - } else { - d3 = p3.GetDistanceSquared({p1.x + d3 * d.x, p1.y + d3 * d.y}); - } - } - - if (d2 > d3) { - if (d2 < approx.distance_tolerance_square) { - points.emplace_back(p2); - return; - } - } else { - if (d3 < approx.distance_tolerance_square) { - points.emplace_back(p3); - return; - } - } - break; - case 1: - /* - * p1, p2, p4 are collinear, p3 is significant. - */ - if (d3 * d3 <= - approx.distance_tolerance_square * (d.x * d.x + d.y * d.y)) { - if (approx.angle_tolerance < kCurveAngleToleranceEpsilon) { - points.emplace_back(p23); - return; - } - - /* - * Angle Condition. - */ - da1 = ::fabs(::atan2(p4.y - p3.y, p4.x - p3.x) - - ::atan2(p3.y - p2.y, p3.x - p2.x)); - - if (da1 >= kPi) { - da1 = 2.0 * kPi - da1; - } - - if (da1 < approx.angle_tolerance) { - points.emplace_back(p2); - points.emplace_back(p3); - return; - } - - if (approx.cusp_limit != 0.0) { - if (da1 > approx.cusp_limit) { - points.emplace_back(p3); - return; - } - } - } - break; - - case 2: - /* - * p1,p3,p4 are collinear, p2 is significant. - */ - if (d2 * d2 <= - approx.distance_tolerance_square * (d.x * d.x + d.y * d.y)) { - if (approx.angle_tolerance < kCurveAngleToleranceEpsilon) { - points.emplace_back(p23); - return; - } - - /* - * Angle Condition. - */ - da1 = ::fabs(::atan2(p3.y - p2.y, p3.x - p2.x) - - ::atan2(p2.y - p1.y, p2.x - p1.x)); - - if (da1 >= kPi) { - da1 = 2.0 * kPi - da1; - } - - if (da1 < approx.angle_tolerance) { - points.emplace_back(p2); - points.emplace_back(p3); - return; - } - - if (approx.cusp_limit != 0.0) { - if (da1 > approx.cusp_limit) { - points.emplace_back(p2); - return; - } - } - } - break; - - case 3: - /* - * Regular case. - */ - if ((d2 + d3) * (d2 + d3) <= - approx.distance_tolerance_square * (d.x * d.x + d.y * d.y)) { - /* - * If the curvature doesn't exceed the distance_tolerance value - * we tend to finish subdivisions. - */ - if (approx.angle_tolerance < kCurveAngleToleranceEpsilon) { - points.emplace_back(p23); - return; - } - - /* - * Angle & Cusp Condition. - */ - k = ::atan2(p3.y - p2.y, p3.x - p2.x); - da1 = ::fabs(k - ::atan2(p2.y - p1.y, p2.x - p1.x)); - da2 = ::fabs(::atan2(p4.y - p3.y, p4.x - p3.x) - k); - - if (da1 >= kPi) { - da1 = 2.0 * kPi - da1; - } - - if (da2 >= kPi) { - da2 = 2.0 * kPi - da2; - } - - if (da1 + da2 < approx.angle_tolerance) { - /* - * Finally we can stop the recursion. - */ - points.emplace_back(p23); - return; - } - - if (approx.cusp_limit != 0.0) { - if (da1 > approx.cusp_limit) { - points.emplace_back(p2); - return; - } - - if (da2 > approx.cusp_limit) { - points.emplace_back(p3); - return; - } - } - } - break; - } +inline QuadraticPathComponent CubicPathComponent::Lower() const { + return QuadraticPathComponent(3.0 * (cp1 - p1), 3.0 * (cp2 - cp1), + 3.0 * (p2 - cp2)); +} - /* - * Continue subdivision. - */ - CubicPathSmoothenRecursive(approx, points, p1, p12, p123, p1234, level + 1); - CubicPathSmoothenRecursive(approx, points, p1234, p234, p34, p4, level + 1); +CubicPathComponent CubicPathComponent::Subsegment(Scalar t0, Scalar t1) const { + auto p0 = Solve(t0); + auto p3 = Solve(t1); + auto d = Lower(); + auto scale = (t1 - t0) * (1.0 / 3.0); + auto p1 = p0 + scale * d.Solve(t0); + auto p2 = p3 - scale * d.Solve(t1); + return CubicPathComponent(p0, p1, p2, p3); } -std::vector CubicPathComponent::CreatePolyline( - const SmoothingApproximation& approximation) const { - std::vector points; - CubicPathSmoothenRecursive(approximation, points, p1, cp1, cp2, p2, 0); - points.emplace_back(p2); - return points; +std::vector CubicPathComponent::ToQuadratics( + Scalar accuracy) const { + std::vector quads; + // The maximum error, as a vector from the cubic to the best approximating + // quadratic, is proportional to the third derivative, which is constant + // across the segment. Thus, the error scales down as the third power of + // the number of subdivisions. Our strategy then is to subdivide `t` evenly. + // + // This is an overestimate of the error because only the component + // perpendicular to the first derivative is important. But the simplicity is + // appealing. + + // This magic number is the square of 36 / sqrt(3). + // See: http://caffeineowl.com/graphics/2d/vectorial/cubic2quad01.html + auto max_hypot2 = 432.0 * accuracy * accuracy; + auto p1x2 = 3.0 * cp1 - p1; + auto p2x2 = 3.0 * cp2 - p2; + auto p = p2x2 - p1x2; + auto err = p.Dot(p); + auto quad_count = std::max(1., ceil(pow(err / max_hypot2, 1. / 6.0))); + + for (size_t i = 0; i < quad_count; i++) { + auto t0 = i / quad_count; + auto t1 = (i + 1) / quad_count; + auto seg = Subsegment(t0, t1); + auto p1x2 = 3.0 * seg.cp1 - seg.p1; + auto p2x2 = 3.0 * seg.cp2 - seg.p2; + quads.emplace_back( + QuadraticPathComponent(seg.p1, ((p1x2 + p2x2) / 4.0), seg.p2)); + } + return quads; } static inline bool NearEqual(Scalar a, Scalar b, Scalar epsilon) { diff --git a/impeller/geometry/path_component.h b/impeller/geometry/path_component.h index d1cdf3a0b0907..cf7b275581049 100644 --- a/impeller/geometry/path_component.h +++ b/impeller/geometry/path_component.h @@ -12,46 +12,15 @@ namespace impeller { -/// Information about how to approximate points on a curved path segment. -/// -/// In particular, the values in this object control how many vertices to -/// generate when approximating curves, and what tolerances to use when -/// calculating the sharpness of curves. -struct SmoothingApproximation { - /// The scaling coefficient to use when translating to screen coordinates. - /// - /// Values approaching 0.0 will generate smoother looking curves with a - /// greater number of vertices, and will be more expensive to calculate. - Scalar scale; - - /// The tolerance value in radians for calculating sharp angles. - /// - /// Values approaching 0.0 will provide more accurate approximation of sharp - /// turns. A 0.0 value means angle conditions are not considered at all. - Scalar angle_tolerance; - - /// An angle in radians at which to introduce bevel cuts. - /// - /// Values greater than zero will restirct the sharpness of bevel cuts on - /// turns. - Scalar cusp_limit; - - /// Used to more quickly detect colinear cases. - Scalar distance_tolerance_square; - - SmoothingApproximation(/* default */) - : SmoothingApproximation(1.0 /* scale */, - 0.0 /* angle tolerance */, - 0.0 /* cusp limit */) {} - - SmoothingApproximation(Scalar p_scale, - Scalar p_angle_tolerance, - Scalar p_cusp_limit) - : scale(p_scale), - angle_tolerance(p_angle_tolerance), - cusp_limit(p_cusp_limit), - distance_tolerance_square(0.5 * p_scale * 0.5 * p_scale) {} -}; +// The default tolerance value for QuadraticCurveComponent::CreatePolyline and +// CubicCurveComponent::CreatePolyline. It also impacts the number of quadratics +// created when flattening a cubic curve to a polyline. +// +// Smaller numbers mean more points. This number seems suitable for particularly +// curvy curves at scales close to 1.0. As the scale increases, this number +// should be divided by Matrix::GetMaxBasisLength to avoid generating too few +// points for the given scale. +static constexpr Scalar kDefaultCurveTolerance = .1f; struct LinearPathComponent { Point p1; @@ -86,8 +55,21 @@ struct QuadraticPathComponent { Point SolveDerivative(Scalar time) const; + // Uses the algorithm described by Raph Levien in + // https://raphlinus.github.io/graphics/curves/2019/12/23/flatten-quadbez.html. + // + // The algorithm has several benefits: + // - It does not require elevation to cubics for processing. + // - It generates fewer and more accurate points than recursive subdivision. + // - Each turn of the core iteration loop has no dependencies on other turns, + // making it trivially parallelizable. + // + // See also the implementation in kurbo: https://github.com/linebender/kurbo. std::vector CreatePolyline( - const SmoothingApproximation& approximation) const; + Scalar tolerance = kDefaultCurveTolerance) const; + + void FillPointsForPolyline(std::vector& points, + Scalar tolerance = kDefaultCurveTolerance) const; std::vector Extrema() const; @@ -117,15 +99,26 @@ struct CubicPathComponent { Point SolveDerivative(Scalar time) const; + // This method approximates the cubic component with quadratics, and then + // generates a polyline from those quadratics. + // + // See the note on QuadraticPathComponent::CreatePolyline for references. std::vector CreatePolyline( - const SmoothingApproximation& approximation) const; + Scalar tolerance = kDefaultCurveTolerance) const; std::vector Extrema() const; + std::vector ToQuadratics(Scalar accuracy) const; + + CubicPathComponent Subsegment(Scalar t0, Scalar t1) const; + bool operator==(const CubicPathComponent& other) const { return p1 == other.p1 && cp1 == other.cp1 && cp2 == other.cp2 && p2 == other.p2; } + + private: + QuadraticPathComponent Lower() const; }; struct ContourComponent { diff --git a/impeller/tessellator/c/tessellator.cc b/impeller/tessellator/c/tessellator.cc index 7a53d9ceded5d..09b44b5014964 100644 --- a/impeller/tessellator/c/tessellator.cc +++ b/impeller/tessellator/c/tessellator.cc @@ -39,12 +39,11 @@ void Close(PathBuilder* builder) { struct Vertices* Tessellate(PathBuilder* builder, int fill_type, - Scalar scale, + Scalar tolerance, Scalar angle_tolerance, Scalar cusp_limit) { auto path = builder->CopyPath(static_cast(fill_type)); - auto smoothing = SmoothingApproximation(scale, angle_tolerance, cusp_limit); - auto polyline = path.CreatePolyline(smoothing); + auto polyline = path.CreatePolyline(tolerance); std::vector points; if (Tessellator{}.Tessellate(path.GetFillType(), polyline, [&points](Point vertex) { diff --git a/impeller/tessellator/c/tessellator.h b/impeller/tessellator/c/tessellator.h index 23a24e1f9603f..0cb01d68f6c42 100644 --- a/impeller/tessellator/c/tessellator.h +++ b/impeller/tessellator/c/tessellator.h @@ -42,7 +42,8 @@ IMPELLER_API void Close(PathBuilder* builder); IMPELLER_API struct Vertices* Tessellate(PathBuilder* builder, int fill_type, - Scalar scale, + Scalar tolerance, + // Unused, remaining for ABI stability. Scalar angle_tolerance, Scalar cusp_limit); From d2e8f15e1f3f923f73ad7983dbf7ab864a1f8df9 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 14 Oct 2022 11:05:19 -0700 Subject: [PATCH 06/10] Refactor polyline bench slightly, add benchmarks including tessellation --- impeller/geometry/BUILD.gn | 1 + impeller/geometry/geometry_benchmarks.cc | 649 ++++++++++------------- 2 files changed, 289 insertions(+), 361 deletions(-) diff --git a/impeller/geometry/BUILD.gn b/impeller/geometry/BUILD.gn index f3bdf11b26e80..e8d518950bdf0 100644 --- a/impeller/geometry/BUILD.gn +++ b/impeller/geometry/BUILD.gn @@ -63,6 +63,7 @@ executable("geometry_benchmarks") { sources = [ "geometry_benchmarks.cc" ] deps = [ ":geometry", + "../tessellator", "//flutter/benchmarking", ] } diff --git a/impeller/geometry/geometry_benchmarks.cc b/impeller/geometry/geometry_benchmarks.cc index 8d612d9d05846..eff277fbf88eb 100644 --- a/impeller/geometry/geometry_benchmarks.cc +++ b/impeller/geometry/geometry_benchmarks.cc @@ -6,381 +6,308 @@ #include "impeller/geometry/path.h" #include "impeller/geometry/path_builder.h" +#include "impeller/tessellator/tessellator.h" namespace impeller { -static void BM_ManyCubicPolyline(benchmark::State& state) { - Path path = - PathBuilder{} - .MoveTo({359.934, 96.6335}) - .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908}, - {354.673, 96.8895}) - .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016}, - {354.367, 96.9075}) - .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113}, - {349.259, 97.2355}) - .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678}, - {348.625, 97.2834}) - .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299}, - {343.789, 97.6722}) - .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402}, - {342.703, 97.7734}) - .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505}, - {338.246, 98.207}) - .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292}, - {336.612, 98.3894}) - .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837}, - {332.623, 98.8476}) - .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818}, - {332.237, 98.8982}) - .LineTo({332.237, 102.601}) - .LineTo({321.778, 102.601}) - .LineTo({321.778, 100.382}) - .CubicCurveTo({321.572, 100.413}, {321.367, 100.442}, - {321.161, 100.476}) - .CubicCurveTo({319.22, 100.79}, {317.277, 101.123}, - {315.332, 101.479}) - .CubicCurveTo({315.322, 101.481}, {315.311, 101.482}, - {315.301, 101.484}) - .LineTo({310.017, 105.94}) - .LineTo({309.779, 105.427}) - .LineTo({314.403, 101.651}) - .CubicCurveTo({314.391, 101.653}, {314.379, 101.656}, - {314.368, 101.658}) - .CubicCurveTo({312.528, 102.001}, {310.687, 102.366}, - {308.846, 102.748}) - .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4}) - .CubicCurveTo({305.048, 103.579}, {304.236, 103.75}, - {303.425, 103.936}) - .LineTo({299.105, 107.578}) - .LineTo({298.867, 107.065}) - .LineTo({302.394, 104.185}) - .LineTo({302.412, 104.171}) - .CubicCurveTo({301.388, 104.409}, {300.366, 104.67}, - {299.344, 104.921}) - .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455}) - .CubicCurveTo({295.262, 105.94}, {293.36, 106.445}, - {291.462, 106.979}) - .CubicCurveTo({291.132, 107.072}, {290.802, 107.163}, - {290.471, 107.257}) - .CubicCurveTo({289.463, 107.544}, {288.455, 107.839}, - {287.449, 108.139}) - .CubicCurveTo({286.476, 108.431}, {285.506, 108.73}, - {284.536, 109.035}) - .CubicCurveTo({283.674, 109.304}, {282.812, 109.579}, - {281.952, 109.859}) - .CubicCurveTo({281.177, 110.112}, {280.406, 110.377}, - {279.633, 110.638}) - .CubicCurveTo({278.458, 111.037}, {277.256, 111.449}, - {276.803, 111.607}) - .CubicCurveTo({276.76, 111.622}, {276.716, 111.637}, - {276.672, 111.653}) - .CubicCurveTo({275.017, 112.239}, {273.365, 112.836}, - {271.721, 113.463}) - .LineTo({271.717, 113.449}) - .CubicCurveTo({271.496, 113.496}, {271.238, 113.559}, - {270.963, 113.628}) - .CubicCurveTo({270.893, 113.645}, {270.822, 113.663}, - {270.748, 113.682}) - .CubicCurveTo({270.468, 113.755}, {270.169, 113.834}, - {269.839, 113.926}) - .CubicCurveTo({269.789, 113.94}, {269.732, 113.957}, - {269.681, 113.972}) - .CubicCurveTo({269.391, 114.053}, {269.081, 114.143}, - {268.756, 114.239}) - .CubicCurveTo({268.628, 114.276}, {268.5, 114.314}, - {268.367, 114.354}) - .CubicCurveTo({268.172, 114.412}, {267.959, 114.478}, - {267.752, 114.54}) - .CubicCurveTo({263.349, 115.964}, {258.058, 117.695}, - {253.564, 119.252}) - .CubicCurveTo({253.556, 119.255}, {253.547, 119.258}, - {253.538, 119.261}) - .CubicCurveTo({251.844, 119.849}, {250.056, 120.474}, - {248.189, 121.131}) - .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331}) - .CubicCurveTo({247.079, 121.522}, {246.531, 121.715}, - {245.975, 121.912}) - .CubicCurveTo({245.554, 122.06}, {245.126, 122.212}, - {244.698, 122.364}) - .CubicCurveTo({244.071, 122.586}, {243.437, 122.811}, - {242.794, 123.04}) - .CubicCurveTo({242.189, 123.255}, {241.58, 123.472}, - {240.961, 123.693}) - .CubicCurveTo({240.659, 123.801}, {240.357, 123.909}, - {240.052, 124.018}) - .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032}) - .LineTo({237.164, 125.003}) - .CubicCurveTo({236.709, 125.184}, {236.262, 125.358}, - {235.81, 125.538}) - .CubicCurveTo({235.413, 125.68}, {234.994, 125.832}, - {234.592, 125.977}) - .CubicCurveTo({234.592, 125.977}, {234.591, 125.977}, - {234.59, 125.977}) - .CubicCurveTo({222.206, 130.435}, {207.708, 135.753}, - {192.381, 141.429}) - .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160}) - .LineTo({360, 160}) - .LineTo({360, 119.256}) - .LineTo({360, 106.332}) - .LineTo({360, 96.6307}) - .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326}, - {359.934, 96.6335}) - .Close() - .MoveTo({337.336, 124.143}) - .CubicCurveTo({337.274, 122.359}, {338.903, 121.511}, - {338.903, 121.511}) - .CubicCurveTo({338.903, 121.511}, {338.96, 123.303}, - {337.336, 124.143}) - .Close() - .MoveTo({340.082, 121.849}) - .CubicCurveTo({340.074, 121.917}, {340.062, 121.992}, - {340.046, 122.075}) - .CubicCurveTo({340.039, 122.109}, {340.031, 122.142}, - {340.023, 122.177}) - .CubicCurveTo({340.005, 122.26}, {339.98, 122.346}, - {339.952, 122.437}) - .CubicCurveTo({339.941, 122.473}, {339.931, 122.507}, - {339.918, 122.544}) - .CubicCurveTo({339.873, 122.672}, {339.819, 122.804}, - {339.75, 122.938}) - .CubicCurveTo({339.747, 122.944}, {339.743, 122.949}, - {339.74, 122.955}) - .CubicCurveTo({339.674, 123.08}, {339.593, 123.205}, - {339.501, 123.328}) - .CubicCurveTo({339.473, 123.366}, {339.441, 123.401}, - {339.41, 123.438}) - .CubicCurveTo({339.332, 123.534}, {339.243, 123.625}, - {339.145, 123.714}) - .CubicCurveTo({339.105, 123.75}, {339.068, 123.786}, - {339.025, 123.821}) - .CubicCurveTo({338.881, 123.937}, {338.724, 124.048}, - {338.539, 124.143}) - .CubicCurveTo({338.532, 123.959}, {338.554, 123.79}, - {338.58, 123.626}) - .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625}) - .CubicCurveTo({338.607, 123.455}, {338.65, 123.299}, - {338.704, 123.151}) - .CubicCurveTo({338.708, 123.14}, {338.71, 123.127}, - {338.714, 123.117}) - .CubicCurveTo({338.769, 122.971}, {338.833, 122.838}, - {338.905, 122.712}) - .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001}, - {338.922, 122.682}) - .CubicCurveTo({338.996, 122.557}, {339.072, 122.444}, - {339.155, 122.34}) - .CubicCurveTo({339.161, 122.333}, {339.166, 122.326}, - {339.172, 122.319}) - .CubicCurveTo({339.256, 122.215}, {339.339, 122.12}, - {339.425, 122.037}) - .CubicCurveTo({339.428, 122.033}, {339.431, 122.03}, - {339.435, 122.027}) - .CubicCurveTo({339.785, 121.687}, {340.106, 121.511}, - {340.106, 121.511}) - .CubicCurveTo({340.106, 121.511}, {340.107, 121.645}, - {340.082, 121.849}) - .Close() - .MoveTo({340.678, 113.245}) - .CubicCurveTo({340.594, 113.488}, {340.356, 113.655}, - {340.135, 113.775}) - .CubicCurveTo({339.817, 113.948}, {339.465, 114.059}, - {339.115, 114.151}) - .CubicCurveTo({338.251, 114.379}, {337.34, 114.516}, - {336.448, 114.516}) - .CubicCurveTo({335.761, 114.516}, {335.072, 114.527}, - {334.384, 114.513}) - .CubicCurveTo({334.125, 114.508}, {333.862, 114.462}, - {333.605, 114.424}) - .CubicCurveTo({332.865, 114.318}, {332.096, 114.184}, - {331.41, 113.883}) - .CubicCurveTo({330.979, 113.695}, {330.442, 113.34}, - {330.672, 112.813}) - .CubicCurveTo({331.135, 111.755}, {333.219, 112.946}, - {334.526, 113.833}) - .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784}) - .CubicCurveTo({333.38, 112.708}, {331.749, 110.985}, - {332.76, 110.402}) - .CubicCurveTo({333.769, 109.82}, {334.713, 111.93}, - {335.228, 113.395}) - .CubicCurveTo({334.915, 111.889}, {334.59, 109.636}, - {335.661, 109.592}) - .CubicCurveTo({336.733, 109.636}, {336.408, 111.889}, - {336.07, 113.389}) - .CubicCurveTo({336.609, 111.93}, {337.553, 109.82}, - {338.563, 110.402}) - .CubicCurveTo({339.574, 110.984}, {337.942, 112.708}, - {336.753, 113.784}) - .CubicCurveTo({336.768, 113.8}, {336.782, 113.816}, - {336.796, 113.833}) - .CubicCurveTo({338.104, 112.946}, {340.187, 111.755}, - {340.65, 112.813}) - .CubicCurveTo({340.71, 112.95}, {340.728, 113.102}, - {340.678, 113.245}) - .Close() - .MoveTo({346.357, 106.771}) - .CubicCurveTo({346.295, 104.987}, {347.924, 104.139}, - {347.924, 104.139}) - .CubicCurveTo({347.924, 104.139}, {347.982, 105.931}, - {346.357, 106.771}) - .Close() - .MoveTo({347.56, 106.771}) - .CubicCurveTo({347.498, 104.987}, {349.127, 104.139}, - {349.127, 104.139}) - .CubicCurveTo({349.127, 104.139}, {349.185, 105.931}, - {347.56, 106.771}) - .Close() - .TakePath(); +namespace { +/// A path with many connected cubic components, including +/// overlaps/self-intersections/multi-contour. +Path CreateCubic(); +/// Similar to the path above, but with all cubics replaced by quadratics. +Path CreateQuadratic(); +} // namespace + +template +static void BM_Polyline(benchmark::State& state, Args&&... args) { + auto args_tuple = std::make_tuple(std::move(args)...); + auto path = std::get(args_tuple); + bool tessellate = std::get(args_tuple); + size_t point_count = 0u; size_t single_point_count = 0u; + Tessellator tess; + while (state.KeepRunning()) { - single_point_count = path.CreatePolyline().points.size(); + auto polyline = path.CreatePolyline(); + single_point_count = polyline.points.size(); point_count += single_point_count; + if (tessellate) { + tess.Tessellate(FillType::kNonZero, polyline, [](Point) {}); + } } state.counters["SinglePointCount"] = single_point_count; state.counters["TotalPointCount"] = point_count; } -BENCHMARK(BM_ManyCubicPolyline); +BENCHMARK_CAPTURE(BM_Polyline, cubic_polyline, CreateCubic(), false); +BENCHMARK_CAPTURE(BM_Polyline, cubic_polyline_tess, CreateCubic(), true); +BENCHMARK_CAPTURE(BM_Polyline, quad_polyline, CreateQuadratic(), false); +BENCHMARK_CAPTURE(BM_Polyline, quad_polyline_tess, CreateQuadratic(), true); -static void BM_ManyQuadPolyline(benchmark::State& state) { - Path path = PathBuilder{} - .MoveTo({359.934, 96.6335}) - .QuadraticCurveTo({358.189, 96.7055}, {354.673, 96.8895}) - .QuadraticCurveTo({354.571, 96.8953}, {354.367, 96.9075}) - .QuadraticCurveTo({352.672, 97.0038}, {349.259, 97.2355}) - .QuadraticCurveTo({349.048, 97.2506}, {348.625, 97.2834}) - .QuadraticCurveTo({347.019, 97.4014}, {343.789, 97.6722}) - .QuadraticCurveTo({343.428, 97.704}, {342.703, 97.7734}) - .QuadraticCurveTo({341.221, 97.9086}, {338.246, 98.207}) - .QuadraticCurveTo({337.702, 98.2642}, {336.612, 98.3894}) - .QuadraticCurveTo({335.284, 98.5356}, {332.623, 98.8476}) - .QuadraticCurveTo({332.495, 98.8635}, {332.237, 98.8982}) - .LineTo({332.237, 102.601}) - .LineTo({321.778, 102.601}) - .LineTo({321.778, 100.382}) - .QuadraticCurveTo({321.572, 100.413}, {321.161, 100.476}) - .QuadraticCurveTo({319.22, 100.79}, {315.332, 101.479}) - .QuadraticCurveTo({315.322, 101.481}, {315.301, 101.484}) - .LineTo({310.017, 105.94}) - .LineTo({309.779, 105.427}) - .LineTo({314.403, 101.651}) - .QuadraticCurveTo({314.391, 101.653}, {314.368, 101.658}) - .QuadraticCurveTo({312.528, 102.001}, {308.846, 102.748}) - .QuadraticCurveTo({307.85, 102.955}, {305.859, 103.4}) - .QuadraticCurveTo({305.048, 103.579}, {303.425, 103.936}) - .LineTo({299.105, 107.578}) - .LineTo({298.867, 107.065}) - .LineTo({302.394, 104.185}) - .LineTo({302.412, 104.171}) - .QuadraticCurveTo({301.388, 104.409}, {299.344, 104.921}) - .QuadraticCurveTo({298.618, 105.1}, {297.165, 105.455}) - .QuadraticCurveTo({295.262, 105.94}, {291.462, 106.979}) - .QuadraticCurveTo({291.132, 107.072}, {290.471, 107.257}) - .QuadraticCurveTo({289.463, 107.544}, {287.449, 108.139}) - .QuadraticCurveTo({286.476, 108.431}, {284.536, 109.035}) - .QuadraticCurveTo({283.674, 109.304}, {281.952, 109.859}) - .QuadraticCurveTo({281.177, 110.112}, {279.633, 110.638}) - .QuadraticCurveTo({278.458, 111.037}, {276.803, 111.607}) - .QuadraticCurveTo({276.76, 111.622}, {276.672, 111.653}) - .QuadraticCurveTo({275.017, 112.239}, {271.721, 113.463}) - .LineTo({271.717, 113.449}) - .QuadraticCurveTo({271.496, 113.496}, {270.963, 113.628}) - .QuadraticCurveTo({270.893, 113.645}, {270.748, 113.682}) - .QuadraticCurveTo({270.468, 113.755}, {269.839, 113.926}) - .QuadraticCurveTo({269.789, 113.94}, {269.681, 113.972}) - .QuadraticCurveTo({269.391, 114.053}, {268.756, 114.239}) - .QuadraticCurveTo({268.628, 114.276}, {268.367, 114.354}) - .QuadraticCurveTo({268.172, 114.412}, {267.752, 114.54}) - .QuadraticCurveTo({263.349, 115.964}, {253.564, 119.252}) - .QuadraticCurveTo({253.556, 119.255}, {253.538, 119.261}) - .QuadraticCurveTo({251.844, 119.849}, {248.189, 121.131}) - .QuadraticCurveTo({248, 121.197}, {247.621, 121.331}) - .QuadraticCurveTo({247.079, 121.522}, {245.975, 121.912}) - .QuadraticCurveTo({245.554, 122.06}, {244.698, 122.364}) - .QuadraticCurveTo({244.071, 122.586}, {242.794, 123.04}) - .QuadraticCurveTo({242.189, 123.255}, {240.961, 123.693}) - .QuadraticCurveTo({240.659, 123.801}, {240.052, 124.018}) - .QuadraticCurveTo({239.12, 124.351}, {237.22, 125.032}) - .LineTo({237.164, 125.003}) - .QuadraticCurveTo({236.709, 125.184}, {235.81, 125.538}) - .QuadraticCurveTo({235.413, 125.68}, {234.592, 125.977}) - .QuadraticCurveTo({234.592, 125.977}, {234.59, 125.977}) - .QuadraticCurveTo({222.206, 130.435}, {192.381, 141.429}) - .QuadraticCurveTo({162.77, 151.336}, {84.1123, 160}) - .LineTo({360, 160}) - .LineTo({360, 119.256}) - .LineTo({360, 106.332}) - .LineTo({360, 96.6307}) - .QuadraticCurveTo({359.978, 96.6317}, {359.934, 96.6335}) - .Close() - .MoveTo({337.336, 124.143}) - .QuadraticCurveTo({337.274, 122.359}, {338.903, 121.511}) - .QuadraticCurveTo({338.903, 121.511}, {337.336, 124.143}) - .Close() - .MoveTo({340.082, 121.849}) - .QuadraticCurveTo({340.074, 121.917}, {340.046, 122.075}) - .QuadraticCurveTo({340.039, 122.109}, {340.023, 122.177}) - .QuadraticCurveTo({340.005, 122.26}, {339.952, 122.437}) - .QuadraticCurveTo({339.941, 122.473}, {339.918, 122.544}) - .QuadraticCurveTo({339.873, 122.672}, {339.75, 122.938}) - .QuadraticCurveTo({339.747, 122.944}, {339.74, 122.955}) - .QuadraticCurveTo({339.674, 123.08}, {339.501, 123.328}) - .QuadraticCurveTo({339.473, 123.366}, {339.41, 123.438}) - .QuadraticCurveTo({339.332, 123.534}, {339.145, 123.714}) - .QuadraticCurveTo({339.105, 123.75}, {339.025, 123.821}) - .QuadraticCurveTo({338.881, 123.937}, {338.539, 124.143}) - .QuadraticCurveTo({338.532, 123.959}, {338.58, 123.626}) - .QuadraticCurveTo({338.58, 123.625}, {338.58, 123.625}) - .QuadraticCurveTo({338.607, 123.455}, {338.704, 123.151}) - .QuadraticCurveTo({338.708, 123.14}, {338.714, 123.117}) - .QuadraticCurveTo({338.769, 122.971}, {338.905, 122.712}) - .QuadraticCurveTo({338.911, 122.702}, {338.922, 122.682}) - .QuadraticCurveTo({338.996, 122.557}, {339.155, 122.34}) - .QuadraticCurveTo({339.161, 122.333}, {339.172, 122.319}) - .QuadraticCurveTo({339.256, 122.215}, {339.425, 122.037}) - .QuadraticCurveTo({339.428, 122.033}, {339.435, 122.027}) - .QuadraticCurveTo({339.785, 121.687}, {340.106, 121.511}) - .QuadraticCurveTo({340.106, 121.511}, {340.082, 121.849}) - .Close() - .MoveTo({340.678, 113.245}) - .QuadraticCurveTo({340.594, 113.488}, {340.135, 113.775}) - .QuadraticCurveTo({339.817, 113.948}, {339.115, 114.151}) - .QuadraticCurveTo({338.251, 114.379}, {336.448, 114.516}) - .QuadraticCurveTo({335.761, 114.516}, {334.384, 114.513}) - .QuadraticCurveTo({334.125, 114.508}, {333.605, 114.424}) - .QuadraticCurveTo({332.865, 114.318}, {331.41, 113.883}) - .QuadraticCurveTo({330.979, 113.695}, {330.672, 112.813}) - .QuadraticCurveTo({331.135, 111.755}, {334.526, 113.833}) - .QuadraticCurveTo({334.54, 113.816}, {334.569, 113.784}) - .QuadraticCurveTo({333.38, 112.708}, {332.76, 110.402}) - .QuadraticCurveTo({333.769, 109.82}, {335.228, 113.395}) - .QuadraticCurveTo({334.915, 111.889}, {335.661, 109.592}) - .QuadraticCurveTo({336.733, 109.636}, {336.07, 113.389}) - .QuadraticCurveTo({336.609, 111.93}, {338.563, 110.402}) - .QuadraticCurveTo({339.574, 110.984}, {336.753, 113.784}) - .QuadraticCurveTo({336.768, 113.8}, {336.796, 113.833}) - .QuadraticCurveTo({338.104, 112.946}, {340.65, 112.813}) - .QuadraticCurveTo({340.71, 112.95}, {340.678, 113.245}) - .Close() - .MoveTo({346.357, 106.771}) - .QuadraticCurveTo({346.295, 104.987}, {347.924, 104.139}) - .QuadraticCurveTo({347.924, 104.139}, {346.357, 106.771}) - .Close() - .MoveTo({347.56, 106.771}) - .QuadraticCurveTo({347.498, 104.987}, {349.127, 104.139}) - .QuadraticCurveTo({349.127, 104.139}, {347.56, 106.771}) - .Close() - .TakePath(); - size_t point_count = 0u; - size_t single_point_count = 0u; - while (state.KeepRunning()) { - single_point_count = path.CreatePolyline().points.size(); - point_count += single_point_count; - } - state.counters["SinglePointCount"] = single_point_count; - state.counters["TotalPointCount"] = point_count; +namespace { +Path CreateCubic() { + return PathBuilder{} + .MoveTo({359.934, 96.6335}) + .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908}, {354.673, 96.8895}) + .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016}, {354.367, 96.9075}) + .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113}, {349.259, 97.2355}) + .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678}, {348.625, 97.2834}) + .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299}, {343.789, 97.6722}) + .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402}, {342.703, 97.7734}) + .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505}, {338.246, 98.207}) + .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292}, {336.612, 98.3894}) + .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837}, {332.623, 98.8476}) + .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818}, {332.237, 98.8982}) + .LineTo({332.237, 102.601}) + .LineTo({321.778, 102.601}) + .LineTo({321.778, 100.382}) + .CubicCurveTo({321.572, 100.413}, {321.367, 100.442}, {321.161, 100.476}) + .CubicCurveTo({319.22, 100.79}, {317.277, 101.123}, {315.332, 101.479}) + .CubicCurveTo({315.322, 101.481}, {315.311, 101.482}, {315.301, 101.484}) + .LineTo({310.017, 105.94}) + .LineTo({309.779, 105.427}) + .LineTo({314.403, 101.651}) + .CubicCurveTo({314.391, 101.653}, {314.379, 101.656}, {314.368, 101.658}) + .CubicCurveTo({312.528, 102.001}, {310.687, 102.366}, {308.846, 102.748}) + .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4}) + .CubicCurveTo({305.048, 103.579}, {304.236, 103.75}, {303.425, 103.936}) + .LineTo({299.105, 107.578}) + .LineTo({298.867, 107.065}) + .LineTo({302.394, 104.185}) + .LineTo({302.412, 104.171}) + .CubicCurveTo({301.388, 104.409}, {300.366, 104.67}, {299.344, 104.921}) + .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455}) + .CubicCurveTo({295.262, 105.94}, {293.36, 106.445}, {291.462, 106.979}) + .CubicCurveTo({291.132, 107.072}, {290.802, 107.163}, {290.471, 107.257}) + .CubicCurveTo({289.463, 107.544}, {288.455, 107.839}, {287.449, 108.139}) + .CubicCurveTo({286.476, 108.431}, {285.506, 108.73}, {284.536, 109.035}) + .CubicCurveTo({283.674, 109.304}, {282.812, 109.579}, {281.952, 109.859}) + .CubicCurveTo({281.177, 110.112}, {280.406, 110.377}, {279.633, 110.638}) + .CubicCurveTo({278.458, 111.037}, {277.256, 111.449}, {276.803, 111.607}) + .CubicCurveTo({276.76, 111.622}, {276.716, 111.637}, {276.672, 111.653}) + .CubicCurveTo({275.017, 112.239}, {273.365, 112.836}, {271.721, 113.463}) + .LineTo({271.717, 113.449}) + .CubicCurveTo({271.496, 113.496}, {271.238, 113.559}, {270.963, 113.628}) + .CubicCurveTo({270.893, 113.645}, {270.822, 113.663}, {270.748, 113.682}) + .CubicCurveTo({270.468, 113.755}, {270.169, 113.834}, {269.839, 113.926}) + .CubicCurveTo({269.789, 113.94}, {269.732, 113.957}, {269.681, 113.972}) + .CubicCurveTo({269.391, 114.053}, {269.081, 114.143}, {268.756, 114.239}) + .CubicCurveTo({268.628, 114.276}, {268.5, 114.314}, {268.367, 114.354}) + .CubicCurveTo({268.172, 114.412}, {267.959, 114.478}, {267.752, 114.54}) + .CubicCurveTo({263.349, 115.964}, {258.058, 117.695}, {253.564, 119.252}) + .CubicCurveTo({253.556, 119.255}, {253.547, 119.258}, {253.538, 119.261}) + .CubicCurveTo({251.844, 119.849}, {250.056, 120.474}, {248.189, 121.131}) + .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331}) + .CubicCurveTo({247.079, 121.522}, {246.531, 121.715}, {245.975, 121.912}) + .CubicCurveTo({245.554, 122.06}, {245.126, 122.212}, {244.698, 122.364}) + .CubicCurveTo({244.071, 122.586}, {243.437, 122.811}, {242.794, 123.04}) + .CubicCurveTo({242.189, 123.255}, {241.58, 123.472}, {240.961, 123.693}) + .CubicCurveTo({240.659, 123.801}, {240.357, 123.909}, {240.052, 124.018}) + .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032}) + .LineTo({237.164, 125.003}) + .CubicCurveTo({236.709, 125.184}, {236.262, 125.358}, {235.81, 125.538}) + .CubicCurveTo({235.413, 125.68}, {234.994, 125.832}, {234.592, 125.977}) + .CubicCurveTo({234.592, 125.977}, {234.591, 125.977}, {234.59, 125.977}) + .CubicCurveTo({222.206, 130.435}, {207.708, 135.753}, {192.381, 141.429}) + .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160}) + .LineTo({360, 160}) + .LineTo({360, 119.256}) + .LineTo({360, 106.332}) + .LineTo({360, 96.6307}) + .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326}, {359.934, 96.6335}) + .Close() + .MoveTo({337.336, 124.143}) + .CubicCurveTo({337.274, 122.359}, {338.903, 121.511}, {338.903, 121.511}) + .CubicCurveTo({338.903, 121.511}, {338.96, 123.303}, {337.336, 124.143}) + .Close() + .MoveTo({340.082, 121.849}) + .CubicCurveTo({340.074, 121.917}, {340.062, 121.992}, {340.046, 122.075}) + .CubicCurveTo({340.039, 122.109}, {340.031, 122.142}, {340.023, 122.177}) + .CubicCurveTo({340.005, 122.26}, {339.98, 122.346}, {339.952, 122.437}) + .CubicCurveTo({339.941, 122.473}, {339.931, 122.507}, {339.918, 122.544}) + .CubicCurveTo({339.873, 122.672}, {339.819, 122.804}, {339.75, 122.938}) + .CubicCurveTo({339.747, 122.944}, {339.743, 122.949}, {339.74, 122.955}) + .CubicCurveTo({339.674, 123.08}, {339.593, 123.205}, {339.501, 123.328}) + .CubicCurveTo({339.473, 123.366}, {339.441, 123.401}, {339.41, 123.438}) + .CubicCurveTo({339.332, 123.534}, {339.243, 123.625}, {339.145, 123.714}) + .CubicCurveTo({339.105, 123.75}, {339.068, 123.786}, {339.025, 123.821}) + .CubicCurveTo({338.881, 123.937}, {338.724, 124.048}, {338.539, 124.143}) + .CubicCurveTo({338.532, 123.959}, {338.554, 123.79}, {338.58, 123.626}) + .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625}) + .CubicCurveTo({338.607, 123.455}, {338.65, 123.299}, {338.704, 123.151}) + .CubicCurveTo({338.708, 123.14}, {338.71, 123.127}, {338.714, 123.117}) + .CubicCurveTo({338.769, 122.971}, {338.833, 122.838}, {338.905, 122.712}) + .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001}, + {338.922, 122.682}) + .CubicCurveTo({338.996, 122.557}, {339.072, 122.444}, {339.155, 122.34}) + .CubicCurveTo({339.161, 122.333}, {339.166, 122.326}, {339.172, 122.319}) + .CubicCurveTo({339.256, 122.215}, {339.339, 122.12}, {339.425, 122.037}) + .CubicCurveTo({339.428, 122.033}, {339.431, 122.03}, {339.435, 122.027}) + .CubicCurveTo({339.785, 121.687}, {340.106, 121.511}, {340.106, 121.511}) + .CubicCurveTo({340.106, 121.511}, {340.107, 121.645}, {340.082, 121.849}) + .Close() + .MoveTo({340.678, 113.245}) + .CubicCurveTo({340.594, 113.488}, {340.356, 113.655}, {340.135, 113.775}) + .CubicCurveTo({339.817, 113.948}, {339.465, 114.059}, {339.115, 114.151}) + .CubicCurveTo({338.251, 114.379}, {337.34, 114.516}, {336.448, 114.516}) + .CubicCurveTo({335.761, 114.516}, {335.072, 114.527}, {334.384, 114.513}) + .CubicCurveTo({334.125, 114.508}, {333.862, 114.462}, {333.605, 114.424}) + .CubicCurveTo({332.865, 114.318}, {332.096, 114.184}, {331.41, 113.883}) + .CubicCurveTo({330.979, 113.695}, {330.442, 113.34}, {330.672, 112.813}) + .CubicCurveTo({331.135, 111.755}, {333.219, 112.946}, {334.526, 113.833}) + .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784}) + .CubicCurveTo({333.38, 112.708}, {331.749, 110.985}, {332.76, 110.402}) + .CubicCurveTo({333.769, 109.82}, {334.713, 111.93}, {335.228, 113.395}) + .CubicCurveTo({334.915, 111.889}, {334.59, 109.636}, {335.661, 109.592}) + .CubicCurveTo({336.733, 109.636}, {336.408, 111.889}, {336.07, 113.389}) + .CubicCurveTo({336.609, 111.93}, {337.553, 109.82}, {338.563, 110.402}) + .CubicCurveTo({339.574, 110.984}, {337.942, 112.708}, {336.753, 113.784}) + .CubicCurveTo({336.768, 113.8}, {336.782, 113.816}, {336.796, 113.833}) + .CubicCurveTo({338.104, 112.946}, {340.187, 111.755}, {340.65, 112.813}) + .CubicCurveTo({340.71, 112.95}, {340.728, 113.102}, {340.678, 113.245}) + .Close() + .MoveTo({346.357, 106.771}) + .CubicCurveTo({346.295, 104.987}, {347.924, 104.139}, {347.924, 104.139}) + .CubicCurveTo({347.924, 104.139}, {347.982, 105.931}, {346.357, 106.771}) + .Close() + .MoveTo({347.56, 106.771}) + .CubicCurveTo({347.498, 104.987}, {349.127, 104.139}, {349.127, 104.139}) + .CubicCurveTo({349.127, 104.139}, {349.185, 105.931}, {347.56, 106.771}) + .Close() + .TakePath(); } -BENCHMARK(BM_ManyQuadPolyline); +Path CreateQuadratic() { + return PathBuilder{} + .MoveTo({359.934, 96.6335}) + .QuadraticCurveTo({358.189, 96.7055}, {354.673, 96.8895}) + .QuadraticCurveTo({354.571, 96.8953}, {354.367, 96.9075}) + .QuadraticCurveTo({352.672, 97.0038}, {349.259, 97.2355}) + .QuadraticCurveTo({349.048, 97.2506}, {348.625, 97.2834}) + .QuadraticCurveTo({347.019, 97.4014}, {343.789, 97.6722}) + .QuadraticCurveTo({343.428, 97.704}, {342.703, 97.7734}) + .QuadraticCurveTo({341.221, 97.9086}, {338.246, 98.207}) + .QuadraticCurveTo({337.702, 98.2642}, {336.612, 98.3894}) + .QuadraticCurveTo({335.284, 98.5356}, {332.623, 98.8476}) + .QuadraticCurveTo({332.495, 98.8635}, {332.237, 98.8982}) + .LineTo({332.237, 102.601}) + .LineTo({321.778, 102.601}) + .LineTo({321.778, 100.382}) + .QuadraticCurveTo({321.572, 100.413}, {321.161, 100.476}) + .QuadraticCurveTo({319.22, 100.79}, {315.332, 101.479}) + .QuadraticCurveTo({315.322, 101.481}, {315.301, 101.484}) + .LineTo({310.017, 105.94}) + .LineTo({309.779, 105.427}) + .LineTo({314.403, 101.651}) + .QuadraticCurveTo({314.391, 101.653}, {314.368, 101.658}) + .QuadraticCurveTo({312.528, 102.001}, {308.846, 102.748}) + .QuadraticCurveTo({307.85, 102.955}, {305.859, 103.4}) + .QuadraticCurveTo({305.048, 103.579}, {303.425, 103.936}) + .LineTo({299.105, 107.578}) + .LineTo({298.867, 107.065}) + .LineTo({302.394, 104.185}) + .LineTo({302.412, 104.171}) + .QuadraticCurveTo({301.388, 104.409}, {299.344, 104.921}) + .QuadraticCurveTo({298.618, 105.1}, {297.165, 105.455}) + .QuadraticCurveTo({295.262, 105.94}, {291.462, 106.979}) + .QuadraticCurveTo({291.132, 107.072}, {290.471, 107.257}) + .QuadraticCurveTo({289.463, 107.544}, {287.449, 108.139}) + .QuadraticCurveTo({286.476, 108.431}, {284.536, 109.035}) + .QuadraticCurveTo({283.674, 109.304}, {281.952, 109.859}) + .QuadraticCurveTo({281.177, 110.112}, {279.633, 110.638}) + .QuadraticCurveTo({278.458, 111.037}, {276.803, 111.607}) + .QuadraticCurveTo({276.76, 111.622}, {276.672, 111.653}) + .QuadraticCurveTo({275.017, 112.239}, {271.721, 113.463}) + .LineTo({271.717, 113.449}) + .QuadraticCurveTo({271.496, 113.496}, {270.963, 113.628}) + .QuadraticCurveTo({270.893, 113.645}, {270.748, 113.682}) + .QuadraticCurveTo({270.468, 113.755}, {269.839, 113.926}) + .QuadraticCurveTo({269.789, 113.94}, {269.681, 113.972}) + .QuadraticCurveTo({269.391, 114.053}, {268.756, 114.239}) + .QuadraticCurveTo({268.628, 114.276}, {268.367, 114.354}) + .QuadraticCurveTo({268.172, 114.412}, {267.752, 114.54}) + .QuadraticCurveTo({263.349, 115.964}, {253.564, 119.252}) + .QuadraticCurveTo({253.556, 119.255}, {253.538, 119.261}) + .QuadraticCurveTo({251.844, 119.849}, {248.189, 121.131}) + .QuadraticCurveTo({248, 121.197}, {247.621, 121.331}) + .QuadraticCurveTo({247.079, 121.522}, {245.975, 121.912}) + .QuadraticCurveTo({245.554, 122.06}, {244.698, 122.364}) + .QuadraticCurveTo({244.071, 122.586}, {242.794, 123.04}) + .QuadraticCurveTo({242.189, 123.255}, {240.961, 123.693}) + .QuadraticCurveTo({240.659, 123.801}, {240.052, 124.018}) + .QuadraticCurveTo({239.12, 124.351}, {237.22, 125.032}) + .LineTo({237.164, 125.003}) + .QuadraticCurveTo({236.709, 125.184}, {235.81, 125.538}) + .QuadraticCurveTo({235.413, 125.68}, {234.592, 125.977}) + .QuadraticCurveTo({234.592, 125.977}, {234.59, 125.977}) + .QuadraticCurveTo({222.206, 130.435}, {192.381, 141.429}) + .QuadraticCurveTo({162.77, 151.336}, {84.1123, 160}) + .LineTo({360, 160}) + .LineTo({360, 119.256}) + .LineTo({360, 106.332}) + .LineTo({360, 96.6307}) + .QuadraticCurveTo({359.978, 96.6317}, {359.934, 96.6335}) + .Close() + .MoveTo({337.336, 124.143}) + .QuadraticCurveTo({337.274, 122.359}, {338.903, 121.511}) + .QuadraticCurveTo({338.903, 121.511}, {337.336, 124.143}) + .Close() + .MoveTo({340.082, 121.849}) + .QuadraticCurveTo({340.074, 121.917}, {340.046, 122.075}) + .QuadraticCurveTo({340.039, 122.109}, {340.023, 122.177}) + .QuadraticCurveTo({340.005, 122.26}, {339.952, 122.437}) + .QuadraticCurveTo({339.941, 122.473}, {339.918, 122.544}) + .QuadraticCurveTo({339.873, 122.672}, {339.75, 122.938}) + .QuadraticCurveTo({339.747, 122.944}, {339.74, 122.955}) + .QuadraticCurveTo({339.674, 123.08}, {339.501, 123.328}) + .QuadraticCurveTo({339.473, 123.366}, {339.41, 123.438}) + .QuadraticCurveTo({339.332, 123.534}, {339.145, 123.714}) + .QuadraticCurveTo({339.105, 123.75}, {339.025, 123.821}) + .QuadraticCurveTo({338.881, 123.937}, {338.539, 124.143}) + .QuadraticCurveTo({338.532, 123.959}, {338.58, 123.626}) + .QuadraticCurveTo({338.58, 123.625}, {338.58, 123.625}) + .QuadraticCurveTo({338.607, 123.455}, {338.704, 123.151}) + .QuadraticCurveTo({338.708, 123.14}, {338.714, 123.117}) + .QuadraticCurveTo({338.769, 122.971}, {338.905, 122.712}) + .QuadraticCurveTo({338.911, 122.702}, {338.922, 122.682}) + .QuadraticCurveTo({338.996, 122.557}, {339.155, 122.34}) + .QuadraticCurveTo({339.161, 122.333}, {339.172, 122.319}) + .QuadraticCurveTo({339.256, 122.215}, {339.425, 122.037}) + .QuadraticCurveTo({339.428, 122.033}, {339.435, 122.027}) + .QuadraticCurveTo({339.785, 121.687}, {340.106, 121.511}) + .QuadraticCurveTo({340.106, 121.511}, {340.082, 121.849}) + .Close() + .MoveTo({340.678, 113.245}) + .QuadraticCurveTo({340.594, 113.488}, {340.135, 113.775}) + .QuadraticCurveTo({339.817, 113.948}, {339.115, 114.151}) + .QuadraticCurveTo({338.251, 114.379}, {336.448, 114.516}) + .QuadraticCurveTo({335.761, 114.516}, {334.384, 114.513}) + .QuadraticCurveTo({334.125, 114.508}, {333.605, 114.424}) + .QuadraticCurveTo({332.865, 114.318}, {331.41, 113.883}) + .QuadraticCurveTo({330.979, 113.695}, {330.672, 112.813}) + .QuadraticCurveTo({331.135, 111.755}, {334.526, 113.833}) + .QuadraticCurveTo({334.54, 113.816}, {334.569, 113.784}) + .QuadraticCurveTo({333.38, 112.708}, {332.76, 110.402}) + .QuadraticCurveTo({333.769, 109.82}, {335.228, 113.395}) + .QuadraticCurveTo({334.915, 111.889}, {335.661, 109.592}) + .QuadraticCurveTo({336.733, 109.636}, {336.07, 113.389}) + .QuadraticCurveTo({336.609, 111.93}, {338.563, 110.402}) + .QuadraticCurveTo({339.574, 110.984}, {336.753, 113.784}) + .QuadraticCurveTo({336.768, 113.8}, {336.796, 113.833}) + .QuadraticCurveTo({338.104, 112.946}, {340.65, 112.813}) + .QuadraticCurveTo({340.71, 112.95}, {340.678, 113.245}) + .Close() + .MoveTo({346.357, 106.771}) + .QuadraticCurveTo({346.295, 104.987}, {347.924, 104.139}) + .QuadraticCurveTo({347.924, 104.139}, {346.357, 106.771}) + .Close() + .MoveTo({347.56, 106.771}) + .QuadraticCurveTo({347.498, 104.987}, {349.127, 104.139}) + .QuadraticCurveTo({349.127, 104.139}, {347.56, 106.771}) + .Close() + .TakePath(); +} +} // namespace } // namespace impeller From 3ac466e911ebe00739d7ac2fc89c569f025a5aa5 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 14 Oct 2022 11:15:08 -0700 Subject: [PATCH 07/10] unused test code --- impeller/geometry/geometry_unittests.cc | 130 ------------------------ 1 file changed, 130 deletions(-) diff --git a/impeller/geometry/geometry_unittests.cc b/impeller/geometry/geometry_unittests.cc index 0a227cb2e900c..f88df791d6bff 100644 --- a/impeller/geometry/geometry_unittests.cc +++ b/impeller/geometry/geometry_unittests.cc @@ -1713,135 +1713,5 @@ TEST(GeometryTest, Gradient) { } } -static void LogPoint(Point p, bool comma) { - if (comma) { - std::cout << "{x: " << p.x << ", y: " << p.y << "}," << std::endl; - } else { - std::cout << "{x: " << p.x << ", y: " << p.y << "}" << std::endl; - } -} - -static Scalar ApproximateParabolaIntegral(Scalar x) { - constexpr Scalar d = 0.67; - return x / (1.0 - d + sqrt(sqrt(pow(d, 4) + 0.25 * x * x))); -} - -static std::vector CreateQuadPolyline( - const QuadraticPathComponent& component) { - auto tolerance = .1f; - auto sqrt_tol = sqrt(tolerance); - - auto d01 = component.cp - component.p1; - auto d12 = component.p2 - component.cp; - auto dd = d01 - d12; - auto cross = (component.p2 - component.p1).Cross(dd); - auto x0 = d01.Dot(dd) * 1 / cross; - auto x2 = d12.Dot(dd) * 1 / cross; - auto scale = abs(cross / (hypot(dd.x, dd.y) * (x2 - x0))); - - auto a0 = ApproximateParabolaIntegral(x0); - auto a2 = ApproximateParabolaIntegral(x2); - Scalar val = 0.f; - if (isfinite(scale)) { - auto da = abs(a2 - a0); - auto sqrt_scale = sqrt(scale); - if ((x0 < 0 && x2 < 0) || (x0 >= 0 && x2 >= 0)) { - val = da * sqrt_scale; - } else { - // cusp case - auto xmin = sqrt_tol / sqrt_scale; - val = sqrt_tol * da / ApproximateParabolaIntegral(xmin); - } - } - auto u0 = ApproximateParabolaIntegral(a0); - auto u2 = ApproximateParabolaIntegral(a2); - auto uscale = 1 / (u2 - u0); - - auto line_count = ceil(0.5 * val / sqrt_tol); - auto step = 1 / line_count; - FML_LOG(ERROR) << "Line count: " << line_count; - for (size_t i = 1; i < line_count; i += 1) { - auto u = i * step; - auto a = a0 + (a2 - a0) * u; - auto t = (ApproximateParabolaIntegral(a) - u0) * uscale; - LogPoint(component.Solve(t), true); - } - LogPoint(component.p2, false); - - return {}; -} - -static std::vector CreateCubicPolyline( - const CubicPathComponent& component) { - FML_LOG(ERROR) << "New"; - - Scalar t = 0; - - CubicPathComponent current_component = component; - int count = 0; - while (t < 1.0) { - count += 1; - - auto v1 = current_component.cp1 - current_component.p1; - auto v2 = current_component.cp2 - current_component.p1; - - auto s = abs(v2.Cross(v1) / hypot(v1.x, v1.y)); - - if (s < kEhCloseEnough) { - break; - } - - constexpr Scalar f = 0.005; - t = 2 * sqrt(f / (3.f * s)); - - // P'1 - auto ab = current_component.p1 + - t * (current_component.cp1 - current_component.p1); - // P'2 - auto bc = current_component.cp1 + - t * (current_component.cp2 - current_component.cp1); - // P'3 - auto cd = current_component.cp2 + - t * (current_component.p2 - current_component.cp2); - - // P''1 - auto abc = ab + t * (bc - ab); - // P''2 - auto bcd = bc + t * (cd - bc); - - // P'''1 - auto abcd = abc + t * (bcd - abc); - - current_component = {abcd, bcd, cd, current_component.p2}; - LogPoint(abcd, true); - } - LogPoint(component.p2, false); - FML_LOG(ERROR) << count; - return {}; -} - -TEST(GeometryTest, NewPolylineAlgo) { - // CubicPathComponent component({10, 10}, {25, 12}, {40, 15}, {38, 24}); - CubicPathComponent component({100, 100}, {300, 200}, {200, 200}, {200, 100}); - auto points = component.CreatePolyline(); - LogPoint({100, 100}, true); - for (auto point : points) { - LogPoint(point, point != points.back()); - } - FML_LOG(ERROR) << points.size(); - CreateCubicPolyline(component); -} - -TEST(GeometryTest, NewQuadPolylineAlgo) { - QuadraticPathComponent component({100, 100}, {300, 200}, {200, 100}); - auto points = component.CreatePolyline(); - // LogPoint({100, 100}, true); - for (auto point : points) { - LogPoint(point, point != points.back()); - } - FML_LOG(ERROR) << points.size(); - CreateQuadPolyline(component); -} - } // namespace testing } // namespace impeller From 3fc3ff9e52321ef6e8e1d57b4850589a07298ab2 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 14 Oct 2022 11:22:46 -0700 Subject: [PATCH 08/10] make tessellator static --- impeller/geometry/geometry_benchmarks.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/geometry/geometry_benchmarks.cc b/impeller/geometry/geometry_benchmarks.cc index eff277fbf88eb..9b6631871bf45 100644 --- a/impeller/geometry/geometry_benchmarks.cc +++ b/impeller/geometry/geometry_benchmarks.cc @@ -18,6 +18,8 @@ Path CreateCubic(); Path CreateQuadratic(); } // namespace +static Tessellator tess; + template static void BM_Polyline(benchmark::State& state, Args&&... args) { auto args_tuple = std::make_tuple(std::move(args)...); @@ -26,8 +28,6 @@ static void BM_Polyline(benchmark::State& state, Args&&... args) { size_t point_count = 0u; size_t single_point_count = 0u; - Tessellator tess; - while (state.KeepRunning()) { auto polyline = path.CreatePolyline(); single_point_count = polyline.points.size(); From dd0c272484db01dd4624a32fd2088e142c61745e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 18 Oct 2022 20:35:15 -0700 Subject: [PATCH 09/10] review --- impeller/geometry/path_component.cc | 8 ++++---- impeller/tessellator/c/tessellator.cc | 4 +--- impeller/tessellator/c/tessellator.h | 5 +---- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/impeller/geometry/path_component.cc b/impeller/geometry/path_component.cc index 92eb1f6d1d9ad..04eb592cb6ac5 100644 --- a/impeller/geometry/path_component.cc +++ b/impeller/geometry/path_component.cc @@ -108,7 +108,7 @@ void QuadraticPathComponent::FillPointsForPolyline(std::vector& points, auto a0 = ApproximateParabolaIntegral(x0); auto a2 = ApproximateParabolaIntegral(x2); Scalar val = 0.f; - if (isfinite(scale)) { + if (std::isfinite(scale)) { auto da = abs(a2 - a0); auto sqrt_scale = sqrt(scale); if ((x0 < 0 && x2 < 0) || (x0 >= 0 && x2 >= 0)) { @@ -154,7 +154,7 @@ Point CubicPathComponent::SolveDerivative(Scalar time) const { } std::vector CubicPathComponent::CreatePolyline(Scalar tolerance) const { - auto quads = ToQuadratics(.1); + auto quads = ToQuadraticPathComponents(.1); std::vector points; for (const auto& quad : quads) { quad.FillPointsForPolyline(points, tolerance); @@ -177,8 +177,8 @@ CubicPathComponent CubicPathComponent::Subsegment(Scalar t0, Scalar t1) const { return CubicPathComponent(p0, p1, p2, p3); } -std::vector CubicPathComponent::ToQuadratics( - Scalar accuracy) const { +std::vector +CubicPathComponent::ToQuadraticPathComponents(Scalar accuracy) const { std::vector quads; // The maximum error, as a vector from the cubic to the best approximating // quadratic, is proportional to the third derivative, which is constant diff --git a/impeller/tessellator/c/tessellator.cc b/impeller/tessellator/c/tessellator.cc index 6798b94187d95..1bdbfde66db84 100644 --- a/impeller/tessellator/c/tessellator.cc +++ b/impeller/tessellator/c/tessellator.cc @@ -39,9 +39,7 @@ void Close(PathBuilder* builder) { struct Vertices* Tessellate(PathBuilder* builder, int fill_type, - Scalar tolerance, - Scalar angle_tolerance, - Scalar cusp_limit) { + Scalar tolerance) { auto path = builder->CopyPath(static_cast(fill_type)); auto polyline = path.CreatePolyline(tolerance); std::vector points; diff --git a/impeller/tessellator/c/tessellator.h b/impeller/tessellator/c/tessellator.h index 0cb01d68f6c42..7a323b5413233 100644 --- a/impeller/tessellator/c/tessellator.h +++ b/impeller/tessellator/c/tessellator.h @@ -42,10 +42,7 @@ IMPELLER_API void Close(PathBuilder* builder); IMPELLER_API struct Vertices* Tessellate(PathBuilder* builder, int fill_type, - Scalar tolerance, - // Unused, remaining for ABI stability. - Scalar angle_tolerance, - Scalar cusp_limit); + Scalar tolerance); IMPELLER_API void DestroyVertices(Vertices* vertices); From bbe5364699e731c5974519bb6c9a7796b10b6eb1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 18 Oct 2022 21:04:21 -0700 Subject: [PATCH 10/10] Save before commit... --- impeller/geometry/path_component.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/impeller/geometry/path_component.h b/impeller/geometry/path_component.h index cf7b275581049..df658eaf580ce 100644 --- a/impeller/geometry/path_component.h +++ b/impeller/geometry/path_component.h @@ -108,7 +108,8 @@ struct CubicPathComponent { std::vector Extrema() const; - std::vector ToQuadratics(Scalar accuracy) const; + std::vector ToQuadraticPathComponents( + Scalar accuracy) const; CubicPathComponent Subsegment(Scalar t0, Scalar t1) const;