Skip to content

[Windows] Use an unsized texture format for backing stores on OpenGL ES 2 - #192917

Merged
auto-submit[bot] merged 2 commits into
flutter:masterfrom
krll-kov:windows-gles2-backing-store-format
Sep 17, 2026
Merged

auto-submit[bot] merged 2 commits into
flutter:masterfrom
krll-kov:windows-gles2-backing-store-format

Conversation

@krll-kov

Copy link
Copy Markdown
Contributor

On GPUs limited to D3D11 feature level 10_0, ANGLE only creates an OpenGL ES 2.0 context. CompositorOpenGL::CreateBackingStore passes the sized format (GL_BGRA8_EXT or GL_RGBA8) as the internalformat of glTexImage2D. ES 2.0 requires internalformat to equal format, so the call fails with GL_INVALID_VALUE, the backing store framebuffer is incomplete and the window stays black with no error logged. Flutter 3.44.2 passed the unsized format there, the sized one came in with the MSAA backing store changes.

This change picks the internal format once in Initialize: the unsized general format on an ES 2 context, the sized format otherwise. The three TexImage2D calls use it. The sized format is still reported to the engine through FlutterOpenGLFramebuffer.target, and nothing changes on ES 3 contexts.

Tests:

  • CreateBackingStoreGLES2Unsized: ES 2 with Skia, glTexImage2D gets GL_BGRA_EXT, the engine still gets GL_BGRA8_EXT.
  • CreateBackingStoreImpellerGLES2Unsized: ES 2 with Impeller, GL_BGRA_EXT.
  • CreateBackingStoreGLES3Sized: ES 3 keeps GL_RGBA8.

The two ES 2 tests fail without the change.

Manually verified with a dxcpl Feature level limit of 10_0, where the unpatched engine shows a black window: on 3.47.4 x64 a stock app renders with Skia and Impeller, and so does an app with gradients, shadows, a multiply blend and animation. An animated app runs at 120 FPS at 10_0 with both renderers, the same as the official engine without the limit. With Impeller, content drawn before a BackdropFilter is still lost at 10_0; that is a separate Impeller bug. On main (arm64) the stock app renders with an ES 2 context, a complete framebuffer and no GL errors. Also verified in a production app on 3.47.4.

Fixes #191978

Pre-launch Checklist

@krll-kov
krll-kov requested a review from a team as a code owner September 17, 2026 06:23
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. platform-windows Building on or for Windows specifically a: desktop Running on desktop team-windows Owned by the Windows platform team labels Sep 17, 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 updates the Windows OpenGL compositor to support OpenGL ES 2.0 by introducing an internal_format field that dynamically selects between sized and unsized formats based on the detected GLES version. Unit tests are also added to verify this behavior under GLES2 and GLES3 contexts. Feedback suggests adding a defensive null check for the GLES description to prevent potential crashes, and refactoring a static std::vector in the unit tests to comply with the Google C++ Style Guide's rules on trivial destructibility.

Comment on lines +284 to +288
const impeller::DescriptionGLES* description = gl_->GetDescription();
bool is_gles2 =
description->IsES() && description->GetGlVersion().major_version < 3;
format_.internal_format =
is_gles2 ? format_.general_format : format_.sized_format;

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.

high

The gl_->GetDescription() call may return nullptr if the OpenGL context or driver description is not available or failed to initialize. Dereferencing it directly without a null check can lead to a crash. Please add a defensive null check before accessing its members.

Suggested change
const impeller::DescriptionGLES* description = gl_->GetDescription();
bool is_gles2 =
description->IsES() && description->GetGlVersion().major_version < 3;
format_.internal_format =
is_gles2 ? format_.general_format : format_.sized_format;
const impeller::DescriptionGLES* description = gl_->GetDescription();
bool is_gles2 = description &&
description->IsES() &&
description->GetGlVersion().major_version < 3;
format_.internal_format =
is_gles2 ? format_.general_format : format_.sized_format;

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.

GetDescription() cannot return null at this point, so I'd rather not add the check.

Initialize bails out when the proc table is invalid, a few lines above:

gl_ = std::make_unique<impeller::ProcTableGLES>(resolver_);
if (!gl_->IsValid()) {
gl_.reset();
return false;
}

gl_ = std::make_unique<impeller::ProcTableGLES>(resolver_);
if (!gl_->IsValid()) {
  gl_.reset();
  return false;
}

ProcTableGLES creates its description first and only becomes valid at the very end of the constructor, after the description passed its own check:

description_ = std::make_unique<DescriptionGLES>(*this);
if (!description_->IsValid()) {
return;
}

description_ = std::make_unique<DescriptionGLES>(*this);
if (!description_->IsValid()) {
  return;
}
...
is_valid_ = true;

The existing BGRA check right above the new code already dereferences it the same way:

if (gl_->GetDescription()->HasExtension("GL_EXT_texture_format_BGRA8888")) {

if (gl_->GetDescription()->HasExtension("GL_EXT_texture_format_BGRA8888")) {

Comment on lines +166 to +169
std::vector<GLint>& TexImage2DInternalFormats() {
static std::vector<GLint> internal_formats;
return internal_formats;
}

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

According to the Google C++ Style Guide, static variables must be trivially destructible. std::vector has a non-trivial destructor, which violates this rule. To comply with the style guide, allocate the vector on the heap and store a pointer to it.

Suggested change
std::vector<GLint>& TexImage2DInternalFormats() {
static std::vector<GLint> internal_formats;
return internal_formats;
}
std::vector<GLint>& TexImage2DInternalFormats() {
static std::vector<GLint>* internal_formats = new std::vector<GLint>();
return *internal_formats;
}
References
  1. According to the Google C++ Style Guide, static variables must be trivially destructible. Class templates like std::vector have non-trivial destructors and are not allowed as static variables. (link)

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.

This follows the pattern already used by the Windows embedder tests, where a captureless mock function records into a function-local or file-level static std::vector:


static std::vector<UINT> received_messages;

static std::vector<int> key_event_logs;
static std::vector<UINT> received_messages;

The mock has to be a plain function pointer for the ProcTableGLES resolver, so it cannot capture state, and the vector is cleared at the start of each test. I kept it consistent with the neighbouring tests

@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.

Looks good to me, thanks for the quick PR. Switching context's and setting up the environment to develop this PR would have taken some time. I just have some cleanup notes.


TEST_F(CompositorOpenGLTest, CreateBackingStoreGLES3Sized) {
UseHeadlessEngine();
TexImage2DInternalFormats().clear();

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.

Let's put this in TearDown() to avoid leaks between tests

return internal_formats;
}

void RecordTexImage2D(GLenum,

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.

We have a mechanism to statically assert that this signature is correct, it's probably easiest just to copy it into this file. We should unify these mocks at some point.

static_assert(CheckSameSignature<decltype(mockGetString), //

};

// ANGLE returns these strings for an OpenGL ES 2.0 context
const unsigned char* MockGetStringGLES2(GLenum name) {

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.

(same comment about static_assert's for these functions)

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

Copy link
Copy Markdown
Contributor Author

Looks good to me, thanks for the quick PR. Switching context's and setting up the environment to develop this PR would have taken some time. I just have some cleanup notes.

done

@krll-kov
krll-kov requested a review from gaaclarke September 17, 2026 17:02
@gaaclarke gaaclarke added the CICD Run CI/CD label Sep 17, 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.

LGTM, thanks!

@gaaclarke
gaaclarke requested a review from b-luk September 17, 2026 17:10
@gaaclarke

Copy link
Copy Markdown
Member

@b-luk please be a second reviewer for this.

@b-luk b-luk 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

@gaaclarke gaaclarke added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 17, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Sep 17, 2026
@auto-submit

auto-submit Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/192917, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

@gaaclarke

Copy link
Copy Markdown
Member

Some of the CI failures seem apropos:

https://ci.chromium.org/ui/p/flutter/builders/try/Linux_android_emu%20android_hardware_smoke_opengles_tests/4741/overview

+6 -1: should render and match platformViewTextureLayerTest golden [E]

  Bad state: Captured screenshot is blank/empty after 3 attempts.

  test_driver/driver_test.dart 104:9                 main.templateTest
  ===== asynchronous gap ===========================
  test_driver/driver_test.dart 144:5                 main.<fn>
  ===== asynchronous gap ===========================
  package:test_api/src/backend/declarer.dart 253:15  Declarer.test.<fn>.<fn>
  ===== asynchronous gap ===========================
  package:test_api/src/backend/declarer.dart 250:11  Declarer.test.<fn>
  ===== asynchronous gap ===========================
  package:test_api/src/backend/invoker.dart 318:9    Invoker._waitForOutstandingCallbacks.<fn>


I/PlatformViewsChannel( 5487): Using legacy platform view rendering strategy.
I/PlatformViewsController( 5487): Using hybrid composition for platform view: 1
Captured screenshot is blank/empty (attempt 1/3)
Captured screenshot is blank/empty (attempt 2/3)
Captured screenshot is blank/empty (attempt 3/3)

I'll hit rerun to make sure we aren't experiencing a flake. @krll-kov let me know if you want me to take a stab at diagnosing it deeper. There isn't much in the logs to go on.

@gaaclarke gaaclarke added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 17, 2026
@krll-kov

krll-kov commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor Author

, b> Some of the CI failures seem apropos:

https://ci.chromium.org/ui/p/flutter/builders/try/Linux_android_emu%20android_hardware_smoke_opengles_tests/4741/overview

+6 -1: should render and match platformViewTextureLayerTest golden [E]

  Bad state: Captured screenshot is blank/empty after 3 attempts.

  test_driver/driver_test.dart 104:9                 main.templateTest
  ===== asynchronous gap ===========================
  test_driver/driver_test.dart 144:5                 main.<fn>
  ===== asynchronous gap ===========================
  package:test_api/src/backend/declarer.dart 253:15  Declarer.test.<fn>.<fn>
  ===== asynchronous gap ===========================
  package:test_api/src/backend/declarer.dart 250:11  Declarer.test.<fn>
  ===== asynchronous gap ===========================
  package:test_api/src/backend/invoker.dart 318:9    Invoker._waitForOutstandingCallbacks.<fn>


I/PlatformViewsChannel( 5487): Using legacy platform view rendering strategy.
I/PlatformViewsController( 5487): Using hybrid composition for platform view: 1
Captured screenshot is blank/empty (attempt 1/3)
Captured screenshot is blank/empty (attempt 2/3)
Captured screenshot is blank/empty (attempt 3/3)

I'll hit rerun to make sure we aren't experiencing a flake. @krll-kov let me know if you want me to take a stab at diagnosing it deeper. There isn't much in the logs to go on.

Pr only touches windows files in shell/platform/windows, i'm not sure how that could affect android, but i'll try to execute that test locally

@gaaclarke

Copy link
Copy Markdown
Member

Pr only touches windows files in shell/platform/windows, i'm not sure how that could affect android, but i'll try to execute that test locally

Ah yea, I saw OpenGLES and Android and thought we triggered something. You're right. I'll keep poking at CI to try to get this past.

@krll-kov

krll-kov commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor Author

Ah yea, I saw OpenGLES and Android and thought we triggered something. You're right. I'll keep poking at CI to try to get this past.

just checked that shell/platform/windows/BUILD.gn starts with assert(is_win), so none of the changed files are compiled into the Android embedder at all. Looks like a capture flake or something that is not related to this pr

@auto-submit
auto-submit Bot added this pull request to the merge queue Sep 17, 2026
@eduardohr-muniz

Copy link
Copy Markdown

Hi! Thanks for this fix, and for #193306.

Could both be considered for a cherry-pick to the 3.47 stable branch?

Impact: We ship a Windows point-of-sale app (MSIX, Microsoft Store) built with Flutter 3.47.1. Several of our customers run it on older hardware, and on those machines the window stays completely black. The app is running fine underneath: network calls succeed, navigation happens, logs are written. Nothing is drawn, so the app is unusable for these customers.

Affected machine:

  • CPU: Intel Core i5 650 (Clarkdale, 2010)
  • GPU: Intel HD Graphics (Ironlake), driver 8.15.10.2900 (2012), WDDM 1.1
  • Max Direct3D feature level: 10_0
  • OS: Windows 10 Pro 64-bit (build 19045)

Intel publishes no newer driver for this GPU on Windows 10, so the customer cannot fix it on their side.

Why both PRs: this machine is at feature level 10_0, so it needs this PR to get past the black window (#191978), and #193306 so that Impeller does not erase content drawn before a BackdropFilter (#192918).

Current state: I checked 3.47.6 (latest stable) and 3.49.0-0.2.pre (latest beta), and neither contains this PR. Our only option today is to pin our Windows builds to 3.44.x, which also holds back the rest of the app.

This PR is small and only touches the Windows embedder, so the risk to other platforms looks low. Happy to test a candidate build on the affected hardware if that helps.

Thanks!

Rusino pushed a commit to Rusino/flutter that referenced this pull request Oct 12, 2026
…level 10_0 (flutter#194114)

Adds a parameter (only used in tests) to `egl::Manager` to cap ANGLE's
D3D11 feature level. Adds `compositor_opengl_angle_unittests.cc`, based
on
[`compositor_opengl_unittests.cc`](https://github.com/flutter/flutter/blob/97db29fcaa2aa757c8d86f06187b5268bf4eed4a/engine/src/flutter/shell/platform/windows/compositor_opengl_unittests.cc).
Unlike the existing tests, the new tests exercise the compositor with
real ANGLE instead of mocks.

The new tests exercise the compositor's backing store creation and
presenting. The tests run both at uncapped feature level and capped to
10_0. This emulates the case where
flutter#191978 resulted in a black
window.

Verified locally that when
flutter#192917 is reverted, the new
tests fail when running at feature level 10_0 and pass when running
without a feature level cap.

Part of flutter#192899:
- This PR exercises the OpenGL compositor and swapchain presenting
codepath on 10_0, verifying that the backing store framebuffer is valid
(GL_FRAMEBUFFER_COMPLETE) with no GL errors. This catches issues that
occur at the compositor level, like
flutter#191978.
- This would not catch issues where the rendering behavior of Impeller
is broken due to taking different code paths on 10_0 (e.g.
flutter#192918 resulting in different
BackdropFilter behavior because offscreen MSAA is unavailable with
10_0).
- I intend to follow up with a PR that extends our existing
[`engine_integration_golden_test.dart`](https://github.com/flutter/flutter/blob/38785ef8b19e2a1ee1303167074ec98f95f7cb5b/dev/integration_tests/engine_integration_golden_test/integration_test/engine_integration_golden_test.dart)
devicelab golden test, which currently [runs on
Windows](https://github.com/flutter/flutter/blob/38785ef8b19e2a1ee1303167074ec98f95f7cb5b/dev/devicelab/lib/tasks/integration_tests.dart#L242-L248),
to also run with feature level 10_0. These golden tests would catch
issues where our Impeller rendering is broken. Goldens do not catch
compositor level issues because the golden functionality reads its
images from Impeller, skipping the compositor portion of the rendering
pipeline.
- This PR, together with the anticipated follow up PR, will give us
basic smoke testing coverage on 10_0 of the rendering pipeline from
Flutter app code, through Impeller rendering, to presenting on the
swapchain.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant in-code documentation (doc comments with
`///`).
- [x] If this PR introduces a new feature or capability, I created and
linked a website documentation issue or PR in [flutter/website] (or
verified none is needed).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/CONTRIBUTING.ai.md
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[flutter/website]: https://github.com/flutter/website
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
@gaabrielricci

Copy link
Copy Markdown

Confirming that #192917 ("[Windows] Use an unsized texture format for backing stores on OpenGL ES 2") fixes this for us.

We built our Windows app with 3.50.0-0.1.pre (framework 07502c7, engine b890cdd), which includes that commit, and tested it with 3 users. The window renders normally for
all three; no more black screen.

Before this, 3.47.x opened black on the affected machine (Intel HD Graphics 0x8086:0x0042, 2012 driver, WDDM 1.1), while 3.44.2 worked. That matches the regression in the
OpenGL compositor's backing store format that the PR reverts to unsized.

Thanks for the fix. Is there a plan to cherry-pick it to a 3.47.x stable hotfix? Until then we're shipping from beta.

suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
…level 10_0 (flutter#194114)

Adds a parameter (only used in tests) to `egl::Manager` to cap ANGLE's
D3D11 feature level. Adds `compositor_opengl_angle_unittests.cc`, based
on
[`compositor_opengl_unittests.cc`](https://github.com/flutter/flutter/blob/97db29fcaa2aa757c8d86f06187b5268bf4eed4a/engine/src/flutter/shell/platform/windows/compositor_opengl_unittests.cc).
Unlike the existing tests, the new tests exercise the compositor with
real ANGLE instead of mocks.

The new tests exercise the compositor's backing store creation and
presenting. The tests run both at uncapped feature level and capped to
10_0. This emulates the case where
flutter#191978 resulted in a black
window.

Verified locally that when
flutter#192917 is reverted, the new
tests fail when running at feature level 10_0 and pass when running
without a feature level cap.

Part of flutter#192899:
- This PR exercises the OpenGL compositor and swapchain presenting
codepath on 10_0, verifying that the backing store framebuffer is valid
(GL_FRAMEBUFFER_COMPLETE) with no GL errors. This catches issues that
occur at the compositor level, like
flutter#191978.
- This would not catch issues where the rendering behavior of Impeller
is broken due to taking different code paths on 10_0 (e.g.
flutter#192918 resulting in different
BackdropFilter behavior because offscreen MSAA is unavailable with
10_0).
- I intend to follow up with a PR that extends our existing
[`engine_integration_golden_test.dart`](https://github.com/flutter/flutter/blob/38785ef8b19e2a1ee1303167074ec98f95f7cb5b/dev/integration_tests/engine_integration_golden_test/integration_test/engine_integration_golden_test.dart)
devicelab golden test, which currently [runs on
Windows](https://github.com/flutter/flutter/blob/38785ef8b19e2a1ee1303167074ec98f95f7cb5b/dev/devicelab/lib/tasks/integration_tests.dart#L242-L248),
to also run with feature level 10_0. These golden tests would catch
issues where our Impeller rendering is broken. Goldens do not catch
compositor level issues because the golden functionality reads its
images from Impeller, skipping the compositor portion of the rendering
pipeline.
- This PR, together with the anticipated follow up PR, will give us
basic smoke testing coverage on 10_0 of the rendering pipeline from
Flutter app code, through Impeller rendering, to presenting on the
swapchain.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant in-code documentation (doc comments with
`///`).
- [x] If this PR introduces a new feature or capability, I created and
linked a website documentation issue or PR in [flutter/website] (or
verified none is needed).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/CONTRIBUTING.ai.md
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[flutter/website]: https://github.com/flutter/website
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
@ricardordr

Copy link
Copy Markdown

Dears, is it possible to cherrypick this fix to 3.47 versions?

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

Labels

a: desktop Running on desktop CICD Run CI/CD engine flutter/engine related. See also e: labels. platform-windows Building on or for Windows specifically team-windows Owned by the Windows platform team

Projects

None yet

6 participants