Sitelet https://github.com/flutter/flutter/pull/192158
Skip to content

[Impeller][GLES] Rebind textures before buffer uploads - #192158

Merged
auto-submit[bot] merged 7 commits into
flutter:masterfrom
dfdgsdfg:fix/mali-gles-texture-name-reuse
Sep 23, 2026
Merged

auto-submit[bot] merged 7 commits into
flutter:masterfrom
dfdgsdfg:fix/mali-gles-texture-name-reuse

Conversation

@dfdgsdfg

@dfdgsdfg dfdgsdfg commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Addresses #190640

Reproduction

Public deterministic reproduction: dfdgsdfg/mali-crash-app. The workload and the historical matrix table are documented in the README.

Evidence

Confirmed facts from the diagnostic engine and the same production-like scenario:

  • The shared renderer deletes a texture name.
  • The same numeric name is regenerated on the resource context.
  • The upload path ends with isTexture=false for that name.
  • The first isolated error is FramebufferTexture2D: GL_INVALID_OPERATION, followed by a missing framebuffer attachment.

The trace matrix 7268086803036215683, force-rebind pass matrix 7248171571680282013, and verify-3 matrix 9163761808229023214 are the key Test Lab runs.

Inference: the trace and A/B results are consistent with a deleted object remaining bound and Mali treating a rebind to the same numeric name as no state transition. This is an inference about the driver behavior, not a claim that the GLES implementation violates the object-name specification.

Change

The direct GLES buffer-to-texture upload path now performs one extra zero bind immediately before binding the destination texture. The final binding state is unchanged. The RGBA unit test uses deterministic texture name 7 and preserves the ordered 0 then 7 binding sequence.

This is a minimal workaround and does not supersede #190655: that PR covers a different make-current failure path, while this reproduction had a successful/current resource context. #190655 was not directly tested here.

Physical validation

Using a Flutter 3.44.8-based diagnostic engine with the same app, Scenario 9, and Mali device:

  • Four affected diagnostic runs crashed after approximately 7–10 seconds.
  • The force-rebind A/B passed 4/4 runs, each running for 606 seconds, with no GL_INVALID_OPERATION, FBO failure, isTexture=false, or fatal signal observations.

The latest-master patch received the host validation below; the physical Test Lab binaries were built from the Flutter 3.44.8-based diagnostic engine, not from this latest-master patch.

Host validation

  • BlitCommandGLESTest.BlitCopyBufferToTextureCommandGLESRGBA: 1/1 passed
  • BlitCommandGLESTest.*: 11/11 passed
  • ProcTableGLES.*: 5/5 passed
  • ReactorGLES.*: 6 passed, 1 skipped because the host does not support labelling
  • ImageDecoderNoGLTest.*: 6/6 passed
  • Host impeller_unittests and ui_unittests builds passed
  • clang-format and git diff --check passed

Scope and trade-offs

This is a narrow workaround validated for one deterministic reproduction; it is not an architectural redesign or a general fix for all GLES texture-binding paths. The current physical mechanism is inferred from the trace and A/B results; this does not prove that every Mali crash in #190640 has the same cause.

The workaround applies only to BlitCopyBufferToTextureCommandGLES; other GLES bind/upload paths remain unchanged. It adds one additional glBindTexture per direct buffer-to-texture upload. Affected callers include image decode, glyph atlas, small utility textures, and Flutter GPU buffer-to-texture overwrite/copy paths.

The extra bind is likely small compared with texel transfer for normal uploads, but it has not been benchmarked; repeated small per-frame uploads may be sensitive. GL names come from the driver via glGenTextures, and Flutter cannot prevent numeric name reuse.

Reactor-level name-reuse prevention is not a simple alternative: delayed deletion and glFinish add memory and stall cost, and do not directly force the observed same-name state transition.

Reviewer guidance on performance and scope, including broader workaround plumbing if needed, is welcome.

@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. e: impeller Impeller rendering backend issues and features requests labels Sep 2, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a texture rebind before binding the target texture in BlitCopyBufferToTextureCommandGLES::Encode to resolve an issue on Mali GPUs where deleted shared texture names are reused. Feedback suggests replacing GL_NONE with 0 to avoid a conceptual type mismatch and align with idiomatic OpenGL/GLES usage.

const auto& gl = reactor.GetProcTable();
// Force a rebind after deleted shared texture names can be reused on Mali.
// See https://github.com/flutter/flutter/issues/190640.
gl.BindTexture(texture_type, GL_NONE);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In OpenGL/GLES, the default texture name (representing no texture bound) is 0. GL_NONE is a GLenum constant (typically used for draw/read buffer settings, etc.) and passing it to a parameter expecting a GLuint texture ID is a conceptual type mismatch, even though both evaluate to 0. Using 0 is more idiomatic and matches the expectation in the unit tests (which expect 0u).

Suggested change
gl.BindTexture(texture_type, GL_NONE);
gl.BindTexture(texture_type, 0);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Updated this to use 0u in a7d9451 so the texture-name type and intent are explicit and consistent with the unit-test expectation.

@gaaclarke gaaclarke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we try this instead? The current patch may still leave paths open to the mali crash. This patch, instead of preemptively clearing out the name, does the cleanup after the texture is used and addresses the case from texture_gles.cc:

    diff --git a/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc
    index 80e415a7e4..44d320be48 100644
    --- a/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc
    +++ b/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc
    @@ -211,6 +211,11 @@ bool BlitCopyBufferToTextureCommandGLES::Encode(
       }
       const auto& gl = reactor.GetProcTable();
       gl.BindTexture(texture_type, gl_handle.value());
    +  // Clean up texture binding so the worker/upload context doesn't retain a
    +  // dangling reference to a shared texture that may be deleted by another context.
    +  // See https://github.com/flutter/flutter/issues/190640.
    +  fml::ScopedCleanupClosure unbind([&gl, texture_type]() { gl.BindTexture(texture_type, 0u); });
    +
       const GLvoid* tex_data =
           source.GetBuffer()->OnGetContents() + source.GetRange().offset;
     
    diff --git a/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.cc
    index af7fa58d4a..9dfcba9586 100644
    --- a/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.cc
    +++ b/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.cc
    @@ -10,6 +10,7 @@
     #include "flutter/fml/logging.h"
     #include "flutter/fml/mapping.h"
     #include "flutter/fml/trace_event.h"
    +#include "flutter/fml/closure.h"
     #include "impeller/base/allocation.h"
     #include "impeller/base/validation.h"
     #include "impeller/core/formats.h"
    @@ -316,6 +317,10 @@ bool TextureGLES::OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
             }
             const auto& gl = reactor.GetProcTable();
             gl.BindTexture(texture_type, gl_handle.value());
    +        // Clean up texture binding so the worker/upload context doesn't retain a
    +        // dangling reference to a shared texture that may be deleted by another context.
    +        // See https://github.com/flutter/flutter/issues/190640.
    +        fml::ScopedCleanupClosure unbind([&gl, texture_type]() { gl.BindTexture(texture_type, 0u); });
             const GLvoid* tex_data = nullptr;
             if (mapping) {
               tex_data = mapping->GetMapping();

It's a bit of a shame to incur the overhead of this for one bad driver, but hopefully it isn't so bad that we have to conditionally do it.

@dfdgsdfg

dfdgsdfg commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — I like the cleanup direction and agree that leaving texture bindings behind at self-contained upload boundaries is worth addressing.

My one concern is that post-use unbinding at these two sites may not repair a stale same-name binding that is already present when the next blit upload starts. In the deterministic trace, the old name 7 binding was created through TextureGLES::InitializeContentsIfNecessary and framebuffer attachment, rather than OnSetContents. If that deleted object is still represented by binding 7 in the resource context when glGenTextures returns 7 again, the first BindTexture(target, 7) in the proposed sequence may already be the operation that the driver treats as no state transition. The cleanup at the end would then be too late for that upload.

That said, this is inferred from the trace rather than confirmed driver internals. I will test your exact two-site cleanup without the current pre-bind workaround against the deterministic physical-device reproduction and report the result here before deciding which form to keep.

@dfdgsdfg

dfdgsdfg commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for the suggestion — I tested the exact cleanup-only variant: the current pre-bind was removed, and post-use BindTexture(target, 0) was added only in BlitCopyBufferToTextureCommandGLES and TextureGLES::OnSetContents.

The APK/lib SHA and the crashing tombstone Build ID matched, so there was no stale-build ambiguity. It still crashed in the same Scenario 9 after about 5.13 seconds; I did not repeat the run.

The preceding owner, logical handle 311/name 8, was created through InitializeContentsIfNecessary and a successful FBO attach, and passed through neither cleanup site. It was deleted from the other shared context, then name 8 was regenerated for logical handle 315. The new blit upload reported GL_NO_ERROR, but glIsTexture was false. The cleanup happened only after that upload; the pending GL_INVALID_OPERATION was followed by INCOMPLETE_ATTACHMENT and the blit_pass_gles.cc(88) fatal.

By contrast, the pre-bind 0 → name workaround passed 4/4 runs at 606 seconds each. This is limited evidence: the exact two-site cleanup is insufficient for this deterministic reproduction, while the driver-internal mechanism remains inferred from diagnostics on a single device.

The public evidence is summarized here.

@dfdgsdfg
dfdgsdfg requested a review from gaaclarke September 5, 2026 07:46
@dfdgsdfg

dfdgsdfg commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

I completed a diagnostics-free performance A/B for the unconditional pre-bind.

The same frozen app commit (01186607bfbf8794615061657cd99db088480f0b) was tested with the exact PR base (ce1f5ff8d3f0932e7ab683b7b7d2d8fa3d4e1c57) versus the tip (a7d9451e72ee62511197f17108203ecf8917fdde). DEPS was identical. The source diff was the production change in blit_command_gles.cc plus its unit test. Both builds were profile Impeller GLES arm64 APKs without diagnostics.

The target was Pixel 5 (redfin), Android 30, ko_KR, portrait. Scenario 7 used n=3 runs per variant in the preselected sequence B1, P1, P2, B2, B3, P3; all 6/6 runs passed in 602–603 seconds. The workload consists of batches of 20 1536x1536 PNG decode/upload/resize/display operations. It is not a tiny-upload microbenchmark.

Using the full paginated sample series, the run-percentile mean deltas were CPU p50 +0.104 percentage points, p90 -0.132 percentage points, and p99 +0.060 percentage points. End-to-end iterations were 1553.7 → 1518.7 (-2.25%), but same-variant run-to-run variation was substantial, so the bind cost remains inconclusive. memoryTotal changes are descriptive only and do not support a causal memory claim.

There was no consistent sampled CPU regression signal in this workload. graphicsStats was empty, so FPS, GPU time, frame pacing, thermal state, and DVFS effects were not measured. Test Lab did not guarantee the same physical unit. This experiment does not establish a performance upper bound; high-frequency tiny uploads such as glyph atlas, utility textures, and Flutter GPU overwrite remain unmeasured. I am not making a general negligible/no-regression claim.

The complete table, artifact identities, and limitations are documented here:
https://github.com/dfdgsdfg/mali-crash-app/blob/main/docs/evidence.md#unconditional-pre-bind-performance-ab

@gaaclarke gaaclarke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. I think maybe we could have come up with something cleaner but the device is rare. The overhead for the extra set seem negligible so we can avoid putting it behind a workaround branch.

@gaaclarke
gaaclarke requested a review from flar September 8, 2026 22:04
@gaaclarke

Copy link
Copy Markdown
Member

@flar can you be a secondary reviewer on this please

@dfdgsdfg

dfdgsdfg commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor Author

Updated proposal: would you consider applying the extra pre-bind to native GLES on Mali-G models with a numeric model identifier of 76 or lower, rather than restricting it to G52/G71/G72/G76 individually or applying it to all GPUs?

This scopes the workaround, not Impeller support. In the production records we have reviewed, this crash group includes G52, G71, G72, and G76; we have not identified a report on a Mali-G model numbered above 76. That is an observation from our available records, not evidence of sufficient exposure or proof that higher-numbered models are unaffected.

Why broaden the proposal? Driver versions can differ by manufacturer firmware and Android release. A passing test on one OS build does not establish that the same GPU model is unaffected on older firmware. A broader numerical cutoff would include untested models within the range instead of assuming they are safe merely because we lack reports.

Evidence so far:

  • G71 / Galaxy A10 / Android 10: scenario 9 crashes with the G72-only guard inactive, using an ABI-matched armeabi-v7a APK. Test Lab reported a 16-second test, with Impeller OpenGLES and this sequence:

    GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
    [FATAL:flutter/impeller/renderer/backend/gles/blit_pass_gles.cc(88)]
    Check failed: result. Must be able to encode GL commands without error.
    SIGABRT
    
  • G72 / S9 / Android 10: reproduced without pre-bind; the G72-conditional build completed 604 seconds.

  • G52 / A31: present on Android 10 in our production report. The recent baseline pass was on Android 12, not the same OS/driver combination.

  • G76: no suitable device was identified in the current Test Lab catalog. However, our Google Play Android vitals report includes Galaxy S10 5G / Exynos 9820 / Mali-G76 on Android 10 in the same reported error group: 10 reports / 1 user in that query window. This is production evidence, not a Test Lab reproduction.

  • Controls: baseline scenario 9 completed on G57/A15/Android 14 (613 seconds) and G77/Note20 Ultra/Android 13 (602 seconds), one run each. These passes do not establish a driver-version boundary; under this proposal G57 would still receive the workaround.

Illustrative code, assuming the renderer has been parsed into an optional numeric Mali-G model identifier:

// Compute once during GLES description initialization.
// Parse the complete model token: G720 is 720, not G72.
needs_texture_upload_prebind_ =
    is_native_gles && !is_angle && mali_g_model.has_value() &&
    *mali_g_model > 0 && *mali_g_model <= 76;

// In BlitCopyBufferToTextureCommandGLES::Encode:
if (description.NeedsTextureUploadPrebind()) {
  gl.BindTexture(texture_type, 0u);
}
gl.BindTexture(texture_type, gl_handle.value());

The cutoff is explicitly numeric, not an architectural or chronological ordering: for example, G57 and G68 would be included, while G77 and G710 would not. It does not classify Mali-T-series or unknown renderer names. ANGLE would remain excluded. This is a conservative coverage proposal within that range, not proof that every included model is defective or that the cutoff is optimal.

Limitations: GPU labels in these device tests are model/SoC-based, without captured runtime GL renderer/driver strings. The G71 run differs in ABI/toolchain from the earlier arm64 baseline and is not a controlled A/B. We have not yet validated pre-bind enabled versus disabled on G71. A shared FBO/abort signature does not prove the same deleted-name-reuse mechanism on every family. The extra bind cost would remain on every direct buffer-to-texture upload on included GPUs; this proposal does not establish a performance upper bound or redesign other GLES binding paths.

flar
flar previously approved these changes Sep 9, 2026
Comment thread engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc Outdated
@dfdgsdfg

dfdgsdfg commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor Author

@gaaclarke gaaclarke added CICD Run CI/CD and removed CICD Run CI/CD labels Sep 9, 2026

@gaaclarke gaaclarke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dfdgsdfg there is a broken test you'll have to address.

[1519/9318] CommandBufferGLES.BufferToTextureBlitCanBeSubmittedBeforeContextCurrent (51 ms)
[INFO:flutter/testing/test_timeout_listener.cc(75)] Test timeout of 300 seconds per test case will be enforced.
�[0;33mNote: Google Test filter = CommandBufferGLES.BufferToTextureBlitCanBeSubmittedBeforeContextCurrent
�[m�[0;32m[==========] �[mRunning 1 test from 1 test suite.
�[0;32m[----------] �[mGlobal test environment set-up.
�[0;32m[----------] �[m1 test from CommandBufferGLES
�[0;32m[ RUN      ] �[mCommandBufferGLES.BufferToTextureBlitCanBeSubmittedBeforeContextCurrent
unknown file: Failure

Unexpected mock function call - returning directly.
    Function call: BindTexture(3553, 0)
Google Mock tried the following 1 expectation, but it didn't match:

../../../flutter/impeller/renderer/backend/gles/command_buffer_gles_unittests.cc:193: EXPECT_CALL(mock_gles_impl_ref, BindTexture(0x0DE1, kTextureHandle))...
  Expected arg #1: is equal to 1234
           Actual: 0
         Expected: to be called at least once
           Actual: never called - unsatisfied and active

@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Sep 10, 2026
@gaaclarke gaaclarke added the CICD Run CI/CD label Sep 10, 2026
@dfdgsdfg
dfdgsdfg force-pushed the fix/mali-gles-texture-name-reuse branch from 03b12e8 to d00e967 Compare September 11, 2026 00:28
@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Sep 11, 2026
@dfdgsdfg

dfdgsdfg commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor Author

Arm has confirmed this as a driver erratum. I filed it on the Arm developer forum and Arm replied with the errata writeup they're preparing:

Description — "Attaching a texture or renderbuffer to a framebuffer object
does not trigger synchronization with state updates made in a shared context."

Workaround — "You can bind the resource to a bind point using
glBindTexture() or glBindRenderBuffer() to force a state synchronization,
before attaching the resource to a framebuffer object."

https://community.arm.com/forums/f/mobile-graphics-and-gaming-forum/57861/mali-g72-reused-texture-name-invalid-after-shared-context-upload-zero-bind-avoids-failure/187047

Two things follow from that framing, and they bear on your original reviewcomment.

  1. It explains why the zero-bind is load-bearing. Encode() already called BindTexture(target, handle), but the reused name was already the current binding, so that bind was redundant and no synchronization happened. Binding zero first makes it a real bind-point state change. That's also why an unbind-after-use variant works — either way the next bind is no longer redundant.

  2. @gaaclarke You were right that "the current patch may still leave paths open". Arm describes the unsynchronized operation as the FBO attach, and TextureGLES::SetAsFramebufferAttachment() (texture_gles.cc:796) issues FramebufferTexture2D / FramebufferTexture2DMultisampleEXT / FramebufferRenderbuffer with no preceding bind at all. Callers are blit_command_gles.cc:49 and render_pass_gles.cc:290/297/305/657 — which is exactly the file your first suggested diff touched.

Per your original suggestion, I'll extend this PR to bind the resource before the attach in SetAsFramebufferAttachment and push an update shortly.

Arm identified the reproduced texture-name reuse failure as EN_ID 1,792,661, affecting Bifrost and Valhall r17p0 through r23p0 and fixed in r24p0. Cache the workaround decision from native GLES renderer and driver strings, retaining a conservative fallback for unidentifiable Arm G-series drivers. Cover driver boundaries, exclusions, malformed versions, and bind-before-upload ordering.
@dfdgsdfg

dfdgsdfg commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor Author

Arm has now identified the correct erratum for our API sequence: EN_ID 1,792,661, affecting Bifrost and Valhall drivers r17p0 through r23p0, with a fix in r24p0. They confirmed that binding texture zero before rebinding the desired name reliably avoids this issue.

Arm's updated response.

Based on that confirmation, I have kept the pre-upload zero-bind and have not added the post-use unbind in the two upload functions you suggested (BlitCopyBufferToTextureCommandGLES::Encode and TextureGLES::OnSetContents). To be precise, Arm confirmed the pre-bind workaround is sufficient for this erratum; they did not explicitly recommend against post-use cleanup. Omitting that additional cleanup is my implementation choice based on their response.

For now, commit cd0b145 targets the driver range Arm identified: on native GLES with a Mali-G / Immortalis-G renderer, the extra zero-bind applies to r17–r23, and is omitted for known releases before r17 or from r24 onward. If that driver version cannot be determined, the workaround remains enabled conservatively. OEM backports within the affected range cannot be detected.

This also corrects my earlier comment promising an extension to SetAsFramebufferAttachment: Arm subsequently clarified that their initial FBO-attachment diagnosis was a different issue.

@gaaclarke @flar Could you confirm which scope you would prefer? If you would like the workaround applied unconditionally across drivers, or the proposed post-use unbind added to both upload functions, I'm happy to revise the patch accordingly. Otherwise, could you please re-apply the CICD label so presubmit can run on the current driver-scoped implementation (cd0b145)? The PR is currently waiting on that label.

Validation: all 19 driver-scope regression cases pass; related GLES suites report 90 passed, 1 skipped. Host build and pre-push formatting checks passed. The new driver selector has not yet received physical-device validation; the prior device A/B results cover the zero-bind workaround itself.

@gaaclarke gaaclarke added the CICD Run CI/CD label Sep 16, 2026
@gaaclarke

Copy link
Copy Markdown
Member

@gaaclarke @flar Could you confirm which scope you would prefer? If you would like the workaround applied unconditionally across drivers, or the proposed post-use unbind added to both upload functions, I'm happy to revise the patch accordingly. Otherwise, could you please re-apply the CICD label so presubmit can run on the current driver-scoped implementation (cd0b145)? The PR is currently waiting on that label.

I was fine with applying it across drivers for now. If we are going to target specific drivers though I would want that added to CapabilitiesGLES not DescriptionGLES. Since you did good research to identify what is affected, it would be appreciated if you included the driver guard. It's up to you.

@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Sep 17, 2026
@gaaclarke gaaclarke added the CICD Run CI/CD label Sep 17, 2026
@gaaclarke

Copy link
Copy Markdown
Member

When you're ready for a rereview, just press the "Request re-review" button by my name.

@dfdgsdfg

Copy link
Copy Markdown
Contributor Author

@gaaclarke Updated in 5b2763f: moved the driver guard to CapabilitiesGLES, preserving the Arm-confirmed r17–r23 scope and the existing fallback for unparseable driver versions. Also merged the latest upstream/master available at the time (461663f).

Rebuilt with synced dependencies: related GLES tests passed (90 passed, 1 skipped), including all 19 driver-scope cases. Formatting checks also passed.

Could you please take another look and re-apply the CICD label so engine presubmit can run? Thanks!

@gaaclarke gaaclarke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks, great work

@gaaclarke
gaaclarke requested a review from flar September 18, 2026 15:58

@flar flar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD e: impeller Impeller rendering backend issues and features requests engine flutter/engine related. See also e: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants