8000 iOS Impeller-only crash with BackdropFilter+blank PlatformView · Issue #124612 · flutter/flutter · GitHub
[go: up one dir, main page]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS Impeller-only crash with BackdropFilter+blank PlatformView #124612

Closed
moffatman opened this issue Apr 11, 2023 · 2 comments · Fixed by flutter/engine#41085
Closed

iOS Impeller-only crash with BackdropFilter+blank PlatformView #124612

moffatman opened this issue Apr 11, 2023 · 2 comments · Fixed by flutter/engine#41085
Labels
e: impeller Impeller rendering backend issues and features requests

Comments

@moffatman
Copy link
Contributor
moffatman commented Apr 11, 2023

I found a crash on flutter 3.10.0-3.0.pre.31 which only occurs when rendering using Impeller.
It comes from using the package native_drag_n_drop: ^0.0.5 which creates a "blank" platform view (only thing set is the backgroundColor = UIColor.clear, and it's used to add a drag-and-drop interaction.

https://github.com/alexrabin/FlutterNativeDragAndDrop/blob/main/ios/Classes/SwiftNativeDragNDropPlugin.swift

When putting a BackdropFilter on top, the program crashes instantly with an Metal exception.

Code sample
import 'dart:async';
import 'dart:math';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:native_drag_n_drop/native_drag_n_drop.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  createState() => MyAppState16();
}

class MyAppState16 extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      home: CupertinoPageScaffold(
        child: NativeDropView(
          loading: (isLoading) {

          },
          dataReceived: (data) {

          },
          child: Stack(
            fit: StackFit.expand,
            children: [
              const Center(
                child: Text('asdfasdfasdfasdf')
              ),
              Center(
                child: ClipRect(
                  child: BackdropFilter(
                    filter: ui.ImageFilter.blur(sigmaX: 10, sigmaY: 10),
                    child: Container(
                      width: 100,
                      height: 100,
                      color: Colors.black38,
                    )
                  )
                )
              )
            ]
          )
        )
      )
    );
  }
}

The error is as follows:

-[MTLDebugBlitCommandEncoder internalValidateCopyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:options:]:388: failed assertion `Copy From Texture Validation
destinationTexture must not be a framebufferOnly texture.

I ran with a local engine where I changed IOSSurfaceMetalImpeller::GetCAMetalLayer to always set layer.framebufferOnly = NO, and the crash doesn't happen. But I don't know anything about Impeller - not sure if that is a correct fix, or rather the invalid operation (blit) should not be attempted on such a layer.

Engine backtrace

To explain the bottom stack frames, this is running on M1 mac, not an actual iOS device.

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x0000000183692868 libsystem_kernel.dylib`__pthread_kill + 8
    frame #1: 0x0000000101e66bc4 libsystem_pthread.dylib`pthread_kill + 288
    frame #2: 0x00000001836022c8 libsystem_c.dylib`abort + 180
    frame #3: 0x0000000183601620 libsystem_c.dylib`__assert_rtn + 272
    frame #4: 0x000000018caeaba0 Metal`MTLReportFailure.cold.1 + 48
    frame #5: 0x000000018cac770c Metal`MTLReportFailure + 464
    frame #6: 0x000000018cabdaa4 Metal`_MTLMessageContextEnd + 876
    frame #7: 0x0000000183ec96bc MetalTools`-[MTLDebugBlitCommandEncoder internalValidateCopyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:options:] + 1116
    frame #8: 0x0000000183eca33c MetalTools`-[MTLDebugBlitCommandEncoder validateCopyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:options:move:] + 116
    frame #9: 0x0000000183eca6dc MetalTools`-[MTLDebugBlitCommandEncoder copyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:] + 148
    frame #10: 0x000000010d67bac4 Flutter`impeller::BlitCopyTextureToTextureCommandMTL::Encode(id<MTLBlitCommandEncoder>) const + 176
    frame #11: 0x000000010d67c1f4 Flutter`impeller::BlitPassMTL::EncodeCommands(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<impeller::Allocator> const&) const + 584
    frame #12: 0x000000010d5d12b8 Flutter`impeller::AiksContext::Render(impeller::Picture const&, impeller::RenderTarget&) + 3324
    frame #13: 0x000000010d6a5ac0 Flutter`std::_LIBCPP_ABI_NAMESPACE::__function::__func<fml::internal::CopyableLambda<flutter::GPUSurfaceMetalImpeller::AcquireFrame(SkISize const&)::$_0>, std::_LIBCPP_ABI_NAMESPACE::allocator<fml::internal::CopyableLambda<flutter::GPUSurfaceMetalImpeller::AcquireFrame(SkISize const&)::$_0> >, bool (flutter::SurfaceFrame&, flutter::DlCanvas*)>::operator()(flutter::SurfaceFrame&, flutter::DlCanvas*&&) + 556
    frame #14: 0x000000010d55f2e4 Flutter`flutter::SurfaceFrame::Submit() + 84
    frame #15: 0x000000010d0f66cc Flutter`flutter::IOSExternalViewEmbedder::SubmitFrame(GrDirectContext*, std::_LIBCPP_ABI_NAMESPACE::unique_ptr<flutter::SurfaceFrame, std::_LIBCPP_ABI_NAMESPACE::default_delete<flutter::SurfaceFrame> >) + 4056
    frame #16: 0x000000010d4a0cc0 Flutter`flutter::Rasterizer::DrawToSurfaceUnsafe(flutter::FrameTimingsRecorder&, flutter::LayerTree&) + 1320
    frame #17: 0x000000010d4a1770 Flutter`std::_LIBCPP_ABI_NAMESPACE::__function::__func<flutter::Rasterizer::DrawToSurface(flutter::FrameTimingsRecorder&, flutter::LayerTree&)::$_1, std::_LIBCPP_ABI_NAMESPACE::allocator<flutter::Rasterizer::DrawToSurface(flutter::FrameTimingsRecorder&, flutter::LayerTree&)::$_1>, void ()>::operator()() + 28
    frame #18: 0x000000010d3a6888 Flutter`fml::SyncSwitch::Execute(fml::SyncSwitch::Handlers const&) const + 72
    frame #19: 0x000000010d4a0638 Flutter`flutter::Rasterizer::DrawToSurface(flutter::FrameTimingsRecorder&, flutter::LayerTree&) + 272
    frame #20: 0x000000010d4a26ec Flutter`std::_LIBCPP_ABI_NAMESPACE::__function::__func<flutter::Rasterizer::Draw(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::Pipeline<flutter::LayerTreeItem> > const&, std::_LIBCPP_ABI_NAMESPACE::function<bool (flutter::LayerTree&)>)::$_1, std::_LIBCPP_ABI_NAMESPACE::allocator<flutter::Rasterizer::Draw(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::Pipeline<flutter::LayerTreeItem> > const&, std::_LIBCPP_ABI_NAMESPACE::function<bool (flutter::LayerTree&)>)::$_1>, void (std::_LIBCPP_ABI_NAMESPACE::unique_ptr<flutter::LayerTreeItem, std::_LIBCPP_ABI_NAMESPACE::default_delete<flutter::LayerTreeItem> >)>::operator()(std::_LIBCPP_ABI_NAMESPACE::unique_ptr<flutter::LayerTreeItem, std::_LIBCPP_ABI_NAMESPACE::default_delete<flutter::LayerTreeItem> >&&) + 312
    frame #21: 0x000000010d4a19bc Flutter`flutter::Rasterizer::Draw(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::Pipeline<flutter::LayerTreeItem> > const&, std::_LIBCPP_ABI_NAMESPACE::function<bool (flutter::LayerTree&)>) + 460
    frame #22: 0x000000010d4b8a8c Flutter`std::_LIBCPP_ABI_NAMESPACE::__function::__func<fml::internal::CopyableLambda<flutter::Shell::OnAnimatorDraw(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::Pipeline<flutter::LayerTreeItem> >)::$_0>, std::_LIBCPP_ABI_NAMESPACE::allocator<fml::internal::CopyableLambda<flutter::Shell::OnAnimatorDraw(std::_LIBCPP_ABI_NAMESPACE::shared_ptr<flutter::Pipeline<flutter::LayerTreeItem> >)::$_0> >, void ()>::operator()() + 368
    frame #23: 0x000000010d3a4ec0 Flutter`fml::MessageLoopImpl::FlushTasks(fml::FlushType) + 568
    frame #24: 0x000000010d3a8cbc Flutter`fml::MessageLoopDarwin::OnTimerFire(__CFRunLoopTimer*, fml::MessageLoopDarwin*) + 32
    frame #25: 0x00000001837c354c CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 32
    frame #26: 0x00000001837c31f4 CoreFoundation`__CFRunLoopDoTimer + 940
    frame #27: 0x00000001837c2d4c CoreFoundation`__CFRunLoopDoTimers + 356
    frame #28: 0x00000001837a8734 CoreFoundation`__CFRunLoopRun + 1896
    frame #29: 0x00000001837a7878 CoreFoundation`CFRunLoopRunSpecific + 612
    frame #30: 0x000000018ce87fa0 HIToolbox`RunCurrentEventLoopInMode + 292
    frame #31: 0x000000018ce87de4 HIToolbox`ReceiveNextEventCommon + 672
    frame #32: 0x000000018ce87b2c HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 72
    frame #33: 0x0000000186a2d838 AppKit`_DPSNextEvent + 632
    frame #34: 0x0000000186a2c9c8 AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 728
    frame #35: 0x0000000186a20df8 AppKit`-[NSApplication run] + 464
    frame #36: 0x00000001869f823c AppKit`NSApplicationMain + 880
    frame #37: 0x0000000186c526fc AppKit`_NSApplicationMainWithInfoDictionary + 24
    frame #38: 0x0000000199d42b04 UIKitMacHelper`UINSApplicationMain + 988
    frame #39: 0x00000001ad8380e4 UIKitCore`UIApplicationMain + 148
  * frame #40: 0x0000000100bde92c Runner`main at AppDelegate.swift:6:13
    frame #41: 0x000000018339fe50 dyld`start + 2544
@jonahwilliams jonahwilliams added the e: impeller Impeller rendering backend issues and features requests label Apr 11, 2023
@bdero
Copy lin 8000 k
Member
bdero commented Apr 11, 2023

cc @chinmaygarde It turns out users rely on framebufferOnly being turned off for platform view layers (to make them readable). Maybe it's time to give up on the dream and just make them readable like Skia does?

bdero added a commit to flutter/engine that referenced this issue Apr 11, 2023
Resolves flutter/flutter#124612.

Doing this would also allow us to remove the final blit on iOS when
advanced blends/backdrop filters are present (all of the facilities
would remain in place for GLES + Vulkan though).
zhongwuzw pushed a commit to zhongwuzw/engine that referenced this issue Apr 14, 2023
Resolves flutter/flutter#124612.

Doing this would also allow us to remove the final blit on iOS when
advanced blends/backdrop filters are present (all of the facilities
would remain in place for GLES + Vulkan though).
@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 25, 2023
bdero added a commit to bdero/flutter-engine that referenced this issue May 25, 2023
Resolves flutter/flutter#124612.

Doing this would also allow us to remove the final blit on iOS when
advanced blends/backdrop filters are present (all of the facilities
would remain in place for GLES + Vulkan though).

(cherry picked from commit ef089a6)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
e: impeller Impeller rendering backend issues and features requests
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants
0