Skip to content

Rendering text is much slower using Impeller on iOS with iPhone 7 Plus, where Skia is ~2ms while Impeller is ~20ms #127760

@fzyzcjy

Description

@fzyzcjy

Is there an existing issue for this?

Steps to reproduce

Run the demo app. I see this problem when executing regression tests using my internal continuous benchmark infra.

I am not sure whether this is a bug or expected feature, but anyway I post it here since this rendering scenario (unlike my actual complex screens) looks simple for debugging.

Expected results

When skia:

image

Zoom in

image

Actual results

When impeller:

image

Zoom in

image

Code sample

Code sample
class BenchmarkComplexRenderWidget extends StatefulWidget {
  const BenchmarkComplexRenderWidget({super.key});

  @override
  State<BenchmarkComplexRenderWidget> createState() => _BenchmarkComplexRenderWidgetState();
}

class _BenchmarkComplexRenderWidgetState extends State<BenchmarkComplexRenderWidget> {
  late final DateTime startTime;
  var frameIndex = 0;

  @override
  void initState() {
    super.initState();

    startTime = DateTime.now();

    unawaited(() async {
      while (true) {
        await WidgetsBinding.instance.endOfFrame;
        if (!mounted) break;
        setState(() => frameIndex++);
      }
    }());
  }

  @override
  Widget build(BuildContext context) {
    final duration = DateTime.now().difference(startTime);
    final fps = frameIndex / (duration.inMilliseconds / 1000 + 1e-5);

    // ignore: ban-name
    return Scaffold(
      // ignore: ban-name
      appBar: AppBar(
        title: const Text('ComplexRender'),
      ),
      body: ListView(
        children: [
          const SizedBox(height: 16),
          Row(
            children: [
              Expanded(child: Center(child: Text('FPS=${fps.toStringAsFixed(1)}'))),
              Expanded(child: Center(child: Text('frame=$frameIndex'))),
              Expanded(child: Center(child: Text('time=${duration.inMilliseconds}ms'))),
            ],
          ),
          const SizedBox(height: 16),
          _buildComplexRender(),
        ],
      ),
    );
  }

  Widget _buildComplexRender() {
    final alpha = (frameIndex % 60) / 60;

    return Opacity(
      opacity: alpha,
      child: ShaderMask(
        // ignore: prefer-extracting-callbacks
        shaderCallback: (bounds) => RadialGradient(
          center: Alignment.topLeft,
          radius: 0.5 + alpha * 0.5,
          colors: <Color>[Colors.yellow, Colors.deepOrange.shade900],
          tileMode: TileMode.mirror,
        ).createShader(bounds),
        child: Text(
          'This is complex render text' * 1000,
          style: TextStyle(
            fontSize: 6,
            height: 1,
            color: Theme.of(context).colorScheme.background,
          ),
        ),
      ),
    );
  }
}

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

Assignees

No one assigned

    Labels

    e: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions