33// found in the LICENSE file.
44
55part of engine;
6-
76final bool _supportsDecode = js_util.getProperty (
87 js_util.getProperty (
98 js_util.getProperty (html.window, 'Image' ), 'prototype' ),
@@ -23,46 +22,54 @@ class HtmlCodec implements ui.Codec {
2322
2423 @override
2524 Future <ui.FrameInfo > getNextFrame () async {
26- StreamSubscription <html.Event > loadSubscription;
27- StreamSubscription <html.Event > errorSubscription;
2825 final Completer <ui.FrameInfo > completer = Completer <ui.FrameInfo >();
29- final html.ImageElement imgElement = html.ImageElement ();
30- // If the browser doesn't support asynchronous decoding of an image,
31- // then use the `onload` event to decide when it's ready to paint to the
32- // DOM. Unfortunately, this will case the image to be decoded synchronously
33- // on the main thread, and may cause dropped framed.
34- if (! _supportsDecode) {
35- loadSubscription = imgElement.onLoad.listen ((html.Event event) {
36- loadSubscription.cancel ();
37- errorSubscription.cancel ();
26+ if (_supportsDecode) {
27+ final html.ImageElement imgElement = html.ImageElement ();
28+ imgElement.src = src;
29+ js_util.setProperty (imgElement, 'decoding' , 'async' );
30+ imgElement.decode ().then ((dynamic _) {
3831 final HtmlImage image = HtmlImage (
3932 imgElement,
4033 imgElement.naturalWidth,
4134 imgElement.naturalHeight,
4235 );
4336 completer.complete (SingleFrameInfo (image));
37+ }).catchError ((e) {
38+ // This code path is hit on Chrome 80.0.3987.16 when too many
39+ // images are on the page (~1000).
40+ // Fallback here is to load using onLoad instead.
41+ _decodeUsingOnLoad (completer);
4442 });
43+ } else {
44+ _decodeUsingOnLoad (completer);
4545 }
46+ return completer.future;
47+ }
48+
49+ void _decodeUsingOnLoad (Completer completer) {
50+ StreamSubscription <html.Event > loadSubscription;
51+ StreamSubscription <html.Event > errorSubscription;
52+ final html.ImageElement imgElement = html.ImageElement ();
53+ // If the browser doesn't support asynchronous decoding of an image,
54+ // then use the `onload` event to decide when it's ready to paint to the
55+ // DOM. Unfortunately, this will cause the image to be decoded synchronously
56+ // on the main thread, and may cause dropped framed.
4657 errorSubscription = imgElement.onError.listen ((html.Event event) {
4758 loadSubscription? .cancel ();
4859 errorSubscription.cancel ();
4960 completer.completeError (event);
5061 });
62+ loadSubscription = imgElement.onLoad.listen ((html.Event event) {
63+ loadSubscription.cancel ();
64+ errorSubscription.cancel ();
65+ final HtmlImage image = HtmlImage (
66+ imgElement,
67+ imgElement.naturalWidth,
68+ imgElement.naturalHeight,
69+ );
70+ completer.complete (SingleFrameInfo (image));
71+ });
5172 imgElement.src = src;
52- // If the browser supports asynchronous image decoding, use that instead
53- // of `onload`.
54- if (_supportsDecode) {
55- imgElement.decode ().then ((dynamic _) {
56- errorSubscription.cancel ();
57- final HtmlImage image = HtmlImage (
58- imgElement,
59- imgElement.naturalWidth,
60- imgElement.naturalHeight,
61- );
62- completer.complete (SingleFrameInfo (image));
63- });
64- }
65- return completer.future;
6673 }
6774
6875 @override
0 commit comments