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

Add a threshold for rasterization to avoid excessive fixed overhead c… #1462

Merged
merged 1 commit into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 17 additions & 4 deletions lib/src/layer/polygon_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,20 @@ class PolygonLayer extends StatelessWidget {
/// screen space culling of polygons based on bounding box
final bool polygonCulling;

/// The layer allows to rasterize and translate the underlying canvas on
/// panning the map (does not apply for rotations and zooming). This can
/// greatly improve performance if the set polygons in the map's viewport
/// doesn't change. However, rasterization comes at a fixed overhead, which
/// amortizes when drawing the canvas itself is costly and the use-case makes
/// this pan-only optimization worthwhile. Setting the threshold to a large
/// value will basically deactivate the optimization entirely.
final int rasterizationThreshold;

const PolygonLayer({
super.key,
this.polygons = const [],
this.polygonCulling = false,
this.rasterizationThreshold = 128,
});

@override
Expand All @@ -84,27 +94,29 @@ class PolygonLayer extends StatelessWidget {
final origin = map.pixelOrigin;
final offset = Offset(origin.x.toDouble(), origin.y.toDouble());

final Iterable<Polygon> pgons = polygonCulling
final List<Polygon> pgons = polygonCulling
TesteurManiak marked this conversation as resolved.
Show resolved Hide resolved
? polygons.where((p) {
return p.boundingBox.isOverlapping(map.bounds);
})
}).toList()
: polygons;

final paint = CustomPaint(
painter: PolygonPainter(pgons, map),
size: size,
isComplex: true,
);

final rasterize = !kIsWeb && pgons.length > rasterizationThreshold;
return Positioned(
left: -offset.dx,
top: -offset.dy,
child: kIsWeb ? paint : RepaintBoundary(child: paint),
child: rasterize ? RepaintBoundary(child: paint) : paint,
);
}
}

class PolygonPainter extends CustomPainter {
final Iterable<Polygon> polygons;
final List<Polygon> polygons;
final FlutterMapState map;
final double zoom;
final double rotation;
Expand Down Expand Up @@ -285,6 +297,7 @@ class PolygonPainter extends CustomPainter {
return kIsWeb ||
oldDelegate.zoom != zoom ||
oldDelegate.rotation != rotation ||
oldDelegate.polygons.length != polygons.length ||
oldDelegate.hash != hash;
}
}
20 changes: 16 additions & 4 deletions lib/src/layer/polyline_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,21 @@ class PolylineLayer extends StatelessWidget {
/// performance of the layer.
final bool saveLayers;

/// The layer allows to rasterize and translate the underlying canvas on
/// panning the map (does not apply for rotations and zooming). This can
/// greatly improve performance if the set polylines in the map's viewport
/// doesn't change. However, rasterization comes at a fixed overhead, which
/// amortizes when drawing the canvas itself is costly and the use-case makes
/// this pan-only optimization worthwhile. Setting the threshold to a large
/// value will basically deactivate the optimization entirely.
final int rasterizationThreshold;

const PolylineLayer({
super.key,
this.polylines = const [],
this.polylineCulling = false,
this.saveLayers = false,
this.rasterizationThreshold = 128,
});

@override
Expand All @@ -83,10 +93,10 @@ class PolylineLayer extends StatelessWidget {
final origin = map.pixelOrigin;
final offset = Offset(origin.x.toDouble(), origin.y.toDouble());

final Iterable<Polyline> lines = polylineCulling
final List<Polyline> lines = polylineCulling
? polylines.where((p) {
return p.boundingBox.isOverlapping(map.bounds);
})
}).toList()
: polylines;

final paint = CustomPaint(
Expand All @@ -95,16 +105,17 @@ class PolylineLayer extends StatelessWidget {
isComplex: true,
);

final rasterize = !kIsWeb && lines.length > rasterizationThreshold;
return Positioned(
left: -offset.dx,
top: -offset.dy,
child: kIsWeb ? paint : RepaintBoundary(child: paint),
child: rasterize ? RepaintBoundary(child: paint) : paint,
);
}
}

class PolylinePainter extends CustomPainter {
final Iterable<Polyline> polylines;
final List<Polyline> polylines;

/// {@template newPolylinePainter.saveLayers}
/// If `true`, the canvas will be updated on every frame by calling the
Expand Down Expand Up @@ -309,6 +320,7 @@ class PolylinePainter extends CustomPainter {
return kIsWeb ||
oldDelegate.zoom != zoom ||
oldDelegate.rotation != rotation ||
oldDelegate.polylines.length != polylines.length ||
oldDelegate.hash != hash;
}
}