Skip to content

Flutter web does not allow configuration of maximum number of overlays since the merge of single context work #144589

@jezell

Description

@jezell

Steps to reproduce

Create more than 8 overlay groups. Later groups will silently fail to render.

Expected results

Allow increasing the number of overlay groups, also don't stop rendering the platform views.

Actual results

You can't increase the number of overlay groups anymore and you can very easily run out of overlay groups.

When the single overlay context commit was merged, we lost the ability to increase the number of overlay layers.

Before this commit:

flutter/engine@6c164f0

We could increase the number of layers using canvasKitMaximumSurfaces. However, this configuration option was removed despite it still being needed for anyone running into the maximum overlay surfaces limit. This configuration option should be brought back so that the limit can be increased manually.

class HtmlViewEmbedder {
//...
static const int maximumOverlays = 7;

Unfortunately, none of the library authors, including the official video plugin have moved to using createImageFromImageBitmap so people still need a way to work around the overlay limits until libraries get around to reducing the number of layers that they waste.

Also, should probably log some kind of warning when it hits the limit.

Code sample

This code will fail to render the overlays properly:

// Copyright 2019 the Dart project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:web/web.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({
    super.key,
    required this.title,
  });

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Container(),
      ),
      body: Stack(children: [
        for (var i = 0; i < 10; i++)
          Positioned(
              top: i * 30,
              width: 100,
              height: 30,
              left: 0,
              child: Container(
                  decoration: const BoxDecoration(color: Colors.white),
                  clipBehavior: Clip.none,
                  child: HtmlElementView.fromTagName(
                      tagName: "div",
                      onElementCreated: (element) {
                        final div = element as HTMLDivElement;
                        div.innerText = "$i";
                        div.style.background = "#eee";
                        div.style.border = "1px solid #000";
                      }))),
      ]),
    );
  }
}

This code will work, note that simply wrapping the elements in a container breaks them:

// Copyright 2019 the Dart project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:web/web.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({
    super.key,
    required this.title,
  });

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Container(),
      ),
      body: Stack(children: [
        for (var i = 0; i < 10; i++)
          Positioned(
              top: i * 30,
              width: 100,
              height: 30,
              left: 0,
              child: HtmlElementView.fromTagName(
                      tagName: "div",
                      onElementCreated: (element) {
                        final div = element as HTMLDivElement;
                        div.innerText = "$i";
                        div.style.background = "#eee";
                        div.style.border = "1px solid #000";
                      })),
      ]),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[Paste your output here]

Metadata

Metadata

Labels

P1High-priority issues at the top of the work liste: web_canvaskitCanvasKit (a.k.a. Skia-on-WebGL) rendering backend for Webengineflutter/engine related. See also e: labels.found in release: 3.19Found to occur in 3.19found in release: 3.20Found to occur in 3.20has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-webWeb applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-webOwned by Web platform teamtriaged-webTriaged by Web platform team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions