From 6f3fb695b310ff738df2afb26abf1549ed170eb0 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Mon, 29 Nov 2021 14:15:28 -0800 Subject: [PATCH 1/5] WIP --- .../src/engine/canvaskit/embedded_views.dart | 16 ++++++--- .../platform_views/content_manager.dart | 24 ++++++++++++-- lib/web_ui/lib/ui.dart | 10 ++++-- .../test/canvaskit/embedded_views_test.dart | 33 +++++++++++++++++++ 4 files changed, 74 insertions(+), 9 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart b/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart index 00ee90a3540c4..be4aac3eeb4ea 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart @@ -91,6 +91,8 @@ class HtmlViewEmbedder { /// The list of view ids that should be composited, in order. List _compositionOrder = []; + int _numVisibleViews = 0; + /// The most recent composition order. List _activeCompositionOrder = []; @@ -126,7 +128,7 @@ class HtmlViewEmbedder { } void prerollCompositeEmbeddedView(int viewId, EmbeddedViewParams params) { - if (!disableOverlays) { + if (!disableOverlays && !platformViewManager.isInvisible(viewId)) { // We must decide in the preroll phase if a platform view will use the // backup overlay, so that draw commands after the platform view will // correctly paint to the backup surface. @@ -169,12 +171,15 @@ class HtmlViewEmbedder { /// If this returns a [CkCanvas], then that canvas should be the new leaf /// node. Otherwise, keep the same leaf node. CkCanvas? compositeEmbeddedView(int viewId) { - final int compositedViewCount = _compositionOrder.length; + final int overlayIndex = _numVisibleViews; _compositionOrder.add(viewId); + if (!platformViewManager.isInvisible(viewId)) { + _numVisibleViews++; + } if (!disableOverlays) { - if (compositedViewCount < _pictureRecordersCreatedDuringPreroll.length) { + if (overlayIndex < _pictureRecordersCreatedDuringPreroll.length) { _pictureRecorders[viewId] = - _pictureRecordersCreatedDuringPreroll[compositedViewCount]; + _pictureRecordersCreatedDuringPreroll[overlayIndex]; } else { _viewsUsingBackupSurface.add(viewId); _pictureRecorders[viewId] = _backupPictureRecorder!; @@ -455,6 +460,7 @@ class HtmlViewEmbedder { _viewsUsingBackupSurface.clear(); if (listEquals(_compositionOrder, _activeCompositionOrder)) { _compositionOrder.clear(); + _numVisibleViews = 0; return; } @@ -542,6 +548,7 @@ class HtmlViewEmbedder { } _compositionOrder.clear(); + _numVisibleViews = 0; disposeViews(unusedViews); @@ -728,6 +735,7 @@ class HtmlViewEmbedder { _viewsToRecomposite.clear(); _activeCompositionOrder.clear(); _compositionOrder.clear(); + _numVisibleViews = 0; } } diff --git a/lib/web_ui/lib/src/engine/platform_views/content_manager.dart b/lib/web_ui/lib/src/engine/platform_views/content_manager.dart index 064bed679ac29..02d8de2f70978 100644 --- a/lib/web_ui/lib/src/engine/platform_views/content_manager.dart +++ b/lib/web_ui/lib/src/engine/platform_views/content_manager.dart @@ -43,6 +43,9 @@ class PlatformViewManager { // The references to content tags, indexed by their framework-given ID. final Map _contents = {}; + final Set _invisibleViews = {}; + final Map _viewIdToType = {}; + /// Returns `true` if the passed in `viewType` has been registered before. /// /// See [registerViewFactory] to understand how factories are registered. @@ -64,7 +67,8 @@ class PlatformViewManager { /// it's been set. /// /// `factoryFunction` needs to be a [PlatformViewFactory]. - bool registerFactory(String viewType, Function factoryFunction) { + bool registerFactory(String viewType, Function factoryFunction, + {bool isVisible = true}) { assert(factoryFunction is PlatformViewFactory || factoryFunction is ParameterizedPlatformViewFactory); @@ -72,6 +76,9 @@ class PlatformViewManager { return false; } _factories[viewType] = factoryFunction; + if (!isVisible) { + _invisibleViews.add(viewType); + } return true; } @@ -105,11 +112,12 @@ class PlatformViewManager { 'Attempted to render contents of unregistered viewType: $viewType'); final String slotName = getPlatformViewSlotName(viewId); + _viewIdToType[viewId] = viewType; return _contents.putIfAbsent(viewId, () { final html.Element wrapper = html.document .createElement('flt-platform-view') - ..setAttribute('slot', slotName); + ..setAttribute('slot', slotName); final Function factoryFunction = _factories[viewType]!; late html.Element content; @@ -186,6 +194,16 @@ class PlatformViewManager { } } + /// Returns `true` if the given [viewId] is for an invisible platform view. + bool isInvisible(int viewId) { + final String? viewType = _viewIdToType[viewId]; + if (viewType != null) { + return _invisibleViews.contains(viewType); + } else { + return false; + } + } + /// Clears the state. Used in tests. /// /// Returns the set of know view ids, so they can be cleaned up. @@ -194,6 +212,8 @@ class PlatformViewManager { result.forEach(clearPlatformView); _factories.clear(); _contents.clear(); + _invisibleViews.clear(); + _viewIdToType.clear(); return result; } } diff --git a/lib/web_ui/lib/ui.dart b/lib/web_ui/lib/ui.dart index 7b59a3d2d68dc..b4eef816f6dd0 100644 --- a/lib/web_ui/lib/ui.dart +++ b/lib/web_ui/lib/ui.dart @@ -49,7 +49,9 @@ void webOnlyInitializeEngine() { engine.initializeEngine(); } -void webOnlySetPluginHandler(Future Function(String, ByteData?, PlatformMessageResponseCallback?) handler) { +void webOnlySetPluginHandler( + Future Function(String, ByteData?, PlatformMessageResponseCallback?) + handler) { engine.pluginMessageCallHandler = handler; } @@ -64,9 +66,11 @@ typedef PlatformViewFactory = html.Element Function(int viewId); /// A registry for factories that create platform views. class PlatformViewRegistry { /// Register [viewTypeId] as being creating by the given [factory]. - bool registerViewFactory(String viewTypeId, PlatformViewFactory viewFactory) { + bool registerViewFactory(String viewTypeId, PlatformViewFactory viewFactory, + {bool isVisible = true}) { // TODO(web): Deprecate this once there's another way of calling `registerFactory` (js interop?) - return engine.platformViewManager.registerFactory(viewTypeId, viewFactory); + return engine.platformViewManager + .registerFactory(viewTypeId, viewFactory, isVisible: isVisible); } } diff --git a/lib/web_ui/test/canvaskit/embedded_views_test.dart b/lib/web_ui/test/canvaskit/embedded_views_test.dart index b3f03f5a483dd..4e044dc7b1475 100644 --- a/lib/web_ui/test/canvaskit/embedded_views_test.dart +++ b/lib/web_ui/test/canvaskit/embedded_views_test.dart @@ -641,6 +641,39 @@ void testMain() { HtmlViewEmbedder.debugDisableOverlays = false; }); + + test('does not create overlays for invisible platform views', () async { + ui.platformViewRegistry.registerViewFactory( + 'test-visible-view', + (int viewId) => + html.DivElement()..className = 'visible-platform-view'); + ui.platformViewRegistry.registerViewFactory( + 'test-invisible-view', + (int viewId) => + html.DivElement()..className = 'invisible-platform-view', + isVisible: false, + ); + await createPlatformView(0, 'test-visible-view'); + await createPlatformView(1, 'test-invisible-view'); + + final EnginePlatformDispatcher dispatcher = + ui.window.platformDispatcher as EnginePlatformDispatcher; + + int countCanvases() { + return domRenderer.sceneElement!.querySelectorAll('canvas').length; + } + + expect(platformViewManager.isInvisible(0), isFalse); + expect(platformViewManager.isInvisible(1), isTrue); + + LayerSceneBuilder sb = LayerSceneBuilder(); + sb.pushOffset(0, 0); + sb.addPlatformView(1, width: 10, height: 10); + sb.pop(); + dispatcher.rasterizer!.draw(sb.build().layerTree); + + expect(countCanvases(), 1); + }); // TODO(dit): https://github.com/flutter/flutter/issues/60040 }, skip: isIosSafari); } From adb745ab2b730465b299a04be97d01d70e0e160e Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Tue, 30 Nov 2021 13:17:49 -0800 Subject: [PATCH 2/5] WIP on non painting platform views --- .../src/engine/canvaskit/embedded_views.dart | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart b/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart index 18b8960d9a77f..d00ca6bcbac4b 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart @@ -177,7 +177,9 @@ class HtmlViewEmbedder { if (!platformViewManager.isInvisible(viewId)) { _numVisibleViews++; } - if (!disableOverlays) { + final bool needOverlay = + !disableOverlays && !platformViewManager.isInvisible(viewId); + if (needOverlay) { if (overlayIndex < _pictureRecordersCreatedDuringPreroll.length) { _pictureRecorders[viewId] = _pictureRecordersCreatedDuringPreroll[overlayIndex]; @@ -189,7 +191,7 @@ class HtmlViewEmbedder { // Do nothing if this view doesn't need to be composited. if (!_viewsToRecomposite.contains(viewId)) { - if (!disableOverlays) { + if (needOverlay) { return _pictureRecorders[viewId]!.recordingCanvas; } else { return null; @@ -197,7 +199,7 @@ class HtmlViewEmbedder { } _compositeWithParams(viewId, _currentCompositionParams[viewId]!); _viewsToRecomposite.remove(viewId); - if (!disableOverlays) { + if (needOverlay) { return _pictureRecorders[viewId]!.recordingCanvas; } else { return null; @@ -341,9 +343,7 @@ class HtmlViewEmbedder { final svg.ClipPathElement newClipPath = svg.ClipPathElement(); newClipPath.id = clipId; newClipPath.append( - svg.PathElement() - ..setAttribute('d', path.toSvgString()!) - ); + svg.PathElement()..setAttribute('d', path.toSvgString()!)); pathDefs.append(newClipPath); // Store the id of the node instead of [newClipPath] directly. For @@ -361,9 +361,7 @@ class HtmlViewEmbedder { final svg.ClipPathElement newClipPath = svg.ClipPathElement(); newClipPath.id = clipId; newClipPath.append( - svg.PathElement() - ..setAttribute('d', path.toSvgString()!) - ); + svg.PathElement()..setAttribute('d', path.toSvgString()!)); pathDefs.append(newClipPath); // Store the id of the node instead of [newClipPath] directly. For // some reason, calling `newClipPath.remove()` doesn't remove it @@ -426,13 +424,22 @@ class HtmlViewEmbedder { _compositionOrder.isEmpty || disableOverlays) ? null - : diffViewList(_activeCompositionOrder, _compositionOrder); + : diffViewList( + _activeCompositionOrder + .where((int viewId) => !platformViewManager.isInvisible(viewId)) + .toList(), + _compositionOrder + .where((int viewId) => !platformViewManager.isInvisible(viewId)) + .toList()); final Map? insertBeforeMap = _updateOverlays(diffResult); bool _didPaintBackupSurface = false; if (!disableOverlays) { for (int i = 0; i < _compositionOrder.length; i++) { final int viewId = _compositionOrder[i]; + if (platformViewManager.isInvisible(viewId)) { + continue; + } if (_viewsUsingBackupSurface.contains(viewId)) { // Only draw the picture to the backup surface once. if (!_didPaintBackupSurface) { @@ -608,12 +615,15 @@ class HtmlViewEmbedder { // to the backup surface. SurfaceFactory.instance.releaseSurfaces(); _overlays.clear(); + final List viewsNeedingOverlays = _compositionOrder + .where((int viewId) => !platformViewManager.isInvisible(viewId)) + .toList(); final int numOverlays = math.min( SurfaceFactory.instance.maximumOverlays, - _compositionOrder.length, + viewsNeedingOverlays.length, ); for (int i = 0; i < numOverlays; i++) { - final int viewId = _compositionOrder[i]; + final int viewId = viewsNeedingOverlays[i]; assert(!_viewsUsingBackupSurface.contains(viewId)); _initializeOverlay(viewId); } @@ -669,7 +679,8 @@ class HtmlViewEmbedder { while (overlaysToAssign > 0 && index < _compositionOrder.length) { final bool activeView = index < lastOriginalIndex; final int viewId = _compositionOrder[index]; - if (!_overlays.containsKey(viewId)) { + if (!_overlays.containsKey(viewId) && + !platformViewManager.isInvisible(viewId)) { _initializeOverlay(viewId); overlaysToAssign--; if (activeView) { @@ -693,6 +704,7 @@ class HtmlViewEmbedder { for (int i = 0; i < _compositionOrder.length; i++) { final int viewId = _compositionOrder[i]; assert(_viewsUsingBackupSurface.contains(viewId) || + platformViewManager.isInvisible(viewId) || _overlays[viewId] != null); } } @@ -953,8 +965,9 @@ class ViewListDiffResult { // similar to `Surface._insertChildDomNodes` to efficiently handle more cases, // https://github.com/flutter/flutter/issues/89611. ViewListDiffResult? diffViewList(List active, List next) { - assert(active.isNotEmpty && next.isNotEmpty, - 'diffViewList called with empty view list'); + if (active.isEmpty || next.isEmpty) { + return null; + } // If the [active] and [next] lists are in the expected form described above, // then either the first or last element of [next] will be in [active]. int index = active.indexOf(next.first); From d779a81d745085c6de0b6bbc86ab84e9ff158e94 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Tue, 30 Nov 2021 13:30:58 -0800 Subject: [PATCH 3/5] Fix analysis warning --- lib/web_ui/test/canvaskit/embedded_views_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web_ui/test/canvaskit/embedded_views_test.dart b/lib/web_ui/test/canvaskit/embedded_views_test.dart index 4e044dc7b1475..61535ac4768ec 100644 --- a/lib/web_ui/test/canvaskit/embedded_views_test.dart +++ b/lib/web_ui/test/canvaskit/embedded_views_test.dart @@ -666,7 +666,7 @@ void testMain() { expect(platformViewManager.isInvisible(0), isFalse); expect(platformViewManager.isInvisible(1), isTrue); - LayerSceneBuilder sb = LayerSceneBuilder(); + final LayerSceneBuilder sb = LayerSceneBuilder(); sb.pushOffset(0, 0); sb.addPlatformView(1, width: 10, height: 10); sb.pop(); From 4dd5c33c67d7acde0316306310b174824f762fca Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Tue, 30 Nov 2021 15:41:15 -0800 Subject: [PATCH 4/5] Use isVisible --- .../src/engine/canvaskit/embedded_views.dart | 14 ++-- .../platform_views/content_manager.dart | 4 + .../test/canvaskit/embedded_views_test.dart | 80 ++++++++++++++++++- 3 files changed, 90 insertions(+), 8 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart b/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart index d00ca6bcbac4b..028ab571a38bf 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart @@ -129,7 +129,7 @@ class HtmlViewEmbedder { } void prerollCompositeEmbeddedView(int viewId, EmbeddedViewParams params) { - if (!disableOverlays && !platformViewManager.isInvisible(viewId)) { + if (!disableOverlays && platformViewManager.isVisible(viewId)) { // We must decide in the preroll phase if a platform view will use the // backup overlay, so that draw commands after the platform view will // correctly paint to the backup surface. @@ -174,11 +174,11 @@ class HtmlViewEmbedder { CkCanvas? compositeEmbeddedView(int viewId) { final int overlayIndex = _numVisibleViews; _compositionOrder.add(viewId); - if (!platformViewManager.isInvisible(viewId)) { + if (platformViewManager.isVisible(viewId)) { _numVisibleViews++; } final bool needOverlay = - !disableOverlays && !platformViewManager.isInvisible(viewId); + !disableOverlays && platformViewManager.isVisible(viewId); if (needOverlay) { if (overlayIndex < _pictureRecordersCreatedDuringPreroll.length) { _pictureRecorders[viewId] = @@ -426,10 +426,10 @@ class HtmlViewEmbedder { ? null : diffViewList( _activeCompositionOrder - .where((int viewId) => !platformViewManager.isInvisible(viewId)) + .where((int viewId) => platformViewManager.isVisible(viewId)) .toList(), _compositionOrder - .where((int viewId) => !platformViewManager.isInvisible(viewId)) + .where((int viewId) => platformViewManager.isVisible(viewId)) .toList()); final Map? insertBeforeMap = _updateOverlays(diffResult); @@ -616,7 +616,7 @@ class HtmlViewEmbedder { SurfaceFactory.instance.releaseSurfaces(); _overlays.clear(); final List viewsNeedingOverlays = _compositionOrder - .where((int viewId) => !platformViewManager.isInvisible(viewId)) + .where((int viewId) => platformViewManager.isVisible(viewId)) .toList(); final int numOverlays = math.min( SurfaceFactory.instance.maximumOverlays, @@ -680,7 +680,7 @@ class HtmlViewEmbedder { final bool activeView = index < lastOriginalIndex; final int viewId = _compositionOrder[index]; if (!_overlays.containsKey(viewId) && - !platformViewManager.isInvisible(viewId)) { + platformViewManager.isVisible(viewId)) { _initializeOverlay(viewId); overlaysToAssign--; if (activeView) { diff --git a/lib/web_ui/lib/src/engine/platform_views/content_manager.dart b/lib/web_ui/lib/src/engine/platform_views/content_manager.dart index 02d8de2f70978..d33845f3bf7a4 100644 --- a/lib/web_ui/lib/src/engine/platform_views/content_manager.dart +++ b/lib/web_ui/lib/src/engine/platform_views/content_manager.dart @@ -204,6 +204,10 @@ class PlatformViewManager { } } + /// Returns `true` if the given [viewId] is a platform view with a visible + /// component. + bool isVisible(int viewId) => !isInvisible(viewId); + /// Clears the state. Used in tests. /// /// Returns the set of know view ids, so they can be cleaned up. diff --git a/lib/web_ui/test/canvaskit/embedded_views_test.dart b/lib/web_ui/test/canvaskit/embedded_views_test.dart index 61535ac4768ec..20e043889d601 100644 --- a/lib/web_ui/test/canvaskit/embedded_views_test.dart +++ b/lib/web_ui/test/canvaskit/embedded_views_test.dart @@ -655,6 +655,11 @@ void testMain() { ); await createPlatformView(0, 'test-visible-view'); await createPlatformView(1, 'test-invisible-view'); + await createPlatformView(2, 'test-visible-view'); + await createPlatformView(3, 'test-invisible-view'); + await createPlatformView(4, 'test-invisible-view'); + await createPlatformView(5, 'test-invisible-view'); + await createPlatformView(6, 'test-invisible-view'); final EnginePlatformDispatcher dispatcher = ui.window.platformDispatcher as EnginePlatformDispatcher; @@ -666,12 +671,85 @@ void testMain() { expect(platformViewManager.isInvisible(0), isFalse); expect(platformViewManager.isInvisible(1), isTrue); - final LayerSceneBuilder sb = LayerSceneBuilder(); + LayerSceneBuilder sb = LayerSceneBuilder(); + sb.pushOffset(0, 0); + sb.addPlatformView(1, width: 10, height: 10); + sb.pop(); + dispatcher.rasterizer!.draw(sb.build().layerTree); + expect(countCanvases(), 1); + + sb = LayerSceneBuilder(); + sb.pushOffset(0, 0); + sb.addPlatformView(0, width: 10, height: 10); + sb.addPlatformView(1, width: 10, height: 10); + sb.pop(); + dispatcher.rasterizer!.draw(sb.build().layerTree); + expect(countCanvases(), 2); + + sb = LayerSceneBuilder(); + sb.pushOffset(0, 0); + sb.addPlatformView(0, width: 10, height: 10); + sb.addPlatformView(1, width: 10, height: 10); + sb.addPlatformView(2, width: 10, height: 10); + sb.pop(); + dispatcher.rasterizer!.draw(sb.build().layerTree); + expect(countCanvases(), 3); + + sb = LayerSceneBuilder(); + sb.pushOffset(0, 0); + sb.addPlatformView(0, width: 10, height: 10); + sb.addPlatformView(1, width: 10, height: 10); + sb.addPlatformView(2, width: 10, height: 10); + sb.addPlatformView(3, width: 10, height: 10); + sb.pop(); + dispatcher.rasterizer!.draw(sb.build().layerTree); + expect(countCanvases(), 3); + + sb = LayerSceneBuilder(); sb.pushOffset(0, 0); + sb.addPlatformView(0, width: 10, height: 10); + sb.addPlatformView(1, width: 10, height: 10); + sb.addPlatformView(2, width: 10, height: 10); + sb.addPlatformView(3, width: 10, height: 10); + sb.addPlatformView(4, width: 10, height: 10); + sb.pop(); + dispatcher.rasterizer!.draw(sb.build().layerTree); + expect(countCanvases(), 3); + + sb = LayerSceneBuilder(); + sb.pushOffset(0, 0); + sb.addPlatformView(0, width: 10, height: 10); sb.addPlatformView(1, width: 10, height: 10); + sb.addPlatformView(2, width: 10, height: 10); + sb.addPlatformView(3, width: 10, height: 10); + sb.addPlatformView(4, width: 10, height: 10); + sb.addPlatformView(5, width: 10, height: 10); sb.pop(); dispatcher.rasterizer!.draw(sb.build().layerTree); + expect(countCanvases(), 3); + sb = LayerSceneBuilder(); + sb.pushOffset(0, 0); + sb.addPlatformView(0, width: 10, height: 10); + sb.addPlatformView(1, width: 10, height: 10); + sb.addPlatformView(2, width: 10, height: 10); + sb.addPlatformView(3, width: 10, height: 10); + sb.addPlatformView(4, width: 10, height: 10); + sb.addPlatformView(5, width: 10, height: 10); + sb.addPlatformView(6, width: 10, height: 10); + sb.pop(); + dispatcher.rasterizer!.draw(sb.build().layerTree); + expect(countCanvases(), 3); + + sb = LayerSceneBuilder(); + sb.pushOffset(0, 0); + sb.addPlatformView(1, width: 10, height: 10); + sb.addPlatformView(3, width: 10, height: 10); + sb.addPlatformView(4, width: 10, height: 10); + sb.addPlatformView(5, width: 10, height: 10); + sb.addPlatformView(6, width: 10, height: 10); + sb.pop(); + dispatcher.rasterizer!.draw(sb.build().layerTree); expect(countCanvases(), 1); }); // TODO(dit): https://github.com/flutter/flutter/issues/60040 From 628450aebcea0547d739a87af8be1bc04b525bc0 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Tue, 30 Nov 2021 16:59:28 -0800 Subject: [PATCH 5/5] Review comments + undo formatting --- .../src/engine/canvaskit/embedded_views.dart | 21 ++++++++++++------- .../platform_views/content_manager.dart | 8 ++----- lib/web_ui/lib/ui.dart | 4 +--- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart b/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart index 028ab571a38bf..adda18f9477c2 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart @@ -92,7 +92,10 @@ class HtmlViewEmbedder { /// The list of view ids that should be composited, in order. List _compositionOrder = []; - int _numVisibleViews = 0; + /// The number of platform views in this frame which are visible. + /// + /// These platform views will require overlays. + int _visibleViewCount = 0; /// The most recent composition order. List _activeCompositionOrder = []; @@ -172,10 +175,10 @@ class HtmlViewEmbedder { /// If this returns a [CkCanvas], then that canvas should be the new leaf /// node. Otherwise, keep the same leaf node. CkCanvas? compositeEmbeddedView(int viewId) { - final int overlayIndex = _numVisibleViews; + final int overlayIndex = _visibleViewCount; _compositionOrder.add(viewId); if (platformViewManager.isVisible(viewId)) { - _numVisibleViews++; + _visibleViewCount++; } final bool needOverlay = !disableOverlays && platformViewManager.isVisible(viewId); @@ -343,7 +346,8 @@ class HtmlViewEmbedder { final svg.ClipPathElement newClipPath = svg.ClipPathElement(); newClipPath.id = clipId; newClipPath.append( - svg.PathElement()..setAttribute('d', path.toSvgString()!)); + svg.PathElement() + ..setAttribute('d', path.toSvgString()!)); pathDefs.append(newClipPath); // Store the id of the node instead of [newClipPath] directly. For @@ -361,7 +365,8 @@ class HtmlViewEmbedder { final svg.ClipPathElement newClipPath = svg.ClipPathElement(); newClipPath.id = clipId; newClipPath.append( - svg.PathElement()..setAttribute('d', path.toSvgString()!)); + svg.PathElement() + ..setAttribute('d', path.toSvgString()!)); pathDefs.append(newClipPath); // Store the id of the node instead of [newClipPath] directly. For // some reason, calling `newClipPath.remove()` doesn't remove it @@ -467,7 +472,7 @@ class HtmlViewEmbedder { _viewsUsingBackupSurface.clear(); if (listEquals(_compositionOrder, _activeCompositionOrder)) { _compositionOrder.clear(); - _numVisibleViews = 0; + _visibleViewCount = 0; return; } @@ -555,7 +560,7 @@ class HtmlViewEmbedder { } _compositionOrder.clear(); - _numVisibleViews = 0; + _visibleViewCount = 0; disposeViews(unusedViews); @@ -747,7 +752,7 @@ class HtmlViewEmbedder { _viewsToRecomposite.clear(); _activeCompositionOrder.clear(); _compositionOrder.clear(); - _numVisibleViews = 0; + _visibleViewCount = 0; } } diff --git a/lib/web_ui/lib/src/engine/platform_views/content_manager.dart b/lib/web_ui/lib/src/engine/platform_views/content_manager.dart index d33845f3bf7a4..cda4b03486ed5 100644 --- a/lib/web_ui/lib/src/engine/platform_views/content_manager.dart +++ b/lib/web_ui/lib/src/engine/platform_views/content_manager.dart @@ -117,7 +117,7 @@ class PlatformViewManager { return _contents.putIfAbsent(viewId, () { final html.Element wrapper = html.document .createElement('flt-platform-view') - ..setAttribute('slot', slotName); + ..setAttribute('slot', slotName); final Function factoryFunction = _factories[viewType]!; late html.Element content; @@ -197,11 +197,7 @@ class PlatformViewManager { /// Returns `true` if the given [viewId] is for an invisible platform view. bool isInvisible(int viewId) { final String? viewType = _viewIdToType[viewId]; - if (viewType != null) { - return _invisibleViews.contains(viewType); - } else { - return false; - } + return viewType != null && _invisibleViews.contains(viewType); } /// Returns `true` if the given [viewId] is a platform view with a visible diff --git a/lib/web_ui/lib/ui.dart b/lib/web_ui/lib/ui.dart index b4eef816f6dd0..3dcfc8ce273d1 100644 --- a/lib/web_ui/lib/ui.dart +++ b/lib/web_ui/lib/ui.dart @@ -49,9 +49,7 @@ void webOnlyInitializeEngine() { engine.initializeEngine(); } -void webOnlySetPluginHandler( - Future Function(String, ByteData?, PlatformMessageResponseCallback?) - handler) { +void webOnlySetPluginHandler(Future Function(String, ByteData?, PlatformMessageResponseCallback?) handler) { engine.pluginMessageCallHandler = handler; }