Skip to content

[Flutter GPU] Add explicit draw counts#186639

Merged
bdero merged 2 commits into
flutter:masterfrom
bdero:bdero/flutter-gpu-draw-api
May 27, 2026
Merged

[Flutter GPU] Add explicit draw counts#186639
bdero merged 2 commits into
flutter:masterfrom
bdero:bdero/flutter-gpu-draw-api

Conversation

@bdero

@bdero bdero commented May 17, 2026

Copy link
Copy Markdown
Member

Moves the vertex and index count off the buffer-binding calls and onto the draw call.

A simple (breaking) change that fixes a very silly design flaw that I built into the API near the very beginning. Moves Flutter GPU draws towards a design that matches virtually all modern graphics APIs, including today's Impeller!
Now is the right time to make changes like this to Flutter GPU, since the API is not yet considered stable.

Before, bindVertexBuffer and bindIndexBuffer each took a count, and a single argument-less draw() guessed vertex versus index based on whether an index buffer happened to be bound.

Sooooo many reasons this was the wrong design:

  • Wrong object. A draw count belongs on the draw, not on a buffer binding.
  • Implicit kind. Indexed vs. non-indexed was inferred from what happened to be bound, not stated.
  • Colliding counts. Vertex and index counts shared one field; the vertex count was dropped when an index buffer was bound.
  • Slot-0-only. The count came from vertex slot 0; values on other slots were silently ignored.
  • Opaque draws. draw() told you nothing; you had to trace every bind to know what it drew.
  • Sticky state. The count leaked across draws in a pass.
  • Redundant re-binds. Changing only the count forced re-binding the buffer.
  • No room to grow. Nowhere natural for per-draw params like instanceCount or baseVertex.
  • Unconventional. WebGPU, Vulkan, Metal, and D3D all put counts on the draw.
  • Late errors. Bad counts failed at draw() time, far from the mistaken line.

Now:

  • bindVertexBuffer and bindIndexBuffer only bind buffers.
  • draw(vertexCount) does a non-indexed draw.
  • drawIndexed(indexCount) does an indexed draw.

Instanced draws can be landed later via draw and drawIndexed gaining an instanceCount parameter later on, assuming the Impeller-side instancing support in #186653 lands.

Pre-launch Checklist

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label May 17, 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 17, 2026
@github-project-automation github-project-automation Bot moved this to 🤔 Needs Triage in Flutter GPU May 17, 2026
@fluttergithubbot

Copy link
Copy Markdown
Contributor

An existing Git SHA, 32015b673360111432f7f9ee8eb0edd1da7f8fbe, was detected, and no actions were taken.

To re-trigger presubmits after closing or re-opeing a PR, or pushing a HEAD commit (i.e. with --force) that already was pushed before, push a blank commit (git commit --allow-empty -m "Trigger Build") or rebase to continue.

@bdero bdero force-pushed the bdero/flutter-gpu-draw-api branch from 32015b6 to ed965e1 Compare May 17, 2026 22:54
@github-actions github-actions Bot removed the CICD Run CI/CD label May 17, 2026
@bdero bdero changed the title [Flutter GPU] Add instanced draws and explicit draw counts [Flutter GPU] Add explicit draw counts May 17, 2026
@bdero bdero marked this pull request as ready for review May 18, 2026 01:16

@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 refactors the Flutter GPU API by moving vertex and index count parameters from the binding methods, such as bindVertexBuffer and bindIndexBuffer, to the draw and drawIndexed methods. These changes are reflected across the Dart API, the C++ implementation, and the native bindings. Feedback suggests strengthening input validation by replacing asserts with RangeError.checkNotNegative in the Dart public API and adding explicit non-negative checks in the C++ layer to prevent potential integer overflow issues when casting signed integers to size_t.

Comment thread engine/src/flutter/lib/gpu/render_pass.cc
Comment thread engine/src/flutter/lib/gpu/render_pass.cc
Comment thread engine/src/flutter/lib/gpu/lib/src/render_pass.dart Outdated
Comment thread engine/src/flutter/lib/gpu/lib/src/render_pass.dart Outdated
@bdero bdero force-pushed the bdero/flutter-gpu-draw-api branch from ed965e1 to 2705bf3 Compare May 18, 2026 01:34
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label May 18, 2026
@bdero bdero force-pushed the bdero/flutter-gpu-draw-api branch from 2705bf3 to 6db9ef3 Compare May 18, 2026 04:23
@github-actions github-actions Bot removed the CICD Run CI/CD label May 18, 2026
@bdero bdero added the CICD Run CI/CD label May 18, 2026
@bdero bdero requested a review from gaaclarke May 18, 2026 04:42
wolfenrain
wolfenrain previously approved these changes May 18, 2026
@bdero bdero added the autosubmit Merge PR when tree becomes green via auto submit App label May 18, 2026
@bdero

bdero commented May 19, 2026

Copy link
Copy Markdown
Member Author

FYI @gaaclarke, just realized we technically need Googler review on every PR due to the Google testing requirement. 🙃

@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label May 19, 2026
@auto-submit

auto-submit Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/186639, because Pull request flutter/flutter/186639 is not in a mergeable state.

@gaaclarke gaaclarke requested review from walley892 and removed request for gaaclarke May 19, 2026 16:18
@gaaclarke

Copy link
Copy Markdown
Member

@bdero I'm going to let @walley892 handle this one.

walley892
walley892 previously approved these changes May 19, 2026

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

@bdero, LGTM as is and I agree that this more closely matches other graphics APIs.

I'm not super familiar with this part of the codebase, so I left some questions.

const std::shared_ptr<const impeller::DeviceBuffer>& buffer,
int offset_in_bytes,
int length_in_bytes,
int vertex_count,

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.

No action - but it looks like this was always unused?

@bdero bdero May 19, 2026

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.

This was read on line 361 (for slot 0 only 🙃)

RangeError.checkNotNegative(vertexCount, 'vertexCount');
_validateVertexBindings();
if (!_draw(vertexCount)) {
throw Exception("Failed to append draw");

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.

Is there any possibility/value in bubbling up more descriptive error messages? For example, if I try to use a negative vertexCount - will the only error be Failed to append draw, or is there some other logging inside of flutter_gpu that emits more specific errors?

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.

We do most of these kinds of checks on the Dart API surface today rather than lower down. In this case, just above here there's a RangeError.checkNotNegative line. But we don't catch everything, and it's possible to use the API in invalid ways today that can trigger impeller asserts.

But at some point, I'd like to propose a way to gracefully fail encoding and bubble up Impeller's underlying validation errors for the Flutter GPU case and such.

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.

Issue to improve the error handling situation here: #186768

render_pass_->SetScissor(scissor.value());
}

bool result = render_pass_->Draw().ok();

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.

Following my other comment, I see this just returns a bool and not a status object - are detailed failures emitted anywhere?

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.

Added a followup here #186768

@github-actions github-actions Bot removed the CICD Run CI/CD label May 26, 2026
@bdero bdero added CICD Run CI/CD autosubmit Merge PR when tree becomes green via auto submit App labels May 26, 2026
@auto-submit

auto-submit Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

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

  • The status or check suite Mac web_tool_tests has failed. Please fix the issues identified (or deflake) before re-applying this label.

@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label May 26, 2026
@bdero bdero added this pull request to the merge queue May 27, 2026
Merged via the queue into flutter:master with commit c5190fa May 27, 2026
207 checks passed
@bdero bdero deleted the bdero/flutter-gpu-draw-api branch May 27, 2026 05:45
@github-project-automation github-project-automation Bot moved this from 🤔 Needs Triage to ✅ Done in Flutter GPU May 27, 2026
@cbracken

Copy link
Copy Markdown
Member

Reason for revert: doesn't compile on mac, or Linux.

Mac:

../../flutter/testing/dart/gpu_shader_reload_test.dart:64:36: Error: Too many positional arguments: 1 allowed, but 2 found.
Try removing the extra positional arguments.
  state.renderPass.bindVertexBuffer(
                                   ^
../../flutter/testing/dart/gpu_shader_reload_test.dart:72:24: Error: Too few positional arguments: 1 required, 0 given.
  state.renderPass.draw();

Linux:

[5064/6842] ACTION //flutter/testing/dart:compile_gpu_shader_reload_test.dart(//build/toolchain/linux:clang_x64)
FAILED: gen/gpu_shader_reload_test.dart.dill 
vpython3 ../../../build/gn_run_binary.py ../../../flutter/prebuilts/linux-x64/dart-sdk/bin/dartaotruntime /b/s/w/ir/cache/builder/engine/src/out/ci/host_release_benchmarks/gen/frontend_server_aot.dart.snapshot -DkFlutterSrcDirectory=/b/s/w/ir/cache/builder/engine/src/flutter -DkFlutterBuildDirectory=/b/s/w/ir/cache/builder/engine/src/out/ci/host_release_benchmarks/gen -DkSkiaGoldWorkDirectory=/b/s/w/ir/cache/builder/engine/src/out/ci/host_release_benchmarks/gen/skia_gold_gpu_shader_reload_test.dart --packages /b/s/w/ir/cache/builder/engine/src/flutter/.dart_tool/package_config.json --sdk-root flutter_patched_sdk --target=flutter --depfile gen/gpu_shader_reload_test.dart.dill.d --output-dill gen/gpu_shader_reload_test.dart.dill ../../../flutter/testing/dart/gpu_shader_reload_test.dart
Command failed: ./../../../flutter/prebuilts/linux-x64/dart-sdk/bin/dartaotruntime /b/s/w/ir/cache/builder/engine/src/out/ci/host_release_benchmarks/gen/frontend_server_aot.dart.snapshot -DkFlutterSrcDirectory=/b/s/w/ir/cache/builder/engine/src/flutter -DkFlutterBuildDirectory=/b/s/w/ir/cache/builder/engine/src/out/ci/host_release_benchmarks/gen -DkSkiaGoldWorkDirectory=/b/s/w/ir/cache/builder/engine/src/out/ci/host_release_benchmarks/gen/skia_gold_gpu_shader_reload_test.dart --packages /b/s/w/ir/cache/builder/engine/src/flutter/.dart_tool/package_config.json --sdk-root flutter_patched_sdk --target=flutter --depfile gen/gpu_shader_reload_test.dart.dill.d --output-dill gen/gpu_shader_reload_test.dart.dill ../../../flutter/testing/dart/gpu_shader_reload_test.dart
exitCode: 254
result 341449f6-a0e5-4e2b-8f52-4cab34a8338f
../../../flutter/testing/dart/gpu_shader_reload_test.dart:64:36: Error: Too many positional arguments: 1 allowed, but 2 found.
Try removing the extra positional arguments.
  state.renderPass.bindVertexBuffer(
                                   ^
../../../flutter/testing/dart/gpu_shader_reload_test.dart:72:24: Error: Too few positional arguments: 1 required, 0 given.
  state.renderPass.draw();
                       ^

@cbracken cbracken added revert Autorevert PR (with "Reason for revert:" comment) and removed CICD Run CI/CD labels May 27, 2026
@cbracken

cbracken commented May 27, 2026

Copy link
Copy Markdown
Member

Looks like this was added to the merge queue even though presubmits identified a breakage. (I didn't check if it was the same breakage).

Not blaming anyone. I click the "merge when ready" button too, but I always assumed it would NOT merge if presubmits failed. Apparently not. That's a bit surprising.

@auto-submit auto-submit Bot removed the revert Autorevert PR (with "Reason for revert:" comment) label May 27, 2026
@cbracken

Copy link
Copy Markdown
Member

@bdero sorry for the revert. Ran into this locally when testing a PR of mine then noticed the bots were sad too. :/

I always feel bad about these but it'll get the tree green for round two.

pull Bot pushed a commit to AbhiShake1/flutter that referenced this pull request May 27, 2026
…utter#187170)

<!-- start_original_pr_link -->
Reverts: flutter#186639
<!-- end_original_pr_link -->
<!-- start_initiating_author -->
Initiated by: cbracken
<!-- end_initiating_author -->
<!-- start_revert_reason -->
Reason for reverting: doesn't compile on mac, or Linux.

Mac:
```
../../flutter/testing/dart/gpu_shader_reload_test.dart:64:36: Error: Too many positional arguments: 1 allowed, but 2 found.
Try removing the extra positional arguments.
  state.renderPass.bindVertexBuffer(
                                   ^
../../flutter/testing/dart/gpu_shader_reload_test.dart:72:24: Error: Too few positional arguments: 1 requ
<!-- end_revert_reason -->
<!-- start_original_pr_author -->
Original PR Author: bdero
<!-- end_original_pr_author -->

<!-- start_reviewers -->
Reviewed By: {walley892}
<!-- end_reviewers -->

<!-- start_revert_body -->
This change reverts the following previous change:
Moves the vertex and index count off the buffer-binding calls and onto the draw call.

A simple (breaking) change that fixes a very silly design flaw that I built into the API near the very beginning. Moves Flutter GPU draws towards a design that matches virtually all modern graphics APIs, including today's Impeller!
Now is the right time to make changes like this to Flutter GPU, since the API is not yet considered stable.

Before, `bindVertexBuffer` and `bindIndexBuffer` each took a count, and a single argument-less `draw()` guessed vertex versus index based on whether an index buffer happened to be bound.

Sooooo many reasons this was the wrong design:

- **Wrong object.** A draw count belongs on the draw, not on a buffer binding.
- **Implicit kind.** Indexed vs. non-indexed was inferred from what happened to be bound, not stated.
- **Colliding counts.** Vertex and index counts shared one field; the vertex count was dropped when an index buffer was bound.
- **Slot-0-only.** The count came from vertex slot 0; values on other slots were silently ignored.
- **Opaque draws.** `draw()` told you nothing; you had to trace every bind to know what it drew.
- **Sticky state.** The count leaked across draws in a pass.
- **Redundant re-binds.** Changing only the count forced re-binding the buffer.
- **No room to grow.** Nowhere natural for per-draw params like `instanceCount` or `baseVertex`.
- **Unconventional.** WebGPU, Vulkan, Metal, and D3D all put counts on the draw.
- **Late errors.** Bad counts failed at `draw()` time, far from the mistaken line.

Now:
- `bindVertexBuffer` and `bindIndexBuffer` only bind buffers.
- `draw(vertexCount)` does a non-indexed draw.
- `drawIndexed(indexCount)` does an indexed draw.

Instanced draws can be landed later via `draw` and `drawIndexed` gaining an `instanceCount` parameter later on, assuming the Impeller-side instancing support in flutter#186653 lands.

## 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/
[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

<!-- end_revert_body -->

Co-authored-by: auto-submit[bot] <flutter-engprod-team@google.com>
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request May 27, 2026
flutter/flutter@f3a4b98...c8f2f16

2026-05-27 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[Flutter GPU] Add explicit draw counts (#186639)" (flutter/flutter#187170)
2026-05-27 engine-flutter-autoroll@skia.org Roll Dart SDK from 7dcea971af6b to f3db7b7d9801 (2 revisions) (flutter/flutter#187144)
2026-05-27 bdero@google.com [Flutter GPU] Add explicit draw counts (flutter/flutter#186639)
2026-05-27 engine-flutter-autoroll@skia.org Roll Skia from f9db7748563e to fa944af10f91 (1 revision) (flutter/flutter#187139)
2026-05-27 bdero@google.com [Flutter GPU] Flutter GPU ShaderLibrary in-place reload for shader hot reload (flutter/flutter#186793)
2026-05-27 engine-flutter-autoroll@skia.org Roll Skia from a692cbf38952 to f9db7748563e (8 revisions) (flutter/flutter#187135)
2026-05-27 burak.karahan@mail.ru Use local semantics tester in Material button tests (flutter/flutter#186667)
2026-05-27 rmolivares@renzo-olivares.dev Filter out `a: text input` from `team-framework` PR triage  (flutter/flutter#187129)
2026-05-27 bkonyi@google.com [Engine] Fix silent buffer mismatch bug in FML Win32 CommandLineFromPlatform (flutter/flutter#187120)
2026-05-27 srawlins@google.com examples: Remove unused parameters (flutter/flutter#185819)
2026-05-27 116356835+AbdeMohlbi@users.noreply.github.com Remove another `String.valueOf` (flutter/flutter#186628)
2026-05-27 alex.medinsh@gmail.com Print trace when skipping flavor-specific and platform-specific assets (flutter/flutter#187045)
2026-05-26 adilhanney@disroot.org Fix `InteractiveViewer` memory leak from undisposed `CurvedAnimation`s (flutter/flutter#185826)
2026-05-26 meylis@divine.video Fix AccessibilityBridge startup crash on vendor-modified Android (flutter/flutter#184630)
2026-05-26 keertip@users.noreply.github.com Update data driven fixes docs (flutter/flutter#186217)
2026-05-26 ahmedsameha1@gmail.com Add more 0x0 size tests part10 (flutter/flutter#186201)
2026-05-26 46920873+gabrimatic@users.noreply.github.com Disable spell check for obscured text (flutter/flutter#186329)
2026-05-26 chris@bracken.jp [iOS] Migrate VSyncClient and DisplayLinkManager to Swift (flutter/flutter#187001)
2026-05-26 bkonyi@google.com [flutter_tools, devicelab] Add safety filesystem guard to tests (flutter/flutter#186748)
2026-05-26 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from Itd2Jq_ZIABH2rW7B... to k9EizfEGJO4WwQN9-... (flutter/flutter#187115)
2026-05-26 engine-flutter-autoroll@skia.org Roll Dart SDK from 00e625453c43 to 7dcea971af6b (1 revision) (flutter/flutter#187117)
2026-05-26 rmacnak@google.com Remove use of deprecated copy_trees. (flutter/flutter#187091)
2026-05-26 15619084+vashworth@users.noreply.github.com Use resolved implementation plugins with SwiftPM (flutter/flutter#187097)
2026-05-26 engine-flutter-autoroll@skia.org Roll Skia from 27a819894f7c to a692cbf38952 (3 revisions) (flutter/flutter#187109)
2026-05-26 engine-flutter-autoroll@skia.org Roll Packages from 69cf959 to fc795e5 (4 revisions) (flutter/flutter#187114)
2026-05-26 mvincentong@gmail.com Handle simctl process exceptions during discovery (flutter/flutter#186501)
2026-05-26 mvincentong@gmail.com Clarify precache enabled platforms help (flutter/flutter#186878)
2026-05-26 bkonyi@google.com [tool] Refactor artifacts.dart to use enhanced enums and reduce duplication (flutter/flutter#187063)
2026-05-26 jason-simmons@users.noreply.github.com Build script updates for syncing engine sources and building artifacts on linux-arm64 (flutter/flutter#186917)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC boetger@google.com,stuartmorgan@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
@bdero

bdero commented May 27, 2026

Copy link
Copy Markdown
Member Author

@cbracken No worries, thems the rules. This conflicted with a test I added in another change, and both changes just-so-happened to make it into the merge queue at the same time, fair and square. All presubmits were successful on both.

mboetger pushed a commit to mboetger/flutter that referenced this pull request May 27, 2026
Relands flutter#186639, which was reverted in flutter#187170.

The original PR landed clean, but broke the macOS and Linux builds
because `engine/src/flutter/testing/dart/gpu_shader_reload_test.dart`
(added concurrently by flutter#186793, which was in the merge queue at the same
time) still called the old `bindVertexBuffer(view, count)` / `draw()`
API. This reland is identical to flutter#186639 plus a one-spot migration of
that test to `bindVertexBuffer(view)` + `draw(3)`.

---

Moves the vertex and index count off the buffer-binding calls and onto
the draw call.

A simple (breaking) change that fixes a very silly design flaw that I
built into the API near the very beginning. Moves Flutter GPU draws
towards a design that matches virtually all modern graphics APIs,
including today's Impeller! Now is the right time to make changes like
this to Flutter GPU, since the API is not yet considered stable.

Before, `bindVertexBuffer` and `bindIndexBuffer` each took a count, and
a single argument-less `draw()` guessed vertex versus index based on
whether an index buffer happened to be bound.

Sooooo many reasons this was the wrong design:

- **Wrong object.** A draw count belongs on the draw, not on a buffer
binding.
- **Implicit kind.** Indexed vs. non-indexed was inferred from what
happened to be bound, not stated.
- **Colliding counts.** Vertex and index counts shared one field; the
vertex count was dropped when an index buffer was bound.
- **Slot-0-only.** The count came from vertex slot 0; values on other
slots were silently ignored.
- **Opaque draws.** `draw()` told you nothing; you had to trace every
bind to know what it drew.
- **Sticky state.** The count leaked across draws in a pass.
- **Redundant re-binds.** Changing only the count forced re-binding the
buffer.
- **No room to grow.** Nowhere natural for per-draw params like
`instanceCount` or `baseVertex`.
- **Unconventional.** WebGPU, Vulkan, Metal, and D3D all put counts on
the draw.
- **Late errors.** Bad counts failed at `draw()` time, far from the
mistaken line.

Now:
- `bindVertexBuffer` and `bindIndexBuffer` only bind buffers.
- `draw(vertexCount)` does a non-indexed draw.
- `drawIndexed(indexCount)` does an indexed draw.

Instanced draws can be landed later via `draw` and `drawIndexed` gaining
an `instanceCount` parameter later on, assuming the Impeller-side
instancing support in flutter#186653 lands.

## 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/
[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
@cbracken

cbracken commented May 28, 2026

Copy link
Copy Markdown
Member

This conflicted with a test I added in another change, and both changes just-so-happened to make it into the merge queue at the same time, fair and square. All presubmits were successful on both.

Clearly the answer is "Stop being so productive!" 😂 There should probably be an achievement badge for this.

creatorpiyush pushed a commit to creatorpiyush/packages that referenced this pull request Jun 10, 2026
…r#11795)

flutter/flutter@f3a4b98...c8f2f16

2026-05-27 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[Flutter GPU] Add explicit draw counts (#186639)" (flutter/flutter#187170)
2026-05-27 engine-flutter-autoroll@skia.org Roll Dart SDK from 7dcea971af6b to f3db7b7d9801 (2 revisions) (flutter/flutter#187144)
2026-05-27 bdero@google.com [Flutter GPU] Add explicit draw counts (flutter/flutter#186639)
2026-05-27 engine-flutter-autoroll@skia.org Roll Skia from f9db7748563e to fa944af10f91 (1 revision) (flutter/flutter#187139)
2026-05-27 bdero@google.com [Flutter GPU] Flutter GPU ShaderLibrary in-place reload for shader hot reload (flutter/flutter#186793)
2026-05-27 engine-flutter-autoroll@skia.org Roll Skia from a692cbf38952 to f9db7748563e (8 revisions) (flutter/flutter#187135)
2026-05-27 burak.karahan@mail.ru Use local semantics tester in Material button tests (flutter/flutter#186667)
2026-05-27 rmolivares@renzo-olivares.dev Filter out `a: text input` from `team-framework` PR triage  (flutter/flutter#187129)
2026-05-27 bkonyi@google.com [Engine] Fix silent buffer mismatch bug in FML Win32 CommandLineFromPlatform (flutter/flutter#187120)
2026-05-27 srawlins@google.com examples: Remove unused parameters (flutter/flutter#185819)
2026-05-27 116356835+AbdeMohlbi@users.noreply.github.com Remove another `String.valueOf` (flutter/flutter#186628)
2026-05-27 alex.medinsh@gmail.com Print trace when skipping flavor-specific and platform-specific assets (flutter/flutter#187045)
2026-05-26 adilhanney@disroot.org Fix `InteractiveViewer` memory leak from undisposed `CurvedAnimation`s (flutter/flutter#185826)
2026-05-26 meylis@divine.video Fix AccessibilityBridge startup crash on vendor-modified Android (flutter/flutter#184630)
2026-05-26 keertip@users.noreply.github.com Update data driven fixes docs (flutter/flutter#186217)
2026-05-26 ahmedsameha1@gmail.com Add more 0x0 size tests part10 (flutter/flutter#186201)
2026-05-26 46920873+gabrimatic@users.noreply.github.com Disable spell check for obscured text (flutter/flutter#186329)
2026-05-26 chris@bracken.jp [iOS] Migrate VSyncClient and DisplayLinkManager to Swift (flutter/flutter#187001)
2026-05-26 bkonyi@google.com [flutter_tools, devicelab] Add safety filesystem guard to tests (flutter/flutter#186748)
2026-05-26 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from Itd2Jq_ZIABH2rW7B... to k9EizfEGJO4WwQN9-... (flutter/flutter#187115)
2026-05-26 engine-flutter-autoroll@skia.org Roll Dart SDK from 00e625453c43 to 7dcea971af6b (1 revision) (flutter/flutter#187117)
2026-05-26 rmacnak@google.com Remove use of deprecated copy_trees. (flutter/flutter#187091)
2026-05-26 15619084+vashworth@users.noreply.github.com Use resolved implementation plugins with SwiftPM (flutter/flutter#187097)
2026-05-26 engine-flutter-autoroll@skia.org Roll Skia from 27a819894f7c to a692cbf38952 (3 revisions) (flutter/flutter#187109)
2026-05-26 engine-flutter-autoroll@skia.org Roll Packages from 69cf959 to fc795e5 (4 revisions) (flutter/flutter#187114)
2026-05-26 mvincentong@gmail.com Handle simctl process exceptions during discovery (flutter/flutter#186501)
2026-05-26 mvincentong@gmail.com Clarify precache enabled platforms help (flutter/flutter#186878)
2026-05-26 bkonyi@google.com [tool] Refactor artifacts.dart to use enhanced enums and reduce duplication (flutter/flutter#187063)
2026-05-26 jason-simmons@users.noreply.github.com Build script updates for syncing engine sources and building artifacts on linux-arm64 (flutter/flutter#186917)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC boetger@google.com,stuartmorgan@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
via-guy pushed a commit to via-guy/flutter that referenced this pull request Jun 26, 2026
Moves the vertex and index count off the buffer-binding calls and onto
the draw call.

A simple (breaking) change that fixes a very silly design flaw that I
built into the API near the very beginning. Moves Flutter GPU draws
towards a design that matches virtually all modern graphics APIs,
including today's Impeller!
Now is the right time to make changes like this to Flutter GPU, since
the API is not yet considered stable.

Before, `bindVertexBuffer` and `bindIndexBuffer` each took a count, and
a single argument-less `draw()` guessed vertex versus index based on
whether an index buffer happened to be bound.

Sooooo many reasons this was the wrong design:

- **Wrong object.** A draw count belongs on the draw, not on a buffer
binding.
- **Implicit kind.** Indexed vs. non-indexed was inferred from what
happened to be bound, not stated.
- **Colliding counts.** Vertex and index counts shared one field; the
vertex count was dropped when an index buffer was bound.
- **Slot-0-only.** The count came from vertex slot 0; values on other
slots were silently ignored.
- **Opaque draws.** `draw()` told you nothing; you had to trace every
bind to know what it drew.
- **Sticky state.** The count leaked across draws in a pass.
- **Redundant re-binds.** Changing only the count forced re-binding the
buffer.
- **No room to grow.** Nowhere natural for per-draw params like
`instanceCount` or `baseVertex`.
- **Unconventional.** WebGPU, Vulkan, Metal, and D3D all put counts on
the draw.
- **Late errors.** Bad counts failed at `draw()` time, far from the
mistaken line.

Now:
- `bindVertexBuffer` and `bindIndexBuffer` only bind buffers.
- `draw(vertexCount)` does a non-indexed draw.
- `drawIndexed(indexCount)` does an indexed draw.

Instanced draws can be landed later via `draw` and `drawIndexed` gaining
an `instanceCount` parameter later on, assuming the Impeller-side
instancing support in flutter#186653 lands.

## 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/
[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
via-guy pushed a commit to via-guy/flutter that referenced this pull request Jun 26, 2026
…utter#187170)

<!-- start_original_pr_link -->
Reverts: flutter#186639
<!-- end_original_pr_link -->
<!-- start_initiating_author -->
Initiated by: cbracken
<!-- end_initiating_author -->
<!-- start_revert_reason -->
Reason for reverting: doesn't compile on mac, or Linux.

Mac:
```
../../flutter/testing/dart/gpu_shader_reload_test.dart:64:36: Error: Too many positional arguments: 1 allowed, but 2 found.
Try removing the extra positional arguments.
  state.renderPass.bindVertexBuffer(
                                   ^
../../flutter/testing/dart/gpu_shader_reload_test.dart:72:24: Error: Too few positional arguments: 1 requ
<!-- end_revert_reason -->
<!-- start_original_pr_author -->
Original PR Author: bdero
<!-- end_original_pr_author -->

<!-- start_reviewers -->
Reviewed By: {walley892}
<!-- end_reviewers -->

<!-- start_revert_body -->
This change reverts the following previous change:
Moves the vertex and index count off the buffer-binding calls and onto the draw call.

A simple (breaking) change that fixes a very silly design flaw that I built into the API near the very beginning. Moves Flutter GPU draws towards a design that matches virtually all modern graphics APIs, including today's Impeller!
Now is the right time to make changes like this to Flutter GPU, since the API is not yet considered stable.

Before, `bindVertexBuffer` and `bindIndexBuffer` each took a count, and a single argument-less `draw()` guessed vertex versus index based on whether an index buffer happened to be bound.

Sooooo many reasons this was the wrong design:

- **Wrong object.** A draw count belongs on the draw, not on a buffer binding.
- **Implicit kind.** Indexed vs. non-indexed was inferred from what happened to be bound, not stated.
- **Colliding counts.** Vertex and index counts shared one field; the vertex count was dropped when an index buffer was bound.
- **Slot-0-only.** The count came from vertex slot 0; values on other slots were silently ignored.
- **Opaque draws.** `draw()` told you nothing; you had to trace every bind to know what it drew.
- **Sticky state.** The count leaked across draws in a pass.
- **Redundant re-binds.** Changing only the count forced re-binding the buffer.
- **No room to grow.** Nowhere natural for per-draw params like `instanceCount` or `baseVertex`.
- **Unconventional.** WebGPU, Vulkan, Metal, and D3D all put counts on the draw.
- **Late errors.** Bad counts failed at `draw()` time, far from the mistaken line.

Now:
- `bindVertexBuffer` and `bindIndexBuffer` only bind buffers.
- `draw(vertexCount)` does a non-indexed draw.
- `drawIndexed(indexCount)` does an indexed draw.

Instanced draws can be landed later via `draw` and `drawIndexed` gaining an `instanceCount` parameter later on, assuming the Impeller-side instancing support in flutter#186653 lands.

## 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/
[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

<!-- end_revert_body -->

Co-authored-by: auto-submit[bot] <flutter-engprod-team@google.com>
via-guy pushed a commit to via-guy/flutter that referenced this pull request Jun 26, 2026
Relands flutter#186639, which was reverted in flutter#187170.

The original PR landed clean, but broke the macOS and Linux builds
because `engine/src/flutter/testing/dart/gpu_shader_reload_test.dart`
(added concurrently by flutter#186793, which was in the merge queue at the same
time) still called the old `bindVertexBuffer(view, count)` / `draw()`
API. This reland is identical to flutter#186639 plus a one-spot migration of
that test to `bindVertexBuffer(view)` + `draw(3)`.

---

Moves the vertex and index count off the buffer-binding calls and onto
the draw call.

A simple (breaking) change that fixes a very silly design flaw that I
built into the API near the very beginning. Moves Flutter GPU draws
towards a design that matches virtually all modern graphics APIs,
including today's Impeller! Now is the right time to make changes like
this to Flutter GPU, since the API is not yet considered stable.

Before, `bindVertexBuffer` and `bindIndexBuffer` each took a count, and
a single argument-less `draw()` guessed vertex versus index based on
whether an index buffer happened to be bound.

Sooooo many reasons this was the wrong design:

- **Wrong object.** A draw count belongs on the draw, not on a buffer
binding.
- **Implicit kind.** Indexed vs. non-indexed was inferred from what
happened to be bound, not stated.
- **Colliding counts.** Vertex and index counts shared one field; the
vertex count was dropped when an index buffer was bound.
- **Slot-0-only.** The count came from vertex slot 0; values on other
slots were silently ignored.
- **Opaque draws.** `draw()` told you nothing; you had to trace every
bind to know what it drew.
- **Sticky state.** The count leaked across draws in a pass.
- **Redundant re-binds.** Changing only the count forced re-binding the
buffer.
- **No room to grow.** Nowhere natural for per-draw params like
`instanceCount` or `baseVertex`.
- **Unconventional.** WebGPU, Vulkan, Metal, and D3D all put counts on
the draw.
- **Late errors.** Bad counts failed at `draw()` time, far from the
mistaken line.

Now:
- `bindVertexBuffer` and `bindIndexBuffer` only bind buffers.
- `draw(vertexCount)` does a non-indexed draw.
- `drawIndexed(indexCount)` does an indexed draw.

Instanced draws can be landed later via `draw` and `drawIndexed` gaining
an `instanceCount` parameter later on, assuming the Impeller-side
instancing support in flutter#186653 lands.

## 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/
[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

e: impeller Impeller rendering backend issues and features requests engine flutter/engine related. See also e: labels. flutter-gpu team-fluttergpu Owned by Flutter GPU team

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

7 participants