Visitar URL original
dont force extra compositing (#70) · flutter/packages@a9396c7 · GitHub
Skip to content

Commit a9396c7

Browse files
author
Jonah Williams
authored
dont force extra compositing (#70)
1 parent 6e9dce1 commit a9396c7

4 files changed

Lines changed: 40 additions & 42 deletions

File tree

‎packages/vector_graphics/example/lib/main.dart‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ class MyApp extends StatelessWidget {
2929
body: Center(
3030
child: ListView(
3131
children: const <Widget>[
32-
VectorGraphic(
33-
loader: AssetBytesLoader('assets/tiger.bin'),
34-
),
3532
VectorGraphic(
3633
loader: NetworkSvgLoader(
3734
'https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg',

‎packages/vector_graphics/lib/src/listener.dart‎

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,17 @@ import 'dart:ui' as ui;
66
import 'dart:typed_data';
77

88
import 'package:flutter/cupertino.dart';
9-
import 'package:flutter/rendering.dart';
109
import 'package:vector_graphics_codec/vector_graphics_codec.dart';
1110

1211
const VectorGraphicsCodec _codec = VectorGraphicsCodec();
1312

1413
/// The deocded result of a vector graphics asset.
1514
class PictureInfo {
1615
/// Construct a new [PictureInfo].
17-
PictureInfo._(this._handle, this.size);
16+
PictureInfo._(this.picture, this.size);
1817

19-
/// A [LayerHandle] that contains a picture layer with the decoded
20-
/// vector graphic.
21-
final LayerHandle<PictureLayer> _handle;
22-
23-
/// Retrieve the picture layer associated with this [PictureInfo].
24-
///
25-
/// Will be null if info has already been disposed.
26-
PictureLayer? get layer {
27-
return _handle.layer;
28-
}
29-
30-
//// Dispose this picture info.
31-
///
32-
/// It is safe to call this method multiple times.
33-
void dispose() {
34-
_handle.layer = null;
35-
}
18+
/// A picture generated from a vector graphics image.
19+
final ui.Picture picture;
3620

3721
/// The target size of the picture.
3822
///
@@ -131,10 +115,7 @@ class FlutterVectorGraphicsListener extends VectorGraphicsCodecListener {
131115
PictureInfo toPicture() {
132116
assert(!_done);
133117
_done = true;
134-
final LayerHandle<PictureLayer> handle = LayerHandle<PictureLayer>();
135-
handle.layer = PictureLayer(Rect.fromLTWH(0, 0, _size.width, _size.height))
136-
..picture = _recorder.endRecording();
137-
return PictureInfo._(handle, _size);
118+
return PictureInfo._(_recorder.endRecording(), _size);
138119
}
139120

140121
@override

‎packages/vector_graphics/lib/vector_graphics.dart‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class _VectorGraphicsWidgetState extends State<VectorGraphic> {
122122

123123
@override
124124
void dispose() {
125-
_pictureInfo?.dispose();
125+
_pictureInfo?.picture.dispose();
126126
_pictureInfo = null;
127127
super.dispose();
128128
}
@@ -135,7 +135,7 @@ class _VectorGraphicsWidgetState extends State<VectorGraphic> {
135135
textDirection: Directionality.maybeOf(context),
136136
);
137137
setState(() {
138-
_pictureInfo?.dispose();
138+
_pictureInfo?.picture.dispose();
139139
_pictureInfo = pictureInfo;
140140
});
141141
});
@@ -339,17 +339,19 @@ class _RenderVectorGraphics extends RenderBox {
339339
return constraints.smallest;
340340
}
341341

342-
@override
343-
bool get isRepaintBoundary => true;
344-
345342
final Matrix4 transform = Matrix4.identity();
346343

347344
@override
348345
void paint(PaintingContext context, ui.Offset offset) {
349346
if (_scaleCanvasToViewBox(transform, size, pictureInfo.size)) {
350347
context.canvas.transform(transform.storage);
351348
}
352-
context.addLayer(_pictureInfo.layer!);
349+
// Instead of using an explicit non-owned layer here, we just add
350+
// the picture directly. This allows parent render objects to avoid
351+
// extra compositing.
352+
// This is safe to do because the widget itself is wrapped in a repaint
353+
// boundary.
354+
context.canvas.drawPicture(_pictureInfo.picture);
353355
}
354356
}
355357

‎packages/vector_graphics/test/vector_graphics_test.dart‎

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,16 +270,6 @@ void main() {
270270
expect(find.byType(RepaintBoundary), findsOneWidget);
271271
});
272272

273-
testWidgets('PictureInfo.dispose is safe to call multiple times',
274-
(WidgetTester tester) async {
275-
final FlutterVectorGraphicsListener listener =
276-
FlutterVectorGraphicsListener();
277-
final PictureInfo info = listener.toPicture();
278-
279-
info.dispose();
280-
expect(info.dispose, returnsNormally);
281-
});
282-
283273
testWidgets('Can set locale and text direction', (WidgetTester tester) async {
284274
final TestAssetBundle testBundle = TestAssetBundle();
285275
await tester.pumpWidget(
@@ -411,6 +401,34 @@ void main() {
411401

412402
expect(find.byKey(const ValueKey<int>(23)), findsOneWidget);
413403
});
404+
405+
// Show that we avoid compositing extra layers and raster cache the maximum number of paint
406+
// operations.
407+
testWidgets('Only creates a PictureLayer and a repaint boundary',
408+
(WidgetTester tester) async {
409+
final TestAssetBundle testBundle = TestAssetBundle();
410+
411+
await tester.pumpWidget(
412+
DefaultAssetBundle(
413+
bundle: testBundle,
414+
child: Directionality(
415+
textDirection: TextDirection.ltr,
416+
child: VectorGraphic(
417+
loader: const AssetBytesLoader('foo.svg'),
418+
semanticsLabel: 'Foo',
419+
placeholderBuilder: (BuildContext context) {
420+
return Container(key: const ValueKey<int>(23));
421+
},
422+
),
423+
),
424+
),
425+
);
426+
await tester.pumpAndSettle();
427+
428+
expect(tester.layers.last, isA<PictureLayer>()); // vg picture
429+
expect(tester.layers.elementAt(tester.layers.length - 2),
430+
isA<OffsetLayer>()); // Repaint boundary
431+
});
414432
}
415433

416434
class TestAssetBundle extends Fake implements AssetBundle {

0 commit comments

Comments
 (0)