github.com-google-skia
all · 23 devs · built 2026-06-13
Repository snapshot
Monthly reports
Highlights
- Critical *GPU text rendering pipeline* security vulnerability (b/513948227) was addressed by reconstructing `subRun` bounds from glyphs, successfully relanded in [b8544997] and implemented in [f93ed13d] after an initial revert [c480ba2e].
- Enhanced *security* by restricting deserialization types in `SkGlyph` and `SkCustomTypeface` ([f1b8ba87]) and removing unused `SkDrawable` serialization from `SkCustomTypeface` ([9da67e21]).
- Significant *toolchain upgrade* for Windows, updating *MSVC* to 19.51.36244 and *Clang* to 23.0, alongside re-enabling critical *MSVC CI jobs* ([aaa00402]).
- Introduced a new *agent skill registry* with `core_skills.json`, laying groundwork for automated agent operations with `skia-add-test` and `skia-gn-workflow` skills ([8f47b24d]).
- Extensive code quality improvements through widespread refactoring, including consistent use of `std::make_unique` across *core modules*, *image codecs*, and *GPU operations* ([d7a4ca22]), and standardizing *fatal error handling* with `SK_ABORT` macro ([bb889fb1]).
- *Skia Infra* dependency roll enabled *Chrome Browser Benchmarking (CBB) on Android Pixel 10* and enhanced the *performance analysis subsystem* with parallelized anomaly detection ([5a3e4192]).
Observations
- The *waste score* surged by 63% (current: 9, 5-month average: 6) compared to the 5-month average, indicating a period of significant rework and bug fixing.
- Multiple reverts and relands contributed to the high waste, notably for the *Graphite BufferSubAllocator* ([c329e877], [04b084c1], [e7bff78b]) and the critical *GPU text rendering security fix* ([c480ba2e], [b8544997], [f93ed13d]), suggesting challenges in integrating complex changes.
- The *maintenance score* decreased by 62% (current: 5, 5-month average: 12) compared to the 5-month average, despite a high volume of routine dependency updates.
- A continuous pattern of *dependency updates* was observed, with numerous rolls for *vulkan-deps* ([659b6796], [32b547c8], [91e53285], [33a1c4f3], [dc01525a], [087c3cc3], [9cddcf3d], [d218592d], [a38708fb]), *ANGLE* ([47155534], [3f20d967], [f71b8b88]), *Dawn* ([df142ba6], [52c2b023], [92f9b68b], [5890b2d6]), and *SwiftShader* ([71c18003], [1ff231ca], [326cbc3a]), indicating ongoing efforts to keep external components current.
- The *grow score* was 3 this month, a 29% decrease from the 5-month average of 5, suggesting a reduced focus on new feature development in favor of maintenance and addressing existing issues.
- Several bug fixes were implemented across various components, including a *Graphite* null dereference ([0aee4675]), an *SkScalerContext* MSAN issue ([e202cf3e]), *SkVx::isFinite* on MSVC ([87c0eddb]), and an integer overflow in loops ([5493e4c1]), highlighting active issue resolution.
Performance over time
ETV stacked by Growth, Maintenance and Fixes — 90-day moving average, normalized to ETV / month.
Average performance per developer
ETV per active developer per month — 30-day moving average.
Active developers over time
Unique developers committing each day — 90-day moving average.
Knowledge concentration
How dependent is this repo on a small number of contributors? Higher top-1 share = higher key-person risk.
Kaylee Lubick owns 18.3 % of commits.
Top contributors
Most impactful commits
Top 20 by ETV in the all-time window.
- 2.2ETV[wgsl] Apply array polyfills in synthetic sksl tests correctly This refactors `writeUniformsAndBuffers`'s body that handled interface blocks into a helper `writeInterfaceBlock` (logic unchanged) so that it could be called by `writeNonBlockUniformsForTests` in place of it generating bespoke WGSL that was 90% the same as the default generated interface WGSL. This allows the synthetic global uniform block to participate in the array polyfills and matrix polyfills correctly, although there was a minor impact on generated test wgsl where @group and @binding changed order. The array/matrix polyfill types also had to be updated to use @align(16) instead of @size(16). The latter adjusts the size but does not propagate the stricter alignment into any wrapping type. Bug: b/465408252 Change-Id: I41077f77ff8bd752f20c8e0f7603bfd4023a45cf Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1121416 Commit-Queue: Michael Ludwig <michaelludwig@google.com> Reviewed-by: Thomas Smith <thomsmit@google.com>Michael Ludwig · 0d60c01b · 2026-01-14
- 2.2ETV[wgsl] Refactor const-eval workaround into automatic helper Bug: b/465408252 Change-Id: Ic8f8ee4ac16b994b92fb994d262cee25230538bc Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1118697 Reviewed-by: Thomas Smith <thomsmit@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>Michael Ludwig · 2b8e3730 · 2025-12-12
- 1.9ETVChange how backend data is stored in text SubRuns Store backend-specific data in a side car. This allows the type of data stored by Ganesh and Graphite to diverge as their atlas data structures and algorithms evolve independently. Move some backend-specific code in to the new backend-specific type. This avoids some unnecessary spring boarding through neutral types with shallow code that calls back to backend-specific code. Change-Id: I657a9df327acbeb325399e5a606ca621877fd138 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1121037 Reviewed-by: Greg Daniel <egdaniel@google.com> Reviewed-by: Michael Ludwig <michaelludwig@google.com> Commit-Queue: Brian Salomon <briansalomon@gmail.com>Brian Salomon · d12836ea · 2026-02-19
- 1.8ETV[graphite] Remove TextureInfoData and TextureSpec in TextureInfo The intermediates, TextureInfoData and its subclasses, and the backend structs [Foo]TextureSpec are removed. A private TextureInfo::Data virtual class is introduced that holds the sample count and mipmapped state, with the backend [Foo]TextureInfo classes extending. This exposes those fields and preserves their field layout before this CL, and also makes them equivalent to the removed TextureSpec structs. Since TextureInfo::Data is private to TextureInfo and can be friended, the virtual functionality that had been on TextureInfoData is declared up front to simplify the number of types that have to be implemented. In situations where there is a backend context (e.g. a Caps object) or calling a function from a backend-specific compilation unit, template traits are used instead of increasing the number of virtual functions. With a few more follow up CLs, the only virtual functionality on TextureInfo::Data will be related to equality and initialization/assignment operators. I opted to have the template functionality be part of the FooTextureInfo subclasses directly, instead of having a specialization for such as `TextureInfoTraits<FooTextureInfo>`. If it was that way, it would require all the callers/users of the templated functionality to include multiple headers and if the traits specialization wasn't included, the compiler error messages were pretty opaque. Lastly, this goes through all the backends and updates them to access their backend data directly using TextureInfoPriv::Get<T>, which just casts the underlying SkAnySubclass. Change-Id: I5f58146305175ca4da4d0feca5d8499cc850da35 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/952676 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>Michael Ludwig · 7eb3242b · 2025-02-20
- 1.8ETV[Fontations] Structure ffi.rs into modules Requires Chromium side change [1] to use skia_fontations_bridge_root for cxx_bindings in bridge_rust_side and skia_ports_fontations_bridge_rust_side_sources for sources. No functional change. [1] https://chromium-review.googlesource.com/c/chromium/src/+/6395360 Bug: skia:406454923 Cq-Include-Trybots: luci.skia.skia.primary:Build-Debian10-Clang-x86_64-Debug-Fontations,Build-Mac-Clang-x86_64-Debug-Fontations,Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Debug-All-NativeFonts_Fontations,Test-Mac14-Clang-MacMini8.1-CPU-AVX2-x86_64-Debug-All-NativeFonts_Fontations,Test-Mac15-Clang-MacBookPro15.1-CPU-AppleIntel-x86_64-Debug-All-NativeFonts_Fontations Change-Id: I15c2cab0e93f4939d2d6dcb0e28dfe183fa4e848 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/970336 Reviewed-by: Ben Wagner <bungeman@google.com> Reviewed-by: Dominik Röttsches <drott@google.com> Commit-Queue: Dominik Röttsches <drott@google.com>Dominik Röttsches · 62841da1 · 2025-03-27
- 1.7ETV[graphite] Paint and RenderStep share uniform binding. * Avoids loading the ssboIndex from device memory twice, if possible, by storing from the register if it was defined. Change-Id: Id47851e023324a2ba57c88d569b0135bd54f37ce Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1081116 Commit-Queue: Thomas Smith <thomsmit@google.com> Reviewed-by: Michael Ludwig <michaelludwig@google.com>Thomas Smith · dcd71c21 · 2025-11-15
- 1.7ETVIntroduce SkRasterPipelineContexts namespace This makes the names of the structs a tiny bit more clean and helps avoid polluting the global namespace with consts (e.g. kMaxStride and kRGBAChannels) Change-Id: I6321a64ee0e0c34cf194f5f034de389dc3dab8f1 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/969176 Commit-Queue: Kaylee Lubick <kjlubick@google.com> Reviewed-by: Daniel Dilan <danieldilan@google.com> Commit-Queue: Daniel Dilan <danieldilan@google.com> Auto-Submit: Kaylee Lubick <kjlubick@google.com>Kaylee Lubick · a4959402 · 2025-03-24
- 1.7ETVMove editing methods into separate .cpp - also completely removes most editing methods, not just making them private. - will allow us to start the migration to a new backend - also move non-skpath priv methods to priv.cpp - found some lurkers calling setPt(), so migrated them to an equivalent method in SkPathBbuilder. Change-Id: Ic283723b8e3c3ba98cdd86efdce0dbeb7e223557 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1072196 Commit-Queue: Mike Reed <mike@reedtribe.org> Reviewed-by: Kaylee Lubick <kjlubick@google.com> Reviewed-by: Florin Malita <fmalita@google.com>Michael Reed · a23efe34 · 2025-10-14
- 1.6ETVRevert "Move editing methods into separate .cpp" This reverts commit a23efe34c35178a7b03a619f54cf97257d6ef359. Reason for revert: Breaks google3 and chrome rolls Original change's description: > Move editing methods into separate .cpp > > - also completely removes most editing methods, not just making > them private. > - will allow us to start the migration to a new backend > - also move non-skpath priv methods to priv.cpp > - found some lurkers calling setPt(), so migrated them to an equivalent > method in SkPathBbuilder. > > Change-Id: Ic283723b8e3c3ba98cdd86efdce0dbeb7e223557 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1072196 > Commit-Queue: Mike Reed <mike@reedtribe.org> > Reviewed-by: Kaylee Lubick <kjlubick@google.com> > Reviewed-by: Florin Malita <fmalita@google.com> No-Presubmit: true No-Tree-Checks: true No-Try: true Change-Id: I20388184ae272c8514335a1d59ed54ba731a51c6 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1074377 Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>Thomas Smith · 5c9f7307 · 2025-10-14
- 1.6ETVReapply "Move editing methods into separate .cpp" Fix: no fix needed This reverts commit 5c9f73070c10f01fa2296d78dc5b332dba7add85. Change-Id: I1883d6ecfaac3a2e098e66150c96696fdad829d7 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1074796 Reviewed-by: Florin Malita <fmalita@google.com> Reviewed-by: Daniel Dilan <danieldilan@google.com> Commit-Queue: Mike Reed <mike@reedtribe.org>Michael Reed · bbd968fc · 2025-10-15
- 1.6ETVReland "[rust bmp] Initial implementation of rust icc FFI using moxcms crate" This reverts commit bbadc90717c301a13da4dc59778237b7380521db. Reason for revert: BP generator fix landed, this should no longer block Android rolls Original change's description: > Revert "[rust bmp] Initial implementation of rust icc FFI using moxcms crate" > > This reverts commit 0a0079a5741dd0695acfd106bda26deb0e1a05c9. > > Reason for revert: Blocking the Android roller. A tmp file is being generated and included in our Android.bp. See https://googleplex-android-review.git.corp.google.com/c/platform/external/skia/+/37566312/-1..1 > > Original change's description: > > [rust bmp] Initial implementation of rust icc FFI using moxcms crate > > > > This CL is adding rust/icc FFI layer to access moxcms crate > > functionality, which enables to have a rust implementation of ICC > > profile parsing. This is intended to be later be used from all the > > rustified codecs for formats supporting ICC. We are integrating a first > > drop still without any use from rust/png to allow proper BUILD.gn update > > in Chromium after this change and complete integration afterwards > > avoiding breaking Chromium build. > > > > This change has pre-requisite of the following CL landing in skcms: > > > > https://skia-review.googlesource.com/c/skcms/+/1111536 > > > > Change-Id: I1a1792ab6cacbc37f2d57de00aecdc8bb0535d91 > > Bug: 452666425 > > Bug: 463653726 > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1106557 > > Reviewed-by: Christopher Cameron <ccameron@google.com> > > Commit-Queue: Łukasz Anforowicz <lukasza@google.com> > > Reviewed-by: Łukasz Anforowicz <lukasza@google.com> > > Bug: 452666425 > Bug: 463653726 > Change-Id: I250fd8c4d40fdf1b856001e770a328698024fb98 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1128497 > Commit-Queue: Jorge Betancourt <jmbetancourt@google.com> > Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Bug: 452666425 Bug: 463653726 Change-Id: I7314044c197d17253fe6e9ff3dd904835a9adee8 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1128776 Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Commit-Queue: Florin Malita <fmalita@google.com> Reviewed-by: Łukasz Anforowicz <lukasza@google.com>Florin Malita · ea175381 · 2025-12-18
- 1.6ETV[rust bmp] Initial implementation of rust icc FFI using moxcms crate This CL is adding rust/icc FFI layer to access moxcms crate functionality, which enables to have a rust implementation of ICC profile parsing. This is intended to be later be used from all the rustified codecs for formats supporting ICC. We are integrating a first drop still without any use from rust/png to allow proper BUILD.gn update in Chromium after this change and complete integration afterwards avoiding breaking Chromium build. This change has pre-requisite of the following CL landing in skcms: https://skia-review.googlesource.com/c/skcms/+/1111536 Change-Id: I1a1792ab6cacbc37f2d57de00aecdc8bb0535d91 Bug: 452666425 Bug: 463653726 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1106557 Reviewed-by: Christopher Cameron <ccameron@google.com> Commit-Queue: Łukasz Anforowicz <lukasza@google.com> Reviewed-by: Łukasz Anforowicz <lukasza@google.com>Sergio Gonzalez · 0a0079a5 · 2025-12-13
- 1.6ETVRevert "Reland "[graphite] Extracts early in drawGeometry"" This reverts commit 81de4113e3e7cfe8ec91413fbbe51101dcb354e3. Reason for revert: Now breaking chromium roll. Original change's description: > Reland "[graphite] Extracts early in drawGeometry" > > * Reintroduce notify image in use and flush in snapDrawTask. > > * Fixes an issue where multi-draw dependencies were not correctly tracked. > > This reverts commit 1b271fd02a65ba97e12bcaa32f67afa50b5d9b52. > > > Original change's description: > > Revert "[graphite] Extracts early in drawGeometry" > > > > This reverts commit 25f00cb247f23b4a8cbe7a1245bdf609fa0be846. > > > > Reason for revert: Breaks android roll > > > > Original change's description: > > > [graphite] Extracts early in drawGeometry > > > > > > * Moves the creation of UniquePaintIDs from DrawPass::Snap to PaintParams::toKey, which is called in Device::drawGeometry > > > > > > * Moves blend mode calculations into PaintParams, and adds an enum DstUsage to DrawTypes. > > > > > > * Moves the creation of a draw pass from DrawPass::Make to DrawList::snapDrawPass. > > > > > > * Texture and uniform trackers commensurately moved to DrawList. > > > > > > Change-Id: Ie843db44bfad0cd51773ffa7e42050fdbd7c22e3 > > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1045336 > > > Commit-Queue: Thomas Smith <thomsmit@google.com> > > > Reviewed-by: Michael Ludwig <michaelludwig@google.com> > > > > No-Presubmit: true > > No-Tree-Checks: true > > No-Try: true > > Change-Id: I19ad73d77051295e37ac9adaae77f228e4934834 > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1052396 > > Commit-Queue: Thomas Smith <thomsmit@google.com> > > Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> > > Change-Id: Ib8b9aa5b3ed998bdecd3b56a03ca13f189518178 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1052657 > Reviewed-by: Michael Ludwig <michaelludwig@google.com> > Commit-Queue: Thomas Smith <thomsmit@google.com> No-Presubmit: true No-Tree-Checks: true No-Try: true Change-Id: I0132ab1e71955f6a8b35b3107afe9ae48f5654aa Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1059636 Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Commit-Queue: Thomas Smith <thomsmit@google.com>Thomas Smith · 5aafacb1 · 2025-09-22
- 1.5ETV[graphite] Add TextureFormat unit tests Fixed a bug in the colortype -> format lookup that wasn't taking renderability into account. This is only an issue until https://skia-review.git.corp.google.com/c/skia/+/1165836 lands, which removes these in favor of a static lookup map. Added many format rules in Mtl, Dawn, and VulkanCaps that were inconsistently declared between the different backends even though they all had a backend format matching the TextureFormat. Additionally, it adds rules to make the BGRA vs RGBA ordering more relaxed, which is the eventual set of matches that the TextureFormat unit tests lay out. The color -> format rules are minimally done to get the unit tests passing; formats are marked compatible with color types but I didn't change how color types were mapped to formats. Bug: b/390473370 Change-Id: I1851bedad6083e577fb8c0e9e096844582d86206 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1167440 Reviewed-by: Thomas Smith <thomsmit@google.com> Reviewed-by: Nicolette Prevost <nicolettep@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>Michael Ludwig · b1b7bfb4 · 2026-02-27
- 1.5ETVConvert some gms to use spanified Gradients API - this removes gradients4f and gradients4f_nodither, and they are now complete dups of gradients and gradients_nodither Change-Id: I799603e60159550c8e9802296264cb50e6192b32 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1124456 Reviewed-by: Florin Malita <fmalita@google.com> Reviewed-by: Eric Boren <borenet@google.com> Commit-Queue: Mike Reed <mike@reedtribe.org>Michael Reed · 9decbd4c · 2025-12-15
- 1.5ETVRemove D3D includes from GrBackendSurface.h This moves all the functionality to include/gpu/ganesh/d3d/GrD3DBackendSurface.h Suggested review order: - GrD3DBackendSurface.h, GrD3DBackendSurfacePriv.h, include/gpu/ganesh/GrBackendSurface.h to see the APIs move. Note I changed the pattern of taking an out pointer and returning a boolean to just returning the type since the only time that could happen is if the wrong or an uninitialized backend type was passed in, which will cause us to assert in debug mode. Notice also I went with MakeD3D for the constructors to align with GrBackendSemaphore and (soon) GrDirectContext. - GrD3DBackendSurface.cpp to see all the moved code/logic from GrBackendSurface.cpp. - GrD3DTypesMinimal.h/.cpp to remove now-unnecessary default constructor and make method name more concise. - All other changes in any order. Change-Id: I46312ada58e2720838ad2096ef98c9af84323b18 Bug: b/293490566 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1159676 Reviewed-by: Greg Daniel <egdaniel@google.com>Kaylee Lubick · d4797590 · 2026-02-17
- 1.4ETVPass in targetSurface to asView for same surface check. When drawing an image, we need to know if we're drawing into a surface that is backend by the same texture. If so, we need to perform a copy since it is not legal to have the same texture. In Ganesh the copy on write mechanisms are all controled by the ProxyChooser. This change plumbs down the targetSurface proxy into ProxyChooser::chooseProxy where we will check if we're drawing to the same surface or not. Bug: b/387306744 Change-Id: I96e80e58a965ee8b94d13736fd3f3526d8b5778f Reviewed-on: https://skia-review.googlesource.com/c/skia/+/972596 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>Greg Daniel · e1555f69 · 2025-10-08
- 1.4ETVReconstruct subRun bounds from glyphs * Reconstruct the bounds of a subRun after deserialization instead of packaging onto the VertexFiller. * An attacker could create a VertexFiller with creation bounds that did not contain its glyphs but were entirely contained within the current clip, enabling to the glyphs to ignore the creation bounds clip and sample from stale scratch textures Bug: b/513948227 Change-Id: Ib4902657e6a50dd5675db4d73a1576b77c4ce88e Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1239916 Commit-Queue: Thomas Smith <thomsmit@google.com> Reviewed-by: Michael Ludwig <michaelludwig@google.com>Thomas Smith · f93ed13d · 2026-05-28
- 1.4ETV[wgsl] Stop forcing all function calls into scratch lets This leads to decent reduction in the size of the generated WGSL and the WGSL ends up matching closer to the GLSL or MSL that the other code generators emit. We preserve writing to a let or to a statement when handling out parameters since there's a mismatch in SkSL's semantics vs. WGSL's. However, this logic is now consolidated into assembleFunctionCall() instead of spread out across that call, assembleIntrinsicCall(), and assembleSimpleIntrinsic(), etc. This is also part of a larger effort to pull back the use of writeScratchLet(), which poses difficulties with handling f16 vs f32. Bug: b/465408252 Change-Id: I8c20cd9544c686a2578316d54fc85462e92a0f7c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1118497 Reviewed-by: Thomas Smith <thomsmit@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>Michael Ludwig · 8e441f90 · 2025-12-09
- 1.3ETVSkPathData : immutable replacement for SkPathRef - Immutable (except for lazy convexity...?) - Single allocation -- all arrays in single block - Only stores coordinates, not filltype or volatility Known task for follow-up CLs - Lazily compute convexity, or up-front? - UniqueID M1 Max benchmarks 23/23 MB 238 114ns 119ns 122ns 144ns 8% ▁▁▁▆▂▃▂▂█▂ nonrendering path_transform_affine_path 23/23 MB 330 128ns 132ns 133ns 143ns 4% ▁▃▃▃▃▆▃▃▂█ nonrendering path_transform_affine_builder 23/23 MB 601 68.9ns 72.1ns 72.2ns 79ns 4% ▄▃▄▄▁█▃▃▁▃ nonrendering path_transform_affine_data Change-Id: I2f1f2c4e8b3c4bcd3a65e35749c536b19a315ad6 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1025416 Reviewed-by: Florin Malita <fmalita@google.com> Reviewed-by: Kaylee Lubick <kjlubick@google.com> Commit-Queue: Mike Reed <mike@reedtribe.org>Michael Reed · b2b28690 · 2025-10-12