skia — Engineering Performance
23 engineers all time · Jan 2025 – Aug 2026 · built 2026-08-23 · GitHub
Performance snapshot
Today's rolling 90-day reading for skia, compared with the start of the series. Pick a window to move that comparison point.
Eff. capacity added
+6.5engineers
13 devs deliver like 19 (1.5x pre-AI)
Avg. perf / dev / mo (ETV)
+55.9%
0.83 → 1.29
Active engineers
−38.1%
21.0 → 13.0
Features
+2.9pp
25.8% → 28.7%
skia vs. Google
Per-engineer ETV for skia against Google as a whole. Both lines are 90-day rolling averages scaled to a 30-day month, so they share one axis and can be read against each other at any point. Pick a window to zoom the chart to it.
Performance over time
ETV stacked by Features / Maintenance / Tests / Docs / Fixes — 90-day moving average, normalized to ETV / month.
Engineering capacity
Effective engineers behind skia, in pre-AI terms. Per-engineer ETV divided by the Q1 2025 baseline of 0.86 ETV / dev / mo gives a capacity multiple, and that multiple applied to the engineers active in the trailing 90 days turns it into engineer-equivalents. The line is the real headcount, so the gap between line and area is what the leverage is worth.
Knowledge concentration
How dependent is this repo on a small number of engineers? Higher top-1 share = higher key-person risk.
Kaylee Lubick owns 18.6 % of commits.
Reports
Written summary of the work completed each month.
No monthly reports available yet.
Top engineers
Most impactful commits
Top 10 by ETV in the all-time window.
- 3.4ETV[rust jpeg] Initial implementation of rust jpeg Add a CXX FFI bridge connecting zune-jpeg (decoder) and jpeg-encoder (encoder) crates to Skia, following the same pattern as rust_bmp and rust_png. Decoder features: - Baseline, progressive, grayscale, RGB, and CMYK/YCCK JPEG decoding - ICC profile extraction (multi-segment APP2) and validation - EXIF orientation parsing (via shared SkExif::Parse) - Color space transforms (via skcms) - Incremental decode with rewind support - Gainmap extraction (ISO 21496-1, Adobe, Apple) via MPF - OSS-Fuzz integration Encoder features: - RGB, RGBA, BGRA, Grayscale, kRGB_888x pixel formats - Alpha blending (ignore or blend-on-black) - XMP metadata insertion Rust-side JPEG segment scanning, ICC/EXIF metadata extraction, TIFF IFD parsing, and MPF (Multi-Picture Format) parsing are all implemented in memory-safe Rust. Higher-level gainmap detection (XMP, ISO 21496-1) reuses existing C++ SkJpegMetadataDecoder. Known gaps vs SkJpegCodec: - No true incremental decoding — requires zune-jpeg support - No YUV plane decode (onQueryYUVAInfo) — requires zune-jpeg raw planes - No scanline decoding - requires zune-jpeg support - No getSampler (subset decoding) - No Container XMP gainmap fallback (requires EOI offset) Bug: 493315750 Change-Id: Ib96f274241dbfda36a752c350b2fbb439403d206 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1189316 Reviewed-by: Florin Malita <fmalita@google.com> Reviewed-by: Łukasz Anforowicz <lukasza@google.com> Commit-Queue: Florin Malita <fmalita@google.com>Sergio Gonzalez Martin · 5dac00a4 · 2026-08-05
- 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.8ETV[ganesh] More triangulator guards * more speculative fixes for triangulator dereferencing behavior Bug: chromium:473156318 Bug: chromium:470210175 Bug: chromium:546237339 Change-Id: I4d41121c08161b5eebecd46b28c7b8a641477ca2 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1323017 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Thomas Smith <thomsmit@google.com>Thomas Smith · c12ebabc · 2026-08-19
- 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