skia — Engineering Performance
23 engineers all time · Jan 2025 – Sep 2026 · built 2026-09-30 · 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.
Avg. perf / dev / mo
+37.8%
0.83 → 1.15 ETV
Active engineers
−38.1%
21.0 → 13.0
Features
+3.8pp
25.6% → 29.4%
vs. Google
0.41x
0.89x → 0.41x · −59% below
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 Composition
Each month's output split by type of work: Features (new value), Maintenance (sustaining systems), Tests, Docs, and Fixes (rework). The yellow line is output per engineer, so when it rises each engineer is delivering more, whatever the team size did. Unit: Engineering Throughput Value (ETV).
Engineering capacity
Effective engineers behind skia, against its pre-AI baseline. Each subject has its own: skia's is 0.83 ETV / dev / mo, its first reading in Q1 2025. Per-engineer ETV divided by that 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. Because each baseline is its own, every subject opens at 1.0x on its first day: multiples measure improvement and are not comparable between subjects.
Knowledge concentration
How dependent is this repo on a small number of engineers? Higher top-1 share = higher key-person risk.
Kaylee Lubick owns 17.9 % of commits.
Behind the numbers
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.3ETV[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.5ETV[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.2ETVReconstruct 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
- 2.1ETV[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
- 2.0ETV[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
- 2.0ETVRevert "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
- 2.0ETV[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.9ETV[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.9ETV[text] Introduce PackedGPUGlyphID to add more metadata to SkPackedGlyphID Both Ganesh and Graphite share a lot of common structure to their glyph handling code, so the changes outlined below are applied pretty similarly to both codebases. 1. Adds a new shared type PackedGPUGlyphID that wraps SkPackedGlyphID and packs into the free bits the rest of the information that atlas-backed glyphs require, which is the mask format, the amount of padding, and whether or not the data is a coverage or distance value. 2. Pulls back the presence of MaskFormat from the GlyphVector concepts and functions as it's now handled internally by each backend's GlyphData classes and embedded into the packed GPU IDs that they make. 3. Each backend's TextStrike implementation stores PackedGPUGlyphIDs as the keys to GlyphEntries instead of SkPackedGlyphIDs. This ensures that an atlas will only have a cache hit if all of the mask/padding/data-type properties are consistent with what was in the atlas and what is requested by the subrun being drawn. 4. Each backend's GlyphData implementation takes in these additional properties in its constructor (propagating to initBackendData() calls). It then resolves the mask format and padding with the configuration of the backend's atlas manager so that all subsequent PackedGPUGlyphIDs that it makes represent the final configuration. 5. The atlas manager's now require the format and padding to be pre-resolved in many of their functions, such that 565 has been lifted to RGBA8 and 1px of padding is added for direct masks if the caps require all direct masks to have padding (this automatically makes transformed mask subrun glyphs and direct mask subrun glyphs key the same when fSupportBilerpAtlas is true). Backend-specific changes for Graphite: The properties that GlyphData requires for filling out the PackedGPUGlyphID are basically the `sktext::gpu::RendererData` that was being stored in the SubRunData object. I added the srcPadding to it and then made it accessible from GlyphData, so it could be removed from SubRunData. This keeps the number of arguments to the various functions fairly concise. As part of this, RendererData moved from SubRunContainer.h to GlyphVector.h Backend-specific changes for Ganesh: Ganesh didn't use RendererData, so its GlyphData just takes the parameters in directly and from the AtlasTextOp. Its GlyphData class also had an unused declared constructor that I removed, and GrAtlasManager::addToAtlas() could be made private (which made enforcing resolvedMaskFormat easier). Bug: 514078656 Change-Id: I07977910f64d84e15fe6e4c687d8635afb356b7c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1292556 Reviewed-by: Alexis Cruz-Ayala <alexisdavidc@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>Michael Ludwig · f82e81ea · 2026-07-31
- 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