Skip to content

[Impeller]Impeller errors appear when app opens:Break on 'ImpellerValidationBreak' to inspect point of failure: Could not find glyph position in the atlas. #164606

Description

@huycozy

Steps to reproduce

  1. Install and run Wonderous app on Android and iOS, my devices are: Pixel 7, Android 15 and iPhone 16 Pro Max (iOS 18.3.1).
  2. Home page/screen will appear (since the second time open app), and observe Impeller errors appear from the run output log. If you swipe pages, more same errors may appear.

Observing this issue on Flutter master channel 3.30.0-1.0.pre.448while I don't see it on stable 3.29.0.

Expected results

No error appear

Actual results

Multiple same errors are printed out as shared in Logs section.

Code sample

Code sample

https://github.com/gskinnerTeam/flutter-wonderous-app

Screenshots or Video

Screenshots / Video demonstration
Screen.Recording.2025-03-05.at.14.35.06.mov

Logs

Logs
Connecting to VM Service at ws://127.0.0.1:58613/UshQ4FN6TyY=/ws
Connected to the VM Service.
flutter: bootstrap start...
flutter: Navigate to: /
flutter: Saving...
flutter: setting discoveredCount for home widget 2
flutter: Navigate to: /home
11
[ERROR:flutter/impeller/entity/contents/text_contents.cc(161)] Break on 'ImpellerValidationBreak' to inspect point of failure: Could not find glyph position in the atlas.
2
flutter: Saving...
19
[ERROR:flutter/impeller/entity/contents/text_contents.cc(161)] Break on 'ImpellerValidationBreak' to inspect point of failure: Could not find glyph position in the atlas.
2
flutter: Saving...
24
[ERROR:flutter/impeller/entity/contents/text_contents.cc(161)] Break on 'ImpellerValidationBreak' to inspect point of failure: Could not find glyph position in the atlas.

Flutter Doctor output

Doctor output
[!] Flutter (Channel master, 3.30.0-1.0.pre.448, on macOS 15.3.1 24D70 darwin-x64, locale en-VN) [4.1s]
    • Flutter version 3.30.0-1.0.pre.448 on channel master at /Users/huynq/Documents/GitHub/flutter_master
    ! Warning: `flutter` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
    ! Warning: `dart` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 24418d0d80 (2 hours ago), 2025-03-04 00:04:22 -0500
    • Engine revision 24418d0d80
    • Dart version 3.8.0 (build 3.8.0-133.0.dev)
    • DevTools version 2.43.0
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.1) [4.5s]
    • Android SDK at /Users/huynq/Library/Android/sdk
    • Platform android-35, build-tools 35.0.1
    • ANDROID_HOME = /Users/huynq/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
      This JDK is specified in your Flutter configuration.
      To change the current JDK, run: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 16.2) [1,828ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 16C5032a
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web [27ms]
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.3) [25ms]
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • android-studio-dir = /Applications/Android Studio.app
    • Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)

[✓] VS Code (version 1.97.2) [23ms]
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.106.0

[✓] Connected device (4 available) [7.2s]
    • Pixel 7 (mobile)                      • 2B171FDH20084L            • android-arm64  • Android 15 (API 35)
    • iPhone 16 pro max (wireless) (mobile) • 00008140-00194CC23A68801C • ios            • iOS 18.3.1 22D72
    • macOS (desktop)                       • macos                     • darwin-x64     • macOS 15.3.1 24D70 darwin-x64
    • Chrome (web)                          • chrome                    • web-javascript • Google Chrome 133.0.6943.142

[✓] Network resources [477ms]
    • All expected network resources are available.

! Doctor found issues in 1 category.

Activity

  1. added
    engineflutter/engine related. See also e: labels.
    e: impellerImpeller rendering backend issues and features requests
    from: manual-qaIssue caught from manual QA process
    c: regressionIt was better in the past than it is now
    on Mar 5, 2025
  2. huycozy commented on Mar 5, 2025

    @huycozy
    MemberAuthor

    Just detected a similar issue reported recently at #164605. Two different things are:

    • Visual: texts are broken in 164605 while I don't see that issue on my end as reported here( it may be a different issue, mayn't it?)
    • 164605 is detected on Flutter 3.29.0 while I only see this issue on Flutter master channel.
  3. self-assigned this
    on Mar 6, 2025
  4. RaadShariat commented on Mar 6, 2025

    @RaadShariat

    The same issue is happening on Flutter 3.29.1 in the stable channel. The debug console is getting filled with this error:

    [ERROR:flutter/impeller/entity/contents/text_contents.cc(161)] Break on 'ImpellerValidationBreak' to inspect point of failure: Could not find glyph position in the atlas.

    Doctor results:

    [✓] Flutter (Channel stable, 3.29.1, on macOS 15.3.1 24D70 darwin-arm64, locale en-CA)
    [✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
    [✓] Xcode - develop for iOS and macOS (Xcode 16.2)
    [✓] Chrome - develop for the web
    [✓] Android Studio (version 2024.3)
    [✓] VS Code (version 1.98.0)
    [✓] Connected device (4 available)
    
  5. RaadShariat commented on Mar 6, 2025

    @RaadShariat

    Could this be prioritized @jonahwilliams ? The issue will prevent certain projects from upgrading to 3.29.1, which includes several important fixes.

  6. gaaclarke commented on Mar 6, 2025

    @gaaclarke
    Member

    stacktrace:

    frame #0: 0x0000007077f1c86c libflutter.so`impeller::ImpellerValidationBreak(message="Could not find glyph position in the atlas.", file="../../flutter/impeller/entity/contents/text_contents.cc", line=161) at validation.cc:55:7
        frame #1: 0x0000007077f1c82c libflutter.so`impeller::ValidationLog::~ValidationLog(this=0x00000070f9127ed8) at validation.cc:46:5
        frame #2: 0x0000007078c855c4 libflutter.so`impeller::TextContents::ComputeVertexData(vtx_contents=0xb40000704dc84920, frame=0xb4000071816394f0, scale=2.40449524, entity_transform=0x00000070f9128a50, offset=(x = 20.2000008, y = 188), glyph_properties=optional<impeller::GlyphProperties> @ 0x00000070f91283b8, atlas=0xb400007181637218) at text_contents.cc:161:11
        frame #3: 0x0000007078c8676c libflutter.so`impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0::operator()(this=0x00000070f9128e58, contents="") const at text_contents.cc:289:9
        frame #4: 0x0000007078c866dc libflutter.so`decltype(std::declval<impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0&>()(std::declval<unsigned char*>())) std::_fl::__invoke[abi:v15000]<impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0&, unsigned char*>(__f=0x00000070f9128e58, __args=<no value available>) at invoke.h:403:23
        frame #5: 0x0000007078c866ac libflutter.so`void std::_fl::__invoke_void_return_wrapper<void, true>::__call<impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0&, unsigned char*>(__args=0x00000070f9128e58, __args=<no value available>) at invoke.h:488:9
        frame #6: 0x0000007078c86680 libflutter.so`std::_fl::__function::__alloc_func<impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0, std::_fl::allocator<impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0>, void (unsigned char*)>::operator()[abi:v15000](this=0x00000070f9128e58, __arg=<no value available>) at function.h:185:16
        frame #7: 0x0000007078c86650 libflutter.so`std::_fl::__function::__func<impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0, std::_fl::allocator<impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0>, void (unsigned char*)>::operator()(this=0x00000070f9128e50, __arg=<no value available>) at function.h:359:12
        frame #8: 0x0000007077ae57c8 libflutter.so`std::_fl::__function::__value_func<void (fml::TaskSource const*)>::operator()[abi:v15000](this=0x00000070f9128e50, __args=0x00000070f91284c0) const at function.h:512:16
        frame #9: 0x0000007077ae355c libflutter.so`std::_fl::function<void (fml::TaskSource const*)>::operator()(this=0x00000070f9128e50, __arg=0xb40000704dc84920) const at function.h:1187:12
        frame #10: 0x0000007077f1f410 libflutter.so`impeller::HostBuffer::EmplaceInternal(this=0xb4000071816559c0, length=576, align=4, cb=0x00000070f9128e50) at host_buffer.cc:153:3
        frame #11: 0x0000007077f1f0a4 libflutter.so`impeller::HostBuffer::Emplace(this=0xb4000071816559c0, length=576, align=4, cb=0x00000070f9128e50) at host_buffer.cc:78:7
        frame #12: 0x0000007078c86028 libflutter.so`impeller::TextContents::Render(this=0xb4000071816394c8, renderer=0xb4000072516a28e0, entity=0x00000070f9129658, pass=0xb4000071f1660cf0) const at text_contents.cc:284:40
        frame #13: 0x0000007078c8deec libflutter.so`impeller::Entity::Render(this=0x00000070f9129658, renderer=0xb4000072516a28e0, parent_pass=0xb4000071f1660cf0) const at entity.cc:156:21
        frame #14: 0x0000007078bfbeac libflutter.so`impeller::Canvas::AddRenderEntityToCurrentPass(this=0x00000070f912a268, entity=0x00000070f9129658, reuse_depth=false) at canvas.cc:1574:10
        frame #15: 0x0000007078bfe6fc libflutter.so`impeller::Canvas::DrawTextFrame(this=0x00000070f912a268, text_frame=0xb4000072516d0d20, position=(x = 20.2000008, y = 188), paint=0x00000070f912a1d8) at canvas.cc:1402:3
        frame #16: 0x0000007078c0c948 libflutter.so`impeller::DlDispatcherBase::drawTextFrame(this=0x00000070f912a1d0, text_frame=0xb4000072516d0d20, x=20.2000008, y=188) at dl_dispatcher.cc:914:15
        frame #17: 0x0000007077e78580 libflutter.so`flutter::DrawTextFrameOp::dispatch(this=0xb4000072516d0d10, receiver=0x00000070f912a1d0) const at dl_op_records.h:1032:14
        frame #18: 0x0000007077e76d9c libflutter.so`flutter::DisplayList::DispatchOneOp(this=0xb400007171697960, receiver=0x00000070f912a1d0, ptr="B") const at display_list.cc:218:5
        frame #19: 0x0000007077e76fb0 libflutter.so`flutter::DisplayList::Dispatch(this=0xb400007171697960, receiver=0x00000070f912a1d0, cull_rect=0x00000070f9129b00) const at display_list.cc:204:7
        frame #20: 0x0000007077eb5d10 libflutter.so`flutter::DisplayList::Dispatch(this=0xb400007171697960, ctx=0x00000070f912a1d0, cull_rect=0x00000070f9129b00) const at display_list.h:278:5
        frame #21: 0x0000007078c0c550 libflutter.so`impeller::DlDispatcherBase::drawDisplayList(this=0x00000070f912a1d0, display_list=sk_sp<flutter::DisplayList> @ 0x00000070f9129da8, opacity=1) at dl_dispatcher.cc:879:21
        frame #22: 0x0000007077e784d0 libflutter.so`flutter::DrawDisplayListOp::dispatch(this=0xb4000072516717c8, receiver=0x00000070f912a1d0) const at dl_op_records.h:991:14
        frame #23: 0x0000007077e76d7c libflutter.so`flutter::DisplayList::DispatchOneOp(this=0xb400007171658d50, receiver=0x00000070f912a1d0, ptr="@") const at display_list.cc:218:5
        frame #24: 0x0000007077e768f8 libflutter.so`flutter::DisplayList::Dispatch(this=0xb400007171658d50, receiver=0x00000070f912a1d0) const at display_list.cc:184:5
        frame #25: 0x0000007077e76f00 libflutter.so`flutter::DisplayList::Dispatch(this=0xb400007171658d50, receiver=0x00000070f912a1d0, cull_rect=0x00000070f912a048) const at display_list.cc:199:5
        frame #26: 0x0000007077e76e80 libflutter.so`flutter::DisplayList::Dispatch(this=0xb400007171658d50, receiver=0x00000070f912a1d0, cull_rect=0x00000070f912a5d0) const at display_list.cc:190:3
        frame #27: 0x0000007078c0e970 libflutter.so`flutter::DisplayList::Dispatch(this=0xb400007171658d50, ctx=0x00000070f912a1d0, cull_rect=0x00000070f912a5d0) const at display_list.h:281:5
        frame #28: 0x0000007078c0f658 libflutter.so`impeller::RenderToTarget(context=0xb4000072516a28e0, render_target=RenderTarget @ 0x00000070f912a640, display_list=0x00000070f912a858, cull_rect=(fLeft = 0, fTop = 0, fRight = 1080, fBottom = 2274), reset_host_buffer=true, is_onscreen=true) at dl_dispatcher.cc:1360:17
        frame #29: 0x0000007078ed3874 libflutter.so`flutter::GPUSurfaceGLImpeller::AcquireFrame(SkISize const&)::$_3::operator()(this=0xb4000071b169b818, surface_frame=0xb4000071b167d7b0, canvas=0xb4000071c1686ed0) at gpu_surface_gl_impeller.cc:119:12
        frame #30: 0x0000007078ed36c0 libflutter.so`decltype(std::declval<flutter::GPUSurfaceGLImpeller::AcquireFrame(SkISize const&)::$_3&>()(std::declval<flutter::SurfaceFrame&>(), std::declval<flutter::DlCanvas*>())) std::_fl::__invoke[abi:v15000]<flutter::GPUSurfaceGLImpeller::AcquireFrame(SkISize const&)::$_3&, flutter::SurfaceFrame&, flutter::DlCanvas*>(__f=0xb4000071b169b818, __args=0xb4000071b167d7b0, __args=0x00000070f912a998) at invoke.h:403:23
        frame #31: 0x0000007078ed3684 libflutter.so`bool std::_fl::__invoke_void_return_wrapper<bool, false>::__call<flutter::GPUSurfaceGLImpeller::AcquireFrame(SkISize const&)::$_3&, flutter::SurfaceFrame&, flutter::DlCanvas*>(__args=0xb4000071b169b818, __args=0xb4000071b167d7b0, __args=0x00000070f912a998) at invoke.h:479:16
        frame #32: 0x0000007078ed364c libflutter.so`std::_fl::__function::__alloc_func<flutter::GPUSurfaceGLImpeller::AcquireFrame(SkISize const&)::$_3, std::_fl::allocator<flutter::GPUSurfaceGLImpeller::AcquireFrame(SkISize const&)::$_3>, bool (flutter::SurfaceFrame&, flutter::DlCanvas*)>::operator()[abi:v15000](this=0xb4000071b169b818, __arg=0xb4000071b167d7b0, __arg=0x00000070f912a998) at function.h:185:16
        frame #33: 0x0000007078ed3314 libflutter.so`std::_fl::__function::__func<flutter::GPUSurfaceGLImpeller::AcquireFrame(SkISize const&)::$_3, std::_fl::allocator<flutter::GPUSurfaceGLImpeller::AcquireFrame(SkISize const&)::$_3>, bool (flutter::SurfaceFrame&, flutter::DlCanvas*)>::operator()(this=0xb4000071b169b810, __arg=0xb4000071b167d7b0, __arg=0x00000070f912a998) at function.h:359:12
        frame #34: 0x0000007077adc420 libflutter.so`std::_fl::__function::__value_func<bool (fml::UniqueObject<int, fml::internal::os_unix::UniqueFDTraits> const&, std::_fl::basic_string<char, std::_fl::char_traits<char>, std::_fl::allocator<char>> const&)>::operator()[abi:v15000](this=0xb4000071b167d840, __args=0xb4000071b167d7b0, __args=0x00000070f912a998) const at function.h:512:16
        frame #35: 0x0000007078a24d9c libflutter.so`std::_fl::function<bool (flutter::SurfaceFrame&, flutter::DlCanvas*)>::operator()(this=0xb4000071b167d840, __arg=0xb4000071b167d7b0, __arg=0xb4000071c1686ed0) const at function.h:1187:12
        frame #36: 0x0000007078a24ba0 libflutter.so`flutter::SurfaceFrame::PerformEncode(this=0xb4000071b167d7b0) at surface_frame.cc:95:7
        frame #37: 0x0000007078a24af8 libflutter.so`flutter::SurfaceFrame::Encode(this=0xb4000071b167d7b0) at surface_frame.cc:58:14
        frame #38: 0x0000007078a24c40 libflutter.so`flutter::SurfaceFrame::Submit(this=0xb4000071b167d7b0) at surface_frame.cc:65:21
        frame #39: 0x0000007078db7d78 libflutter.so`flutter::Rasterizer::DrawToSurfaceUnsafe(this=0xb4000071c16816d0, view_id=0, layer_tree=0xb4000071516c0c90, device_pixel_ratio=2.75, presentation_time=optional<fml::TimePoint> @ 0x00000070f912b0e8) at rasterizer.cc:795:14
        frame #40: 0x0000007078db71d8 libflutter.so`flutter::Rasterizer::DrawToSurfacesUnsafe(this=0xb4000071c16816d0, frame_timings_recorder=0xb4000071b1673eb0, tasks=vector<std::_fl::unique_ptr<flutter::LayerTreeTask, std::_fl::default_delete<flutter::LayerTreeTask> >, std::_fl::allocator<std::_fl::unique_ptr<flutter::LayerTreeTask, std::_fl::default_delete<flutter::LayerTreeTask> > > > @ 0x00000070f912b6e8) at rasterizer.cc:658:32
        frame #41: 0x0000007078db4ecc libflutter.so`flutter::Rasterizer::DrawToSurfaces(this=0xb4000071c16816d0, frame_timings_recorder=0xb4000071b1673eb0, tasks=vector<std::_fl::unique_ptr<flutter::LayerTreeTask, std::_fl::default_delete<flutter::LayerTreeTask> >, std::_fl::allocator<std::_fl::unique_ptr<flutter::LayerTreeTask, std::_fl::default_delete<flutter::LayerTreeTask> > > > @ 0x00000070f912bc30) at rasterizer.cc:587:9
        frame #42: 0x0000007078db6280 libflutter.so`flutter::Rasterizer::DoDraw(this=0xb4000071c16816d0, frame_timings_recorder=unique_ptr<flutter::FrameTimingsRecorder, std::_fl::default_delete<flutter::FrameTimingsRecorder> > @ 0x00000070f912be28, tasks=vector<std::_fl::unique_ptr<flutter::LayerTreeTask, std::_fl::default_delete<flutter::LayerTreeTask> >, std::_fl::allocator<std::_fl::unique_ptr<flutter::LayerTreeTask, std::_fl::default_delete<flutter::LayerTreeTask> > > > @ 0x00000070f912be10) at rasterizer.cc:491:7
        frame #43: 0x0000007078dbb6a8 libflutter.so`flutter::Rasterizer::Draw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>> const&)::$_0::operator()(this=0x00000070f912c3f8, item=unique_ptr<flutter::FrameItem, std::_fl::default_delete<flutter::FrameItem> > @ 0x00000070f912be78) const at rasterizer.cc:259:19
        frame #44: 0x0000007078dbb618 libflutter.so`decltype(std::declval<flutter::Rasterizer::Draw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>> const&)::$_0&>()(std::declval<std::_fl::unique_ptr<flutter::FrameItem, std::_fl::default_delete<flutter::FrameItem>>>())) std::_fl::__invoke[abi:v15000]<flutter::Rasterizer::Draw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>> const&)::$_0&, std::_fl::unique_ptr<flutter::FrameItem, std::_fl::default_delete<flutter::FrameItem>>>(__f=0x00000070f912c3f8, __args=0x00000070f912bfa0) at invoke.h:403:23
        frame #45: 0x0000007078dbb5d4 libflutter.so`void std::_fl::__invoke_void_return_wrapper<void, true>::__call<flutter::Rasterizer::Draw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>> const&)::$_0&, std::_fl::unique_ptr<flutter::FrameItem, std::_fl::default_delete<flutter::FrameItem>>>(__args=0x00000070f912c3f8, __args=0x00000070f912bfa0) at invoke.h:488:9
        frame #46: 0x0000007078dbb5a8 libflutter.so`std::_fl::__function::__alloc_func<flutter::Rasterizer::Draw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>> const&)::$_0, std::_fl::allocator<flutter::Rasterizer::Draw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>> const&)::$_0>, void (std::_fl::unique_ptr<flutter::FrameItem, std::_fl::default_delete<flutter::FrameItem>>)>::operator()[abi:v15000](this=0x00000070f912c3f8, __arg=0x00000070f912bfa0) at function.h:185:16
        frame #47: 0x0000007078dbb578 libflutter.so`std::_fl::__function::__func<flutter::Rasterizer::Draw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>> const&)::$_0, std::_fl::allocator<flutter::Rasterizer::Draw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>> const&)::$_0>, void (std::_fl::unique_ptr<flutter::FrameItem, std::_fl::default_delete<flutter::FrameItem>>)>::operator()(this=0x00000070f912c3f0, __arg=0x00000070f912bfa0) at function.h:359:12
        frame #48: 0x0000007077ae57c8 libflutter.so`std::_fl::__function::__value_func<void (fml::TaskSource const*)>::operator()[abi:v15000](this=0x00000070f912c3f0, __args=0x00000070f912bfa0) const at function.h:512:16
        frame #49: 0x0000007077f2c338 libflutter.so`std::_fl::function<void (std::_fl::unique_ptr<std::_fl::vector<impeller::TPoint<float>, std::_fl::allocator<impeller::TPoint<float>>>, std::_fl::default_delete<std::_fl::vector<impeller::TPoint<float>, std::_fl::allocator<impeller::TPoint<float>>>>>)>::operator()(this=0x00000070f912c3f0, __arg=unique_ptr<std::_fl::vector<impeller::TPoint<float>, std::_fl::allocator<impeller::TPoint<float> > >, std::_fl::default_delete<std::_fl::vector<impeller::TPoint<float>, std::_fl::allocator<impeller::TPoint<float> > > > > @ 0x00000070f912bfa0) const at function.h:1187:12
        frame #50: 0x0000007078db572c libflutter.so`flutter::Pipeline<flutter::FrameItem>::Consume(this=0xb400007181645d88, consumer=0x00000070f912c3f0) at pipeline.h:203:5
        frame #51: 0x0000007078db52fc libflutter.so`flutter::Rasterizer::Draw(this=0xb4000071c16816d0, pipeline=0x00000070f912c468) at rasterizer.cc:263:52
        frame #52: 0x0000007078de478c libflutter.so`flutter::Shell::OnAnimatorDraw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>>)::$_0::operator()(this=0xb40000716167bc60) at shell.cc:1290:25
        frame #53: 0x0000007078de4720 libflutter.so`auto fml::internal::CopyableLambda<flutter::Shell::OnAnimatorDraw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>>)::$_0>::operator()<>(this=0xb400007111688b98) const at make_copyable.h:24:12
        frame #54: 0x0000007078de46f4 libflutter.so`decltype(std::declval<fml::internal::CopyableLambda<flutter::Shell::OnAnimatorDraw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>>)::$_0>&>()()) std::_fl::__invoke[abi:v15000]<fml::internal::CopyableLambda<flutter::Shell::OnAnimatorDraw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>>)::$_0>&>(__f=0xb400007111688b98) at invoke.h:403:23
        frame #55: 0x0000007078de46d0 libflutter.so`void std::_fl::__invoke_void_return_wrapper<void, true>::__call<fml::internal::CopyableLambda<flutter::Shell::OnAnimatorDraw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>>)::$_0>&>(__args=0xb400007111688b98) at invoke.h:488:9
        frame #56: 0x0000007078de46ac libflutter.so`std::_fl::__function::__alloc_func<fml::internal::CopyableLambda<flutter::Shell::OnAnimatorDraw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>>)::$_0>, std::_fl::allocator<fml::internal::CopyableLambda<flutter::Shell::OnAnimatorDraw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>>)::$_0>>, void ()>::operator()[abi:v15000](this=0xb400007111688b98) at function.h:185:16
        frame #57: 0x0000007078de45c4 libflutter.so`std::_fl::__function::__func<fml::internal::CopyableLambda<flutter::Shell::OnAnimatorDraw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>>)::$_0>, std::_fl::allocator<fml::internal::CopyableLambda<flutter::Shell::OnAnimatorDraw(std::_fl::shared_ptr<flutter::Pipeline<flutter::FrameItem>>)::$_0>>, void ()>::operator()(this=0xb400007111688b90) at function.h:359:12
        frame #58: 0x0000007077ad7254 libflutter.so`std::_fl::__function::__value_func<void ()>::operator()[abi:v15000](this=0x00000070f912c630) const at function.h:512:16
        frame #59: 0x0000007077ad6630 libflutter.so`std::_fl::function<void ()>::operator()(this=0x00000070f912c630) const at function.h:1187:12
        frame #60: 0x0000007077ae0438 libflutter.so`fml::MessageLoopImpl::FlushTasks(this=0xb4000071416e63f0, type=kAll) at message_loop_impl.cc:126:5
        frame #61: 0x0000007077ae0348 libflutter.so`fml::MessageLoopImpl::RunExpiredTasksNow(this=0xb4000071416e63f0) at message_loop_impl.cc:139:3
        frame #62: 0x0000007077af2ffc libflutter.so`fml::MessageLoopAndroid::OnEventFired(this=0xb4000071416e63f0) at message_loop_android.cc:91:5
        frame #63: 0x0000007077af3074 libflutter.so`fml::MessageLoopAndroid::MessageLoopAndroid()::$_0::operator()(this=0x00000070f912c70f, (null)=90, events=1, data=0xb4000071416e63f0) const at message_loop_android.cc:41:52
        frame #64: 0x0000007077af3038 libflutter.so`fml::MessageLoopAndroid::MessageLoopAndroid()::$_0::__invoke((null)=90, events=1, data=0xb4000071416e63f0) at message_loop_android.cc:39:40
        frame #65: 0x00000073b5457078 libutils.so`android::Looper::pollOnce(int, int*, int*, void**) + 812
        frame #66: 0x00000070f485c140 libandroid.so`ALooper_pollOnce + 104
        frame #67: 0x0000007077af2e68 libflutter.so`fml::MessageLoopAndroid::Run(this=0xb4000071416e63f0) at message_loop_android.cc:67:18
        frame #68: 0x0000007077ae02ac libflutter.so`fml::MessageLoopImpl::DoRun(this=0xb4000071416e63f0) at message_loop_impl.cc:94:3
        frame #69: 0x0000007077adf860 libflutter.so`fml::MessageLoop::Run(this=0xb4000071116565f0) at message_loop.cc:49:10
        frame #70: 0x0000007077aed75c libflutter.so`fml::Thread::Thread(std::_fl::function<void (fml::Thread::ThreadConfig const&)> const&, fml::Thread::ThreadConfig const&)::$_0::operator()(this=0xb40000717165ef40) const at thread.cc:154:14
        frame #71: 0x0000007077aed6e4 libflutter.so`decltype(std::declval<fml::Thread::Thread(std::_fl::function<void (fml::Thread::ThreadConfig const&)> const&, fml::Thread::ThreadConfig const&)::$_0&>()()) std::_fl::__invoke[abi:v15000]<fml::Thread::Thread(std::_fl::function<void (fml::Thread::ThreadConfig const&)> const&, fml::Thread::ThreadConfig const&)::$_0&>(__f=0xb40000717165ef40) at invoke.h:403:23
        frame #72: 0x0000007077aed6c0 libflutter.so`void std::_fl::__invoke_void_return_wrapper<void, true>::__call<fml::Thread::Thread(std::_fl::function<void (fml::Thread::ThreadConfig const&)> const&, fml::Thread::ThreadConfig const&)::$_0&>(__args=0xb40000717165ef40) at invoke.h:488:9
        frame #73: 0x0000007077aed69c libflutter.so`std::_fl::__function::__alloc_func<fml::Thread::Thread(std::_fl::function<void (fml::Thread::ThreadConfig const&)> const&, fml::Thread::ThreadConfig const&)::$_0, std::_fl::allocator<fml::Thread::Thread(std::_fl::function<void (fml::Thread::ThreadConfig const&)> const&, fml::Thread::ThreadConfig const&)::$_0>, void ()>::operator()[abi:v15000](this=0xb40000717165ef40) at function.h:185:16
        frame #74: 0x0000007077aed55c libflutter.so`std::_fl::__function::__func<fml::Thread::Thread(std::_fl::function<void (fml::Thread::ThreadConfig const&)> const&, fml::Thread::ThreadConfig const&)::$_0, std::_fl::allocator<fml::Thread::Thread(std::_fl::function<void (fml::Thread::ThreadConfig const&)> const&, fml::Thread::ThreadConfig const&)::$_0>, void ()>::operator()(this=0xb40000717165ef30) at function.h:359:12
        frame #75: 0x0000007077ad7254 libflutter.so`std::_fl::__function::__value_func<void ()>::operator()[abi:v15000](this=0xb40000713193e2d0) const at function.h:512:16
        frame #76: 0x0000007077ad6630 libflutter.so`std::_fl::function<void ()>::operator()(this=0xb40000713193e2d0) const at function.h:1187:12
        frame #77: 0x0000007077aece98 libflutter.so`fml::ThreadHandle::ThreadHandle(std::_fl::function<void ()>&&)::$_0::operator()(this=0x00000070f912cc37, arg=0xb40000713193e2d0) const at thread.cc:76:9
        frame #78: 0x0000007077aece5c libflutter.so`fml::ThreadHandle::ThreadHandle(std::_fl::function<void ()>&&)::$_0::__invoke(arg=0xb40000713193e2d0) at thread.cc:73:7
        frame #79: 0x000000739af603b4 libc.so`__pthread_start(void*) + 212
        frame #80: 0x000000739aefd0bc libc.so`__start_thread + 68
    
  7. gaaclarke commented on Mar 7, 2025

    @gaaclarke
    Member

    debugger

    The lookup is failing from the subpixel differences. This could be because the FontGlyphAtlas was loaded incorrectly, or we are grabbing the wrong FontGlyphAtlas since querying it depends on the rounded_scale key.

    (lldb) p glyph_position.glyph
    (const impeller::Glyph)  (index = 161, type = kPath)
    (lldb) p subpixel
    (impeller::Point)  (x = 0.5, y = 0)
    (lldb) p font_atlas->positions_.size()
    (size_t) 6
    (lldb) p *(++(++font_atlas->positions_.begin()))
    (std::pair<const impeller::SubpixelGlyph, impeller::FrameBounds>) {
      first = {
        glyph = (index = 161, type = kPath)
        subpixel_offset = (x = 0.25, y = 0)
        properties = {
          std::_fl::__optional_move_assign_base<impeller::GlyphProperties, true> = {
            std::_fl::__optional_copy_assign_base<impeller::GlyphProperties, true> = {
              std::_fl::__optional_move_base<impeller::GlyphProperties, true> = {
                std::_fl::__optional_copy_base<impeller::GlyphProperties, true> = {
                  std::_fl::__optional_storage_base<impeller::GlyphProperties, false> = {
                    std::_fl::__optional_destruct_base<impeller::GlyphProperties, true> = {
                       = {
                        __null_state_ = '\0' 0 '\0'
                        __val_ = {
                          color = (red = 4.68555353E+33, green = 1.56945428E-43, blue = 4.68466221E+33, alpha = 1.56945428E-43)
                          stroke_width = 5.97308723E+35
                          stroke_cap = 0x70
                          stroke_join = kMiter
                          stroke_miter = 1.56945428E-43
                          stroke = true
                        }
                      }
                      __engaged_ = false
                    }
                  }
                }
              }
            }
          }
        }
      }
      second = {
        atlas_bounds = (left_ = 1135, top_ = 320, right_ = 1155, bottom_ = 352)
        glyph_bounds = (left_ = 0, top_ = -32, right_ = 20, bottom_ = 0)
        is_placeholder = false
      }
    }
    

    TextFrame::ComputeSubpixelPosition usage

    TextFrame::ComputeSubpixelPosition is called twice, once when filling the glyph atlas and once when reading from the glyph atlas and they are returning different values for some reason. In testing here are the stack traces for loading glyphs vs using them

    loading

    impeller_unittests!impeller::TextFrame::ComputeSubpixelPosition(impeller::TextRun::GlyphPosition const&, impeller::AxisAlignment, impeller::Matrix const&) (/Users/aaclarke/dev/flutter/engine/src/flutter/impe$
    impeller_unittests!impeller::TypographerContextSkia::CollectNewGlyphs(std::_fl::shared_ptr<impeller::GlyphAtlas> const&, std::_fl::vector<std::_fl::shared_ptr<impeller::TextFrame>, std::_fl::allocator<std::_$
    impeller_unittests!impeller::TypographerContextSkia::CreateGlyphAtlas(impeller::Context&, impeller::GlyphAtlas::Type, impeller::HostBuffer&, std::_fl::shared_ptr<impeller::GlyphAtlasContext> const&, std::_fl$
    impeller_unittests!impeller::LazyGlyphAtlas::CreateOrGetGlyphAtlas(impeller::Context&, impeller::HostBuffer&, impeller::GlyphAtlas::Type) const (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/typogr$
    impeller_unittests!impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/entity/conten$
    impeller_unittests!impeller::Entity::Render(impeller::ContentContext const&, impeller::RenderPass&) const (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/entity/entity.cc:156)
    

    using

    impeller_unittests!impeller::TextFrame::ComputeSubpixelPosition(impeller::TextRun::GlyphPosition const&, impeller::AxisAlignment, impeller::Matrix const&) (/Users/aaclarke/dev/flutter/engine/src/flutter/impe$
    impeller_unittests!impeller::TextContents::ComputeVertexData(impeller::GlyphAtlasVertexShader::PerVertexData*, std::_fl::shared_ptr<impeller::TextFrame> const&, float, impeller::Matrix const&, impeller::TPoi$
    impeller_unittests!impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0::operator()(unsigned char*) const (/Users/aaclarke/dev/flutter/en$
    impeller_unittests!decltype(std::declval<impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0&>()(std::declval<unsigned char*>())) std::_$
    impeller_unittests!void std::_fl::__invoke_void_return_wrapper<void, true>::__call<impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0&,$
    impeller_unittests!std::_fl::__function::__alloc_func<impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0, std::_fl::allocator<impeller:$
    impeller_unittests!std::_fl::__function::__func<impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const::$_0, std::_fl::allocator<impeller::TextC$
    impeller_unittests!std::_fl::__function::__value_func<void (unsigned char*)>::operator()[abi:v15000](unsigned char*&&) const (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__funct$
    impeller_unittests!std::_fl::function<void (unsigned char*)>::operator()(unsigned char*) const (/Users/aaclarke/dev/flutter/engine/src/flutter/third_party/libcxx/include/__functional/function.h:1187)
    impeller_unittests!impeller::HostBuffer::EmplaceInternal(unsigned long, unsigned long, std::_fl::function<void (unsigned char*)> const&) (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/core/host_buf$
    impeller_unittests!impeller::HostBuffer::Emplace(unsigned long, unsigned long, std::_fl::function<void (unsigned char*)> const&) (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/core/host_buffer.cc:7$
    impeller_unittests!impeller::TextContents::Render(impeller::ContentContext const&, impeller::Entity const&, impeller::RenderPass&) const (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/entity/conten$
    impeller_unittests!impeller::Entity::Render(impeller::ContentContext const&, impeller::RenderPass&) const (/Users/aaclarke/dev/flutter/engine/src/flutter/impeller/entity/entity.cc:156)
    
  8. gaaclarke commented on Mar 8, 2025

    @gaaclarke
    Member

    This is really tricky since it seems to be a race condition. If I put in a lot of tracing I'll stop being able to reproduce the bug. Here is one log that shows what's going on:

    E/flutter ( 7896): [ERROR:flutter/impeller/typographer/text_frame.cc(107)] SetPerFrameData 
    E/flutter ( 7896): [ERROR:flutter/impeller/typographer/backends/skia/typographer_context_skia.cc(478)] add 584 1 481/200 (
    E/flutter ( 7896):        2.407271,       0.000000,       0.000000,    1039.895630,
    E/flutter ( 7896):        0.000000,       2.407271,       0.000000,     833.210754,
    E/flutter ( 7896):        0.000000,       0.000000,       1.000000,       0.000000,
    E/flutter ( 7896):        0.000000,       0.000000,       0.000000,       1.000000,
    E/flutter ( 7896): )
    E/flutter ( 7896): [ERROR:flutter/impeller/entity/contents/text_contents.cc(161)] Break on 'ImpellerValidationBreak' to inspect point of failure: Could not find glyph position in the atlas. 584 0 481/200 (
    E/flutter ( 7896):        2.407271,       0.000000,       0.000000,     968.883301,
    E/flutter ( 7896):        0.000000,       2.407271,       0.000000,     506.056122,
    E/flutter ( 7896):        0.000000,       0.000000,       1.000000,       0.000000,
    E/flutter ( 7896):        0.000000,       0.000000,       0.000000,       1.000000,
    E/flutter ( 7896): )
    

    So, this is in the span of one SetPerFrameData (I hate stateful stuff like this for this exact reason). Glyph 584 is getting added at subpixel position 1 for scale 481/200. Then later we are looking up glyph 584 with subpixel position 0 for that same scale.

    I've printed out the 2 matrices that are used to call TextFrame::ComputeSubpixelPosition. We can see that the offsets differ for some reason.

  9. added
    P1High-priority issues at the top of the work list
    on Mar 10, 2025
  10. added
    r: fixedIssue is closed as already fixed in a newer version
    on Mar 11, 2025
  11. github-actions commented on Mar 25, 2025

    @github-actions

    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.

  12. locked as resolved and limited conversation to collaborators on Mar 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P1High-priority issues at the top of the work listc: regressionIt was better in the past than it is nowe: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.from: manual-qaIssue caught from manual QA processr: fixedIssue is closed as already fixed in a newer versionteam-engineOwned by Engine teamtriaged-engineTriaged by Engine team

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions