Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b1f1ec2

Browse files
author
Harry Terkelsen
authored
If there are more views than overlays, put the extra views on top (#37014)
1 parent 6e5bde2 commit b1f1ec2

File tree

2 files changed

+33
-20
lines changed

2 files changed

+33
-20
lines changed

lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,8 @@ class HtmlViewEmbedder {
486486
skiaSceneHost.insertBefore(platformViewRoot, elementToInsertBefore);
487487
final Surface? overlay = _overlays[viewId];
488488
if (overlay != null) {
489-
skiaSceneHost
490-
.insertBefore(overlay.htmlElement, elementToInsertBefore);
489+
skiaSceneHost.insertBefore(
490+
overlay.htmlElement, elementToInsertBefore);
491491
}
492492
} else {
493493
final DomElement platformViewRoot = _viewClipChains[viewId]!.root;
@@ -601,8 +601,15 @@ class HtmlViewEmbedder {
601601
return;
602602
}
603603
final List<List<int>> overlayGroups = getOverlayGroups(_compositionOrder);
604-
final Iterable<int> viewsNeedingOverlays =
605-
overlayGroups.map((List<int> group) => group.last);
604+
final List<int> viewsNeedingOverlays =
605+
overlayGroups.map((List<int> group) => group.last).toList();
606+
// If there were more visible views than overlays, then the last group
607+
// doesn't have an overlay.
608+
if (viewsNeedingOverlays.length > SurfaceFactory.instance.maximumOverlays) {
609+
assert(viewsNeedingOverlays.length ==
610+
SurfaceFactory.instance.maximumOverlays + 1);
611+
viewsNeedingOverlays.removeLast();
612+
}
606613
if (diffResult == null) {
607614
// Everything is going to be explicitly recomposited anyway. Release all
608615
// the surfaces and assign an overlay to all the surfaces needing one.
@@ -631,33 +638,39 @@ class HtmlViewEmbedder {
631638
// of the composition order which can share the same overlay. Every overlay
632639
// group is a list containing a visible view followed by zero or more
633640
// invisible views.
641+
//
642+
// If there are more visible views than overlays, then the views which cannot
643+
// be assigned an overlay are grouped together and will be rendered on top of
644+
// the rest of the scene.
634645
List<List<int>> getOverlayGroups(List<int> views) {
635646
// Visibility groups are typically a visible view followed by zero or more
636647
// invisible views. However, if the view list begins with one or more
637648
// invisible views, we can group them with the first visible view.
638-
final int maxGroups = SurfaceFactory.instance.maximumOverlays;
639-
if (maxGroups == 0) {
649+
final int maxOverlays = SurfaceFactory.instance.maximumOverlays;
650+
if (maxOverlays == 0) {
640651
return const <List<int>>[];
641652
}
642653
bool foundFirstVisibleView = false;
643654
final List<List<int>> result = <List<int>>[];
644655
List<int> currentGroup = <int>[];
645656
int i = 0;
646657
for (; i < views.length; i++) {
647-
// If we're on the last group, then break and just add all the rest of the
648-
// views to current group.
649-
if (result.length == maxGroups - 1) {
650-
break;
651-
}
652658
final int view = views[i];
653659
if (platformViewManager.isInvisible(view)) {
654660
currentGroup.add(view);
655661
} else {
656662
if (foundFirstVisibleView) {
657-
// We hit this case if this is the first visible view.
658663
result.add(currentGroup);
659-
currentGroup = <int>[view];
664+
// If we are out of overlays, then break let the rest of the views be
665+
// added to an extra group that will be rendered on top of the scene.
666+
if (result.length == maxOverlays) {
667+
currentGroup = <int>[];
668+
break;
669+
} else {
670+
currentGroup = <int>[view];
671+
}
660672
} else {
673+
// We hit this case if this is the first visible view.
661674
foundFirstVisibleView = true;
662675
currentGroup.add(view);
663676
}

lib/web_ui/test/canvaskit/embedded_views_test.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,8 @@ void testMain() {
337337
_platformView,
338338
_overlay,
339339
_platformView,
340-
_platformView,
341340
_overlay,
341+
_platformView,
342342
]);
343343

344344
// Frame 2:
@@ -389,6 +389,7 @@ void testMain() {
389389
_platformView,
390390
_overlay,
391391
_platformView,
392+
_overlay,
392393
_platformView,
393394
_platformView,
394395
_platformView,
@@ -398,7 +399,6 @@ void testMain() {
398399
_platformView,
399400
_platformView,
400401
_platformView,
401-
_overlay,
402402
]);
403403

404404
// Frame 5:
@@ -491,10 +491,10 @@ void testMain() {
491491
_platformView,
492492
_overlay,
493493
_platformView,
494+
_overlay,
494495
_platformView,
495496
_platformView,
496497
_platformView,
497-
_overlay,
498498
]);
499499

500500
// Frame 2:
@@ -518,10 +518,10 @@ void testMain() {
518518
_platformView,
519519
_overlay,
520520
_platformView,
521+
_overlay,
521522
_platformView,
522523
_platformView,
523524
_platformView,
524-
_overlay,
525525
]);
526526

527527
// Frame 3:
@@ -544,10 +544,10 @@ void testMain() {
544544
_platformView,
545545
_overlay,
546546
_platformView,
547+
_overlay,
547548
_platformView,
548549
_platformView,
549550
_platformView,
550-
_overlay,
551551
]);
552552

553553
// Frame 4:
@@ -570,10 +570,10 @@ void testMain() {
570570
_platformView,
571571
_overlay,
572572
_platformView,
573+
_overlay,
573574
_platformView,
574575
_platformView,
575576
_platformView,
576-
_overlay,
577577
]);
578578

579579
// TODO(yjbanov): skipped due to https://github.com/flutter/flutter/issues/73867
@@ -842,8 +842,8 @@ void testMain() {
842842
_expectSceneMatches(<_EmbeddedViewMarker>[
843843
_overlay,
844844
_platformView,
845-
_platformView,
846845
_overlay,
846+
_platformView,
847847
]);
848848

849849
// Reset configuration

0 commit comments

Comments
 (0)