Skip to content

[Impeller] Retire Y-coord-scale plumbing by flipping GLES at the vertex stage#186556

Merged
auto-submit[bot] merged 12 commits into
flutter:masterfrom
bdero:bdero/impeller-y-flip
May 26, 2026
Merged

[Impeller] Retire Y-coord-scale plumbing by flipping GLES at the vertex stage#186556
auto-submit[bot] merged 12 commits into
flutter:masterfrom
bdero:bdero/impeller-y-flip

Conversation

@bdero
Copy link
Copy Markdown
Member

@bdero bdero commented May 15, 2026

Resolves #186554.

Absorbs OpenGL ES's render-to-texture Y-axis difference once, at the GLES backend, so that render-to-texture content is stored top-down on every backend (matching Metal and Vulkan). This is the same shape wgpu/ANGLE/Tint use. See linked issue for the full background. :)

Injects uniform float _impeller_y_flip & gl_Position.y *= _impeller_y_flip into GLES vertex shaders, and automatically populates with -1.0 & flips the winding order when rendering to an offscreen texture.

No call-site changes here. The existing ~20 texture_sampler_y_coord_scale / src_y_coord_scale plumbing sites in impeller/entity/contents/... carry the value 1.0 (the new GetYCoordScale()), their shader expressions reduce to uv.y = uv.y, and the dead branches drop out at optimization.

I'll send a follow-up PR to remove all the old GetYCoordScale() plumbing once this lands.

Pre-launch Checklist

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label May 15, 2026
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. e: impeller Impeller rendering backend issues and features requests flutter-gpu team-fluttergpu Owned by Flutter GPU team labels May 15, 2026
@github-project-automation github-project-automation Bot moved this to 🤔 Needs Triage in Flutter GPU May 15, 2026
@bdero bdero force-pushed the bdero/impeller-y-flip branch from 41a977f to 1decf43 Compare May 15, 2026 03:18
@github-actions github-actions Bot removed flutter-gpu team-fluttergpu Owned by Flutter GPU team CICD Run CI/CD labels May 15, 2026
@bdero bdero added the CICD Run CI/CD label May 15, 2026
@bdero bdero force-pushed the bdero/impeller-y-flip branch from 1decf43 to 08c120c Compare May 15, 2026 03:29
@github-actions github-actions Bot removed the CICD Run CI/CD label May 15, 2026
@bdero bdero added the CICD Run CI/CD label May 15, 2026
@bdero bdero force-pushed the bdero/impeller-y-flip branch from 08c120c to 1926c63 Compare May 15, 2026 04:35
@github-actions github-actions Bot removed the CICD Run CI/CD label May 15, 2026
@bdero bdero added the CICD Run CI/CD label May 15, 2026
…ex stage (initial MVP)

Implements the design from flutter#186554:
absorb the OpenGL ES render-to-texture Y orientation difference once, in
impellerc plus RenderPassGLES, so render-to-texture content is now stored
top-down on every backend.

* impellerc (compiler.cc): for vertex shaders compiled for any GL target
  (kOpenGLES / kOpenGLDesktop / kRuntimeStageGLES / kRuntimeStageGLES3),
  inject a hidden `uniform float _impeller_y_flip;` declaration and a
  matching `gl_Position.y *= _impeller_y_flip;` epilogue at the end of
  main(). Sits naturally in CreateGLSLCompiler's existing
  spirv-cross-emission stage, alongside the already-enabled
  `sl_options.vertex.fixup_clipspace = true;` knob.

* RenderPassGLES (render_pass_gles.cc): determine flip_y per pass from
  `is_wrapped_fbo` (swapchain -> +1.0, offscreen FBO -> -1.0), write the
  uniform after every pipeline.BindProgram, invert the front-face
  winding state in lockstep when flipping, and switch the viewport /
  scissor Y math to the unflipped form for FBO renders (the existing
  `target_h - y - h` math is preserved for the swapchain so on-screen
  rendering is unchanged).

* TextureGLES::GetYCoordScale: always returns 1.0 now. With the
  vertex-stage flip in place, GLES render-to-texture content is stored
  top-down at the GL framebuffer level. The existing per-site
  `texture_sampler_y_coord_scale` plumbing across the ~20 entity-
  contents and filter sites carries the value 1.0 and reduces to no-ops,
  no source changes needed at the call sites. They get retired in a
  follow-up.
@bdero bdero force-pushed the bdero/impeller-y-flip branch from 1926c63 to 1d950a7 Compare May 15, 2026 04:46
@github-actions github-actions Bot removed the CICD Run CI/CD label May 15, 2026
@bdero bdero added the CICD Run CI/CD label May 15, 2026
@github-actions github-actions Bot removed the CICD Run CI/CD label May 15, 2026
@bdero bdero added the CICD Run CI/CD label May 15, 2026
@bdero bdero requested a review from gaaclarke May 15, 2026 16:53
@bdero bdero marked this pull request as ready for review May 15, 2026 16:53
Copy link
Copy Markdown
Contributor

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

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 implements a vertex-stage Y-flip for GLES offscreen FBO passes to maintain top-down coordinate consistency. Changes include the injection of a hidden _impeller_y_flip uniform into vertex shaders, adjustments to viewport and scissor calculations, and the inversion of winding orders during flipped passes. Review feedback identifies a performance bottleneck caused by querying uniform locations within the command loop and suggests a more robust approach for shader injection to handle early returns and improve parsing reliability.

Comment thread engine/src/flutter/impeller/renderer/backend/gles/render_pass_gles.cc Outdated
Comment on lines +50 to +75
std::string InjectYFlipForGLESVertexShader(std::string source) {
// Scan main()'s body tracking brace depth to find its closing `}`.
const std::string epilogue =
std::string(" gl_Position.y *= ") + kYFlipUniformName + ";\n";

const size_t main_pos = source.find("void main");
if (main_pos == std::string::npos) {
return source;
}
const size_t open_brace = source.find('{', main_pos);
if (open_brace == std::string::npos) {
return source;
}
int depth = 1;
for (size_t i = open_brace + 1; i < source.size(); ++i) {
const char c = source[i];
if (c == '{') {
++depth;
} else if (c == '}') {
--depth;
if (depth == 0) {
source.insert(i, epilogue);
break;
}
}
}
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

The current implementation of InjectYFlipForGLESVertexShader uses simple string matching and brace counting to append the Y-flip logic to the end of main(). This approach has two potential issues:

  1. Early Returns: If the vertex shader contains return statements, the flip logic will be bypassed for those execution paths, leading to incorrectly oriented rendering.
  2. Robustness: Searching for void main and counting braces can be fragile if the substring appears in comments or if there are complex nested blocks.

Consider a more robust approach, such as wrapping the original main function (e.g., renaming it and calling it from a new main) or using SPIRV-Cross's AST manipulation capabilities if possible.

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.

Both of the suggestions, creating a new main and editing the AST sound like good ideas, did you consider those?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah very true about the early returns... I ended up doing a simple main wrapping solution as suggested. I also explored:

  • Injecting statements with spirv-cross. Turns out it'd require calling internal stuff that's not exposed on their external API, so it may break badly at some point while updating if we take that route. I remember us running up against this during past exploration too, which is why we ended up doing string hacking/preprocessing for some other stuff as well.
  • Manipulating the SPIRV IR to insert these inputs/logic. Was excited at the potential for this, but it turned out to be super complicated/fragile/difficult to understand. 100s of lines of code to get the ~10 low level ops that we'd need this.

Copy link
Copy Markdown
Member

@gaaclarke gaaclarke left a comment

Choose a reason for hiding this comment

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

Injecting this into the vertex shaders sounds great to me. I think the injection is somewhat fragile, gemini had some suggestions that are worth considering. There are also some goldens that look wrong worth investigating: https://flutter-gold.skia.org/search?issue=186556&crs=github&patchsets=1&corpus=flutter

Comment on lines +50 to +75
std::string InjectYFlipForGLESVertexShader(std::string source) {
// Scan main()'s body tracking brace depth to find its closing `}`.
const std::string epilogue =
std::string(" gl_Position.y *= ") + kYFlipUniformName + ";\n";

const size_t main_pos = source.find("void main");
if (main_pos == std::string::npos) {
return source;
}
const size_t open_brace = source.find('{', main_pos);
if (open_brace == std::string::npos) {
return source;
}
int depth = 1;
for (size_t i = open_brace + 1; i < source.size(); ++i) {
const char c = source[i];
if (c == '{') {
++depth;
} else if (c == '}') {
--depth;
if (depth == 0) {
source.insert(i, epilogue);
break;
}
}
}
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.

Both of the suggestions, creating a new main and editing the AST sound like good ideas, did you consider those?

… brace counting

Two changes addressing gemini's review and gaaclarke's reply:

1. **Cache `_impeller_y_flip` location at link time** (gemini high-priority).
   `PipelineGLES::BuildVertexDescriptor` now resolves the uniform once via
   `glGetUniformLocation` and stashes it in `y_flip_uniform_location_`.
   `RenderPassGLES` reads it through the new
   `PipelineGLES::GetYFlipUniformLocation()` getter instead of calling
   `glGetUniformLocation` for every command in the inner loop. -1 still
   means "not present" (fragment-only program, no injection, etc.) and
   skips the write. Net: one location query per pipeline link, zero per
   draw.

2. **Wrap `main` instead of brace-counting an epilogue** (gemini medium,
   gaaclarke seconded). `InjectYFlipForGLESVertexShader` now renames the
   SPIRV-Cross-emitted `void main(` to `void _impeller_user_main(` and
   appends a fresh `main()` that calls the renamed user entry point and
   applies `gl_Position.y *= _impeller_y_flip;` afterward. The wrap
   pattern makes the flip run on every control-flow exit including early
   `return`s (gemini's first concern), and the rename anchored on
   `\nvoid main(` in spirv-cross's mechanical, comment-free output is
   unambiguous (gemini's second concern). A SPIRV-Cross
   `SPIRFunction::fixup_hooks_out` based approach was investigated but
   needs subclassing CompilerGLSL to reach protected emit machinery;
   leaving that as a future cleanup.

New test `YFlipInjectionHandlesEarlyReturnsInGLESVertexShader` uses a new
`y_flip_early_return.vert` fixture (an `if (...) { ...; return; }` path
before the implicit final return) and asserts the wrapper exists, calls
the renamed user entry, and is the only remaining `void main(` in the
emitted source.
bdero added a commit to bdero/flutter_scene that referenced this pull request May 25, 2026
flutter_scene (like Impeller's Metal/Vulkan backends) assumes render-to-
texture content is stored top-down. Impeller's OpenGL ES backend stores it
bottom-up, and the upstream fix that makes GLES match (flutter/flutter#186556)
is not yet in the engines we build against, so flutter_scene rendered upside
down on native GLES (e.g. Linux desktop, headless CI).

Absorb the difference in flutter_scene as a temporary workaround, gated on a
GL-backend proxy (no offscreen-MSAA support; Flutter GPU exposes no backend
query). New src/render/y_flip.dart:
- negates gl_Position.y in every offscreen pass (matrix premultiply for the
  matrix-based scene/shadow passes; a FlipInfo uniform for the full-screen
  tonemap/prefilter passes), storing targets top-down;
- inverts cull winding to compensate (the Y negation reverses screen winding);
- so the existing render-target sampling flips become the top-down value on
  every backend (tonemap flip_y 0.0, render_target_flip_y 1.0).

Gated off for Metal/Vulkan and the WebGL2 shim (which does its own flip), so
those paths are byte-identical (verified on macOS/Metal and web). TODO: remove
once the GLES top-down fix lands upstream; see the note in y_flip.dart.
bdero added a commit to bdero/flutter_scene that referenced this pull request May 25, 2026
flutter_scene (like Impeller's Metal/Vulkan backends) assumes render-to-
texture content is stored top-down. Impeller's OpenGL ES backend stores it
bottom-up, and the upstream fix that makes GLES match (flutter/flutter#186556)
is not yet in the engines we build against, so flutter_scene rendered upside
down on native GLES (e.g. Linux desktop, headless CI).

Absorb the difference in flutter_scene as a temporary workaround, gated on a
GL-backend proxy (no offscreen-MSAA support; Flutter GPU exposes no backend
query). New src/render/y_flip.dart:
- negates gl_Position.y in every offscreen pass (matrix premultiply for the
  matrix-based scene/shadow passes; a FlipInfo uniform for the full-screen
  tonemap/prefilter passes), storing targets top-down;
- inverts cull winding to compensate (the Y negation reverses screen winding);
- so the existing render-target sampling flips become the top-down value on
  every backend (tonemap flip_y 0.0, render_target_flip_y 1.0).

Gated off for Metal/Vulkan and the WebGL2 shim (which does its own flip), so
those paths are byte-identical (verified on macOS/Metal and web). TODO: remove
once the GLES top-down fix lands upstream; see the note in y_flip.dart.
@bdero bdero added the autosubmit Merge PR when tree becomes green via auto submit App label May 25, 2026
@auto-submit auto-submit Bot added this pull request to the merge queue May 26, 2026
Merged via the queue into flutter:master with commit 475014b May 26, 2026
206 checks passed
@github-project-automation github-project-automation Bot moved this from 🤔 Needs Triage to ✅ Done in Flutter GPU May 26, 2026
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label May 26, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request May 26, 2026
Roll Flutter from e03b91f1fe34 to f3a4b9897834 (63 revisions)

flutter/flutter@e03b91f...f3a4b98

2026-05-26 47866232+chunhtai@users.noreply.github.com Update batch release doc to reflect latest workflow (flutter/flutter#186979)
2026-05-26 engine-flutter-autoroll@skia.org Roll Skia from 0442274cc696 to 27a819894f7c (5 revisions) (flutter/flutter#187094)
2026-05-26 bkonyi@google.com [Tool Robustness] Gracefully handle asynchronous subprocess crashes and connection timeouts (flutter/flutter#186964)
2026-05-26 bkonyi@google.com [pubspec] Bump Dart SDK constraint to ^3.13.0 (flutter/flutter#186957)
2026-05-26 engine-flutter-autoroll@skia.org Roll Dart SDK from 7eb54169841d to 00e625453c43 (1 revision) (flutter/flutter#187086)
2026-05-26 bdero@google.com [Impeller] Retire Y-coord-scale plumbing by flipping GLES at the vertex stage (flutter/flutter#186556)
2026-05-26 engine-flutter-autoroll@skia.org Roll Skia from f4f294bdf98d to 0442274cc696 (2 revisions) (flutter/flutter#187079)
2026-05-26 kevmoo@users.noreply.github.com [flutter_tools] Fix version cache poisoning from git environment variables (flutter/flutter#186595)
2026-05-26 bkonyi@google.com [Tool] Handle DTD connection failures gracefully in widget-preview (flutter/flutter#186952)
2026-05-25 engine-flutter-autoroll@skia.org Roll Skia from 9d1adb5f2427 to f4f294bdf98d (1 revision) (flutter/flutter#187056)
2026-05-25 engine-flutter-autoroll@skia.org Roll Skia from 4dd78179e6ec to 9d1adb5f2427 (1 revision) (flutter/flutter#187048)
2026-05-25 engine-flutter-autoroll@skia.org Roll Skia from 1f26101197bf to 4dd78179e6ec (4 revisions) (flutter/flutter#187044)
2026-05-24 engine-flutter-autoroll@skia.org Roll Skia from bbe9ccc2bdbf to 1f26101197bf (1 revision) (flutter/flutter#187016)
2026-05-24 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from nsgcNDlZOuweOvy3Q... to Itd2Jq_ZIABH2rW7B... (flutter/flutter#187032)
2026-05-23 engine-flutter-autoroll@skia.org Roll Dart SDK from 7e0f28eb5315 to 7eb54169841d (1 revision) (flutter/flutter#187005)
2026-05-23 engine-flutter-autoroll@skia.org Roll Dart SDK from 90e55fa88456 to 7e0f28eb5315 (1 revision) (flutter/flutter#186990)
2026-05-23 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from 6T6BY9PTftoG3vP_1... to nsgcNDlZOuweOvy3Q... (flutter/flutter#186984)
2026-05-23 chris@bracken.jp iOS] Migrate VSyncClient to a pure Obj-C implementation (#186166) (flutter/flutter#186935)
2026-05-23 30870216+gaaclarke@users.noreply.github.com Disables embedder_tests.cm for fuchsia (flutter/flutter#186969)
2026-05-23 engine-flutter-autoroll@skia.org Roll Dart SDK from b8414c46f6c7 to 90e55fa88456 (2 revisions) (flutter/flutter#186977)
2026-05-22 engine-flutter-autoroll@skia.org Roll Skia from 6fdb013d1953 to bbe9ccc2bdbf (1 revision) (flutter/flutter#186980)
2026-05-22 mdebbar@google.com [web] Fix cutoff text in WebParagraph (flutter/flutter#186819)
2026-05-22 1961493+harryterkelsen@users.noreply.github.com fix(web): Removes the iterative downscaling hack (flutter/flutter#186914)
2026-05-22 30870216+gaaclarke@users.noreply.github.com opts the linux embedder into sdf rendering (flutter/flutter#186909)
2026-05-22 engine-flutter-autoroll@skia.org Roll Skia from dae8778ca40d to 6fdb013d1953 (5 revisions) (flutter/flutter#186970)
2026-05-22 dacoharkes@google.com Fix hooks inputs outputs rebuilt (flutter/flutter#186701)
2026-05-22 30870216+gaaclarke@users.noreply.github.com adds linux impeller integration test for external textures (flutter/flutter#186759)
2026-05-22 kevmoo@users.noreply.github.com fix(flutter_tools): defensively catch DWDS unregistered service extension errors (flutter/flutter#186896)
2026-05-22 bdero@google.com [Impeller] Add golden harness support to the renderer test layer (flutter/flutter#186735)
2026-05-22 mdebbar@google.com [web] Remove image codecs from canvaskit_chromium (flutter/flutter#178133)
2026-05-22 30870216+gaaclarke@users.noreply.github.com opts all macos into wide gamut (flutter/flutter#186277)
2026-05-22 engine-flutter-autoroll@skia.org Roll Skia from 356185490a75 to dae8778ca40d (9 revisions) (flutter/flutter#186949)
2026-05-22 1598289+lukemmtt@users.noreply.github.com Filter out SwiftPM schemes when fetching schemes (flutter/flutter#186006)
2026-05-22 engine-flutter-autoroll@skia.org Roll Packages from 3754d04 to 69cf959 (1 revision) (flutter/flutter#186950)
2026-05-22 engine-flutter-autoroll@skia.org Roll Dart SDK from eca46bec956d to b8414c46f6c7 (2 revisions) (flutter/flutter#186944)
2026-05-22 30870216+gaaclarke@users.noreply.github.com Saves a DeviceHolderVK with the CommandPoolVK (flutter/flutter#186749)
2026-05-22 engine-flutter-autoroll@skia.org Roll Dart SDK from e0d509fd676e to eca46bec956d (1 revision) (flutter/flutter#186922)
2026-05-22 bkonyi@google.com [ Tool ] Stop generating widget preview scaffold under $TMP (flutter/flutter#186476)
2026-05-21 737941+loic-sharma@users.noreply.github.com Fix typo in StretchingOverscrollIndicator docs (flutter/flutter#186897)
2026-05-21 engine-flutter-autoroll@skia.org Roll Dart SDK from 28c7cb5a8e8d to e0d509fd676e (1 revision) (flutter/flutter#186903)
2026-05-21 jason-simmons@users.noreply.github.com Fix some issues in the integration between EmbedderExternalViewEmbedder and Impeller (flutter/flutter#184905)
2026-05-21 jason-simmons@users.noreply.github.com Fix a potential buffer overflow in the animated PNG decoder when parsing malformed fdAT chunks (flutter/flutter#186700)
2026-05-21 engine-flutter-autoroll@skia.org Roll Skia from 2ff20950975d to 356185490a75 (5 revisions) (flutter/flutter#186892)
2026-05-21 flar@google.com Add primitive shadows to rendering benchmark (flutter/flutter#186779)
2026-05-21 15619084+vashworth@users.noreply.github.com Move prefetchSwiftPackages to be per platform (flutter/flutter#186468)
2026-05-21 okorohelijah@google.com Upgrade iOS version (flutter/flutter#186889)
...
@bdero bdero deleted the bdero/impeller-y-flip branch May 27, 2026 04:09
@gaaclarke
Copy link
Copy Markdown
Member

@bdero we need to update the guidance in https://docs.flutter.dev/ui/design/graphics/fragment-shaders too.

@gaaclarke
Copy link
Copy Markdown
Member

@bdero I thought we had a function that abstracted this away which essentially became a noop after your change? I guess I must have dreamed it up.

pull Bot pushed a commit to Hawthorne001/flutter that referenced this pull request May 29, 2026
GOODNIGHT, SWEET PRINCE.

No semantic change, baby.

Follow-up to flutter#186556 (and its tracking issue flutter#186554), where I
deprecated one of the worst landmines in Impeller by absorbing OpenGL
ES's Y-axis difference into the vertex stage and pinned
`Texture::GetYCoordScale()` to 1.0. Every call site is now passing 1.0
and every `IPRemapCoords` call reduces to identity, so this PR removes
the cruft. :)

## 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 documentation (doc comments with `///`).
- [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.
- [ ] All existing and new tests are passing.

<!-- 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/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[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/
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
@bdero
Copy link
Copy Markdown
Member Author

bdero commented May 29, 2026

@bdero I thought we had a function that abstracted this away which essentially became a noop after your change? I guess I must have dreamed it up.

@gaaclarke Hmm, I think the ImageFilter piece may have happened after my time. For the non-ImageFilter FragmentProgram case we didn't have to worry about the GLES y-flip problem because I don't think there was any way for a user to sample from a render target texture.

Maybe we should just get rid of (or rename) FragmentProgram's backend-specific IMPELLER_TARGET_* defines (but keep IMPELLER_GRAPHICS_BACKEND and SKIA_GRAPHICS_BACKEND for runtime_effect.glsl) so that users who employed this hack won't be impacted.

@gaaclarke
Copy link
Copy Markdown
Member

Maybe we should just get rid of (or rename) FragmentProgram's backend-specific IMPELLER_TARGET_* defines (but keep IMPELLER_GRAPHICS_BACKEND and SKIA_GRAPHICS_BACKEND for runtime_effect.glsl) so that users who employed this hack won't be impacted.

We can't remove it, we use it in other places like math.glsl and transform.glsl

jason-simmons added a commit to jason-simmons/flutter that referenced this pull request May 29, 2026
…t shader now that it is no longer required by the Impeller GLES back end

flutter#186556 makes the behavior of
the Y axis in the GLES back end consistent with other Impeller back
ends.  Shaders will render incorrectly if they continue to flip
the Y axis based on "#ifdef IMPELLER_TARGET_OPENGLES".
@bdero
Copy link
Copy Markdown
Member Author

bdero commented May 29, 2026

Ah right... that's another trend I started and now regret. We should probably just have impellerc automatically handle these differences and perform the type rewrites/function shims automatically when the backends differ.

mboetger pushed a commit to mboetger/flutter that referenced this pull request May 29, 2026
…t shader now that it is no longer required by the Impeller GLES back end (flutter#187247)

flutter#186556 makes the behavior of the
Y axis in the GLES back end consistent with other Impeller back ends.
Shaders will render incorrectly if they continue to flip the Y axis
based on "#ifdef IMPELLER_TARGET_OPENGLES".
pull Bot pushed a commit to AbhiShake1/flutter that referenced this pull request Jun 3, 2026
…87316)

flutter#186556 was a breaking change
that removed the necessity of flipping y coordinates when sampling in
opengles. This was a good improvement but it left fragment shader api
users in a prediciment where they had to bump their required flutter
SDK. This was particularly unfortunate timing for the framework team's
releases. This new temporary macro allows people to author shaders that
support flutter 3.44.0 and above.

## before
```glsl
void main() {
  vec2 uv = FlutterFragCoord().xy / u_size;
#ifdef IMPELLER_TARGET_OPENGLES
  uv.y = 1.0 - uv.y;
#endif
  fragColor = texture(u_texture, uv);
}
```

## after (support > 3.44.0)
```glsl
void main() {
  vec2 uv = FlutterFragCoord().xy / u_size;
  fragColor = texture(u_texture, uv);
}
```

## after (support >= 3.44.0)
```glsl
void main() {
  vec2 uv = FlutterFragCoord().xy / u_size;
#if defined(IMPELLER_TARGET_OPENGLES) && !defined(IMPELLER_OPENGLES_UNFLIPPED_DEPRECATED)
  uv.y = 1.0 - uv.y;
#endif
  fragColor = texture(u_texture, uv);
}
```
## 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 documentation (doc comments with `///`).
- [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/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[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
[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
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. will affect goldens Changes to golden files

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

[Impeller] Retire Y-coord-scale plumbing by flipping GLES at the vertex stage

4 participants