Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: add Canvas.drawVertices render pathway for PolygonLayer & fix bundled drawing #1800

Merged
merged 28 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8766aa1
Added 'dart_earcut' dependency
JaffaKetchup Jan 15, 2024
8183af8
Merge branch 'master' into polygon-draw-vertices
JaffaKetchup Jan 22, 2024
7475930
Initial implementation of triangulation and `drawVertices`/`drawRawPo…
JaffaKetchup Jan 23, 2024
9213570
Merge branch 'master' into polygon-draw-vertices
JaffaKetchup Jan 23, 2024
e51877c
Improvements to Polygon Stress Testing example page
JaffaKetchup Jan 24, 2024
62650f9
Removed internal `_renderPoints` flag in favour of `false` (as yields…
JaffaKetchup Jan 24, 2024
5b65017
Added `PolygonLayer.performantRendering` argument to replace internal…
JaffaKetchup Jan 24, 2024
9a0e7bd
Add support for holes
JaffaKetchup Jan 28, 2024
946db37
Check deviation
JaffaKetchup Jan 28, 2024
45dac8e
Revert "Check deviation"
JaffaKetchup Jan 28, 2024
539f3de
Added `Polygon` feature level `performantRendering` parameter
JaffaKetchup Jan 28, 2024
beb598f
Changed `Polygon.performantRendering` type to `bool?` (to allow to in…
JaffaKetchup Jan 28, 2024
7f2af33
Updated dart_earcut dependency to v1.1.0
JaffaKetchup Jan 31, 2024
9f4b4de
Disabled `performantRendering` by default (at layer-level)
JaffaKetchup Jan 31, 2024
8dcdf8a
Fix Polygons page in example app
JaffaKetchup Jan 31, 2024
2eddc12
Merge branch 'master' into polygon-draw-vertices
JaffaKetchup Feb 3, 2024
5b69740
Improved Polygon Stress Test example with more customizable border th…
JaffaKetchup Feb 5, 2024
e879cc6
Fix `Polygon` equality to include `performantRendering`
JaffaKetchup Feb 6, 2024
94feab1
Removed unneccesary `holePointsList` from `Polygon.renderHashCode`
JaffaKetchup Feb 6, 2024
d6dd475
Merge branch 'master' into polygon-draw-vertices
JaffaKetchup Feb 6, 2024
ec6d7bf
Merge branch 'master' into polygon-draw-vertices
JaffaKetchup Feb 6, 2024
d6ad752
Minor performance improvements
JaffaKetchup Feb 6, 2024
dc0d83a
Minor performance improvements
JaffaKetchup Feb 6, 2024
87e0bd5
Documentation fix
JaffaKetchup Feb 6, 2024
9475c7a
Renamed `PolygonLayer.performantRendering` to `useAltRendering`
JaffaKetchup Feb 12, 2024
dfcac55
Minor change to remove dependency on 'dart:math' in one file
JaffaKetchup Feb 12, 2024
69f7f73
Minor efficiency improvement
JaffaKetchup Feb 13, 2024
c68599d
Merge branch 'master' into polygon-draw-vertices
josxha Feb 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 90 additions & 28 deletions example/lib/pages/polygon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ class PolygonPage extends StatelessWidget {
LatLng(54.3498, -6.2603),
LatLng(52.8566, 2.3522),
];
final _notFilledDotedPoints = const [
LatLng(49.29, -2.57),
LatLng(51.46, -6.43),
LatLng(49.86, -8.17),
LatLng(48.39, -3.49),
];
final _filledDotedPoints = const [
LatLng(46.35, 4.94),
LatLng(46.22, -0.11),
Expand All @@ -43,17 +37,36 @@ class PolygonPage extends StatelessWidget {
LatLng(59.77, -7.01),
LatLng(60.77, -6.01),
];
final _holeOuterPoints = const [
final _normalHoleOuterPoints = const [
LatLng(50, -18),
LatLng(50, -14),
LatLng(51.5, -12.5),
LatLng(54, -14),
LatLng(54, -18),
];
final _brokenHoleOuterPoints = const [
LatLng(50, -18),
LatLng(53, -16),
LatLng(51.5, -12.5),
LatLng(54, -14),
LatLng(54, -18),
];
final _holeInnerPoints = const [
LatLng(51, -17),
LatLng(51, -16),
LatLng(52, -16),
LatLng(52, -17),
[
LatLng(52, -17),
LatLng(52, -16),
LatLng(51.5, -15.5),
LatLng(51, -16),
LatLng(51, -17),
],
[
LatLng(53.5, -17),
LatLng(53.5, -16),
LatLng(53, -15),
LatLng(52.25, -15),
LatLng(52.25, -16),
LatLng(52.75, -17),
],
];

@override
Expand Down Expand Up @@ -84,12 +97,6 @@ class PolygonPage extends StatelessWidget {
borderColor: Colors.yellow,
borderStrokeWidth: 4,
),
Polygon(
points: _notFilledDotedPoints,
isDotted: true,
borderColor: Colors.green,
borderStrokeWidth: 4,
),
Polygon(
points: _filledDotedPoints,
isDotted: true,
Expand All @@ -112,25 +119,80 @@ class PolygonPage extends StatelessWidget {
labelPlacement: PolygonLabelPlacement.polylabel,
),
Polygon(
points: _holeOuterPoints,
holePointsList: [_holeInnerPoints],
points: _normalHoleOuterPoints
.map((latlng) =>
LatLng(latlng.latitude, latlng.longitude + 8))
.toList(),
isDotted: true,
holePointsList: _holeInnerPoints
.map(
(latlngs) => latlngs
.map((latlng) =>
LatLng(latlng.latitude, latlng.longitude + 8))
.toList(),
)
.toList(),
borderStrokeWidth: 4,
borderColor: Colors.green,
borderColor: Colors.orange,
color: Colors.orange.withOpacity(0.5),
performantRendering: false,
label: 'This one is not\nperformantly rendered',
rotateLabel: true,
labelPlacement: PolygonLabelPlacement.centroid,
labelStyle: const TextStyle(color: Colors.black),
),
Polygon(
points: _holeOuterPoints
points: _brokenHoleOuterPoints
.map((latlng) =>
LatLng(latlng.latitude, latlng.longitude + 8))
LatLng(latlng.latitude - 6, latlng.longitude + 8))
.toList(),
isDotted: true,
holePointsList: [
_holeInnerPoints
.map((latlng) =>
LatLng(latlng.latitude, latlng.longitude + 8))
.toList()
],
holePointsList: _holeInnerPoints
.map(
(latlngs) => latlngs
.map((latlng) => LatLng(
latlng.latitude - 6, latlng.longitude + 8))
.toList(),
)
.toList(),
borderStrokeWidth: 4,
borderColor: Colors.orange,
color: Colors.orange.withOpacity(0.5),
performantRendering: false,
label: 'This one is not\nperformantly rendered',
rotateLabel: true,
labelPlacement: PolygonLabelPlacement.centroid,
labelStyle: const TextStyle(color: Colors.black),
),
],
),
PolygonLayer(
simplificationTolerance: 0,
performantRendering: true,
polygons: [
Polygon(
points: _normalHoleOuterPoints,
holePointsList: _holeInnerPoints,
borderStrokeWidth: 4,
borderColor: Colors.black,
color: Colors.green,
),
Polygon(
points: _brokenHoleOuterPoints
.map((latlng) =>
LatLng(latlng.latitude - 6, latlng.longitude))
.toList(),
holePointsList: _holeInnerPoints
.map(
(latlngs) => latlngs
.map((latlng) =>
LatLng(latlng.latitude - 6, latlng.longitude))
.toList(),
)
.toList(),
borderStrokeWidth: 4,
borderColor: Colors.black,
color: Colors.green,
),
],
),
Expand Down
180 changes: 166 additions & 14 deletions example/lib/pages/polygon_perf_stress.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Expand All @@ -21,14 +23,12 @@ class PolygonPerfStressPage extends StatefulWidget {
class _PolygonPerfStressPageState extends State<PolygonPerfStressPage> {
static const double _initialSimplificationTolerance = 0.5;
double simplificationTolerance = _initialSimplificationTolerance;
static const bool _initialUsePerformantDrawing = true;
bool usePerformantRendering = _initialUsePerformantDrawing;
static const double _initialBorderThickness = 1;
double borderThickness = _initialBorderThickness;
JaffaKetchup marked this conversation as resolved.
Show resolved Hide resolved

late final geoJsonLoader =
rootBundle.loadString('assets/138k-polygon-points.geojson.noformat').then(
(geoJson) => compute(
(geoJson) => GeoJsonParser()..parseGeoJsonAsString(geoJson),
geoJson,
),
);
late Future<GeoJsonParser> geoJsonParser = loadPolygonsFromGeoJson();

@override
void initState() {
Expand All @@ -38,7 +38,7 @@ class _PolygonPerfStressPageState extends State<PolygonPerfStressPage> {

@override
void dispose() {
geoJsonLoader.ignore();
geoJsonParser.ignore();
JaffaKetchup marked this conversation as resolved.
Show resolved Hide resolved
super.dispose();
}

Expand Down Expand Up @@ -67,14 +67,15 @@ class _PolygonPerfStressPageState extends State<PolygonPerfStressPage> {
children: [
openStreetMapTileLayer,
FutureBuilder(
future: geoJsonLoader,
future: geoJsonParser,
builder: (context, geoJsonParser) =>
geoJsonParser.connectionState != ConnectionState.done ||
geoJsonParser.data == null
? const SizedBox.shrink()
: PolygonLayer(
simplificationTolerance: simplificationTolerance,
polygons: geoJsonParser.data!.polygons,
performantRendering: usePerformantRendering,
simplificationTolerance: simplificationTolerance,
),
),
],
Expand All @@ -83,10 +84,146 @@ class _PolygonPerfStressPageState extends State<PolygonPerfStressPage> {
left: 16,
top: 16,
right: 16,
child: SimplificationToleranceSlider(
initialTolerance: _initialSimplificationTolerance,
onChangedTolerance: (v) =>
setState(() => simplificationTolerance = v),
child: RepaintBoundary(
child: Column(
children: [
SimplificationToleranceSlider(
initialTolerance: _initialSimplificationTolerance,
onChangedTolerance: (v) =>
setState(() => simplificationTolerance = v),
),
JaffaKetchup marked this conversation as resolved.
Show resolved Hide resolved
const SizedBox(height: 12),
Wrap(
alignment: WrapAlignment.center,
spacing: 12,
runSpacing: 12,
children: [
UnconstrainedBox(
child: DecoratedBox(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
borderRadius: BorderRadius.circular(32),
),
child: Padding(
padding: const EdgeInsets.only(
left: 16,
right: 16,
top: 4,
bottom: 4,
JaffaKetchup marked this conversation as resolved.
Show resolved Hide resolved
),
child: Row(
children: [
const Tooltip(
message: 'Use Performant Rendering',
child: Icon(Icons.speed_rounded),
),
const SizedBox(width: 8),
Switch.adaptive(
value: usePerformantRendering,
onChanged: (v) => setState(
() => usePerformantRendering = v,
),
),
],
),
),
),
),
// Not ideal that we have to re-parse the GeoJson every
// time this is changed, but the library gives no easy
// way to change it after
JaffaKetchup marked this conversation as resolved.
Show resolved Hide resolved
UnconstrainedBox(
child: DecoratedBox(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
borderRadius: BorderRadius.circular(32),
),
child: Padding(
padding: const EdgeInsets.only(
left: 16,
right: 16,
top: 8,
bottom: 8,
),
JaffaKetchup marked this conversation as resolved.
Show resolved Hide resolved
child: Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 6,
children: [
const Tooltip(
message: 'Border Thickness',
child: Icon(Icons.line_weight_rounded),
),
if (MediaQuery.devicePixelRatioOf(context) >
1 &&
borderThickness == 1)
const Tooltip(
message:
'Screen has a high DPR: 1px border may be more than 1px.',
child: Icon(
Icons.warning,
color: Colors.amber,
),
),
const SizedBox.shrink(),
JaffaKetchup marked this conversation as resolved.
Show resolved Hide resolved
...List.generate(
4,
(i) {
final thickness = pow(i, 2);
return ChoiceChip(
label: Text(
thickness == 0
? 'None'
: '${thickness}px',
),
selected: borderThickness == thickness,
shape: const StadiumBorder(),
onSelected: (selected) async {
JaffaKetchup marked this conversation as resolved.
Show resolved Hide resolved
if (!selected) return;
setState(() => borderThickness =
thickness.toDouble());
ScaffoldMessenger.of(context)
.showSnackBar(
const SnackBar(
content: Row(
children: [
SizedBox.square(
dimension: 16,
child:
CircularProgressIndicator(
strokeWidth: 3,
valueColor:
AlwaysStoppedAnimation(
Colors.white,
),
),
),
SizedBox(width: 12),
Text(
'Loading GeoJson polygons...',
),
],
),
),
);
await (geoJsonParser =
loadPolygonsFromGeoJson());
if (!context.mounted) return;
ScaffoldMessenger.of(context)
.clearSnackBars();
setState(() {});
},
);
},
),
],
),
),
),
),
],
),
],
),
),
),
if (!kIsWeb)
Expand All @@ -100,4 +237,19 @@ class _PolygonPerfStressPageState extends State<PolygonPerfStressPage> {
),
);
}

Future<GeoJsonParser> loadPolygonsFromGeoJson() async {
const filePath = 'assets/138k-polygon-points.geojson.noformat';

return rootBundle.loadString(filePath).then(
(geoJson) => compute(
(msg) => GeoJsonParser(
defaultPolygonBorderStroke: msg.borderThickness,
defaultPolygonBorderColor: Colors.black.withOpacity(0.5),
defaultPolygonFillColor: Colors.orange[700]!.withOpacity(0.75),
)..parseGeoJsonAsString(msg.geoJson),
(geoJson: geoJson, borderThickness: borderThickness),
),
);
}
}
2 changes: 1 addition & 1 deletion example/lib/widgets/number_of_items_slider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class _NumberOfItemsSliderState extends State<NumberOfItemsSlider> {
child: const Icon(Icons.numbers),
),
Expanded(
child: Slider(
child: Slider.adaptive(
value: _number.toDouble(),
onChanged: (v) {
if (_number == 0 && v != 0) {
Expand Down
Loading
Loading