Skip to content

Render CSS masks, filters, clip paths, and backdrop effects in retained scenes #256

Open
18 of 19 issues completed

Description

@wieslawsoltes

Current checkpoint — 20 September 2026

All effects implementation children are closed except #503, whose WebScene provider and AppScene native consumer are already merged. The open #503 scope is cumulative backdrop pixel, mutation, lifecycle, performance, memory, exact-package, and zero-browser execution; it is not a known missing source slice.

Masks, local SVG/path clips, foreground filters, backdrop blur/saturation, raster resources, multiple/radial mask layers, xor/exclude composition, and Flutter SVG projection are present. Start additional source work only from a reduced current-head failure and attach a focused child first.

Exact recoverable heads: WebScene ef1fa16e100883857804f7b7811ceffbe1a29867, AppScene 762bc24c2fb450385d4e6f963ddf3638b3c258f8, WebScene consolidation #76 020f84fa3912eb6040794f2adf7a5873277cce7c, and local unpushed vscode-demo 8e174f84f975838f11019412675dc3f5c6893614. No validation was executed in this refresh.

Current Code OSS effects status — 19 September 2026

Merged implementation

Remaining effects work

All implementation children through #508 are merged. #503 remains open because execution was deferred, not because an additional implementation slice is known.

Parent epic: #235. Owning workstreams: capability inventory #236 and paint/stacking #241; geometry dependencies belong to #240.

Proven gap

The unchanged VS Code checkout uses SVG/gradient masks for icons and fades, clip-path for editor and accessibility helpers, brightness/grayscale/blur filters, and backdrop blur on onboarding/overlay surfaces. Representative sources include xterm CSS, paneCompositePart.css, chat.css, standalone-tokens.css, and welcome/onboarding styles. The current native capability report explicitly exposes backdrop-filter as unsupported, while #241 has no focused executable plan for masks/filter isolation and resource lifetime.

This issue owns retained-scene representation, compositing, clipping, resource caching, and mutation for these effects. It does not own general layout algorithms or #245 structural invalidation.

Ordered work

  1. Let Publish a versioned CSS capability matrix backed by WPT and native contracts #236 record exact unsupported/partial properties and current executable evidence.
  2. Add WPT-derived parser/computed-value plus fixed-pixel browser/native contracts for mask-image/size/position/repeat/composite, basic filter, backdrop-filter, and reachable clip-path shapes.
  3. Implement the smallest independently testable paint slices in separate commits, preserving stacking-context, opacity, transform, overflow, and rounded-clip order.
  4. Qualify terminal scrollbar/icon masks, workbench icons/fades, editor hidden-text clips, chat gradients, and onboarding blur.

Acceptance and performance gates

  • Each claimed effect has an executable contract and exact boundary; unsupported functions stay explicitly unavailable rather than silently painting as identity.
  • Initial, class/style mutation, resize, scroll, detach/reattach, opacity, transform, and nested-clip cases match Chromium within versioned pixel thresholds and exact scene-command/resource expectations.
  • Backdrop effects sample only the correct prior content and do not leak across stacking contexts, portals, or rounded clips.
  • Resource replacement/reuse is bounded: a 4,096-effect fixture records decode/cache entries, scene nodes, publications, CPU/time, allocations, and peak RSS.
  • One hundred panel/icon mutation cycles return resources and retained scene nodes to the warmed baseline with no monotonic RSS growth.
  • Unsupported hardware paths fail closed with preserved semantic fallback evidence.

Proposed PR stack

  1. syntax/computed values + capability metadata;
  2. masks and clip paths + pixel/resource contracts;
  3. foreground filters;
  4. backdrop isolation/compositing;
  5. performance/lifetime and unchanged-product visual acceptance.

Current effects checkpoint — 19 September 2026

Background/mask/backdrop/filter provider and consumer slices through WebScene ca4fa171 are merged. The latest temporal additions are foreground-filter transitions (#537/#538) and product-used foreground-filter keyframes (#543/#544). #503 remains the cumulative backdrop/effects acceptance owner; AppScene main remains 50da4995 until the active accessibility consumer lands.

No latest-slice pixels, benchmarks, lifecycle/memory runs, package execution, or visual Chromium comparison have run. Keep those as explicit acceptance debt rather than reopening merged implementation children.

Activity

  1. wieslawsoltes commented on Sep 17, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Implementation start boundary (2026-09-17):

    #257 remains deferred until #245 is reconciled.

  2. wieslawsoltes commented on Sep 17, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Final ownership audit before commit:

    This first #256 slice stays limited to product-neutral effect syntax, CSSOM/computed values, mutation, allocation, and cleanup. Retained-scene mask, clip, filter, and backdrop painting remains explicitly unqualified for later #256 work.

  3. wieslawsoltes commented on Sep 17, 2026

    @wieslawsoltes
    CollaboratorAuthor

    First #256 slice merged through PR #282 at 2cf805f1fa8abd5ac56d92d057272a0341aa25b8.

    Qualified in this slice:

    • mask longhand, clip-path, filter, and backdrop-filter syntax/computed values;
    • invalid CSSOM write retention and live class-mutation refresh;
    • native and Chrome contract parity: 1/1 documents, 10/10 subtests on each;
    • 4,096 descendants / 100 cycles / 200 states in 11,171.1 ms, at most 1 retained node, zero settled frame demand, and 7,727,735 accounted peak textual-style bytes under a 32 MiB bound;
    • portable CSS 377/377 on both target frameworks, portable V8, docs, Linux CI, original Native Linux contracts, and independent native-only Linux SDK.

    Final external ownership audit used PR #245 head 5c72775651bc56505e0ef4370cb5265afb4c9605: 64 paths there, 15 paths in #282, 0/64 overlap.

    This issue remains open with vscode-oss/planned: retained-scene mask/clip/filter/backdrop painting and visual acceptance are still unqualified and remain in the later #256 stack. Issue #257 remains deferred pending external #245 reconciliation.

    The rebased checks also confirmed the isolated #255 ABI-contract repair merged through #283 at de85116adcba2cf231c7a731ae82aebc489cf116.

  4. wieslawsoltes commented on Sep 17, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Retained-painting follow-up starts from exact current main aa786c0ea2bbd21599f33caf3795c0eacc19ace3 on feature/css-retained-painting-256.

    The post-#282 gap is exact: effect strings reach computed style and memory accounting, but webscene_native_dom_scene.inc never reads effect_values; therefore clip-path, masks, foreground filters, and backdrop filters emit no retained-scene commands. The smallest independent paint slice is rectangular clip-path: inset(...), because scene kinds 12/13 and every current presenter already provide balanced retained rectangular clipping. This slice can qualify clip ordering without defining new ABI commands or touching #245.

    Initial five-path candidate:

    • retained-scene emission in webscene_native_dom_scene.inc;
    • scene-command/performance/lifecycle assertions in the existing native_css_effect_values_tests.cpp target;
    • a new product-neutral inset-clip reftest and reference;
    • a dedicated profile.

    Ownership audit: #245 exact head d95831cc2018b6ea950670261f6a927bbd9f31ec, 77 paths, 0/5 overlap. The local-only #286 four-path candidate also has 0/5 overlap. I will establish Chromium/native pixel and exact scene-command baselines before implementation. Masks, circle/ellipse/polygon/path clips, filters, and backdrop isolation stay explicitly unclaimed.

  5. wieslawsoltes commented on Sep 17, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Local candidate committed as 5034f88d67edfdaf303e09009dcf33c04bf6737c on feature/css-retained-painting-256 (not pushed; no PR).

    This closes the smallest remaining retained-painting slice after #282: strict rectangular clip-path: inset(...) now emits balanced existing scene clip commands around the element and descendants. It supports 1–4 px/% values and unitless zero, resolves percentages against the border box, and rejects unsupported shapes/units/round without changing the scene ABI or presenters. Parsing in the scene hot path is allocation-free. Transform nesting is asserted as transform begin → clip begin → paint → clip end → transform end.

    Focused evidence:

    • Release native contract: PASS; 4,096 effects, 100 scale cycles in 18,870.5 ms, 4,099 textual-style entries / 7,727,735 bytes, 12,294 commands / 639,288 bytes, 4,096 balanced clips and fills, transform/clip nesting true.
    • Publication/lifecycle: PASS; one live mutation node, 100 cycles / 200 acknowledged publications in 4,136.77 ms, settled frame demand 0, retained DOM-node delta 0 after cleanup.
    • Exact visual oracle: PASS 1/1 in Chromium and native, 240×160 fixture, 0 differing pixels; covers pixel and percentage insets, overflowing descendants, and class mutation.
    • The 25-second scale ceiling reflects current-main baseline evidence: the same Release workload with retained clip emission temporarily disabled measured 19,523.9 ms; the final allocation-free implementation measured 18,870.5 ms.

    Final collision audit immediately before commit: live #245 head 4f9c3ba3e1926a3d6b93db3586834c167541f6ba, 86 paths, overlap 0/5. Local #286 candidate overlap is also 0/5.

    Remaining owner split: masks, circle/ellipse/polygon/path clips, foreground filters, backdrop effects, and effect-driven stacking/isolation remain separate follow-ups. This tranche adds no implementation in those owners.

  6. wieslawsoltes commented on Sep 17, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Focused retained-painting PR opened: #290.

    #290 covers rectangular clip-path: inset(...) painting only. The parent remains open for nonrectangular clips, masks, filters, backdrop effects, and stacking/isolation.

  7. wieslawsoltes commented on Sep 17, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Rectangular retained-painting PR #290 merged to main at 140ec345 after its focused native Linux workflow passed the original document/compiler contracts and independent native-only Linux SDK. The rebased local certification-enabled Release gate passed in 17.15 seconds, and native/Chromium visual comparison passed 1/1 with zero differing pixels. The issue remains open for nonrectangular clips, masks, filters, backdrop effects, and effect-driven stacking/isolation.

  8. wieslawsoltes commented on Sep 18, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Focused retained-paint child #449 is complete through PR #451 at merge 3813a31772917655f71be8a15b04aeb096a049d8 (source 8ffbd20c99fb4d8a75cd1a4cf52df599495ca791).

    The retained scene now paints centered clip-path: circle(<length-or-percentage>) shapes. Percentages use the CSS normalized diagonal, and the resolved circle is emitted as balanced existing rounded clip commands around the element and descendant paint. Transform and opacity ordering remains unchanged. The change is one source file and adds no ABI command, capability bit, resource type, or presenter change.

    The slice deliberately leaves positioned circles, radius keywords, ellipses, polygons, paths, masks, foreground filters, backdrop effects, and effect-driven isolation open. In particular, unchanged Code OSS's Markdown diff indicator uses polygon(...); that needs a separate representation rather than an approximation through rounded clips.

    Implementation throughput was the explicit priority. Tests, browser/native pixel contracts, performance/lifecycle benchmarks, hosted checks, CI monitoring, and exact-package visual acceptance were skipped and remain validation debt. No broader support or release claim is made.

  9. wieslawsoltes commented on Sep 18, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Focused Code OSS polygon child #456 is complete through PR #458 at merge a9f309c8ff80d701ef34e66aece8441e0f8f7fb6 (source bdcab00337e0f9035a50b44efa8f84344e62cc64).

    The retained scene now paints the unchanged Code OSS Markdown diff indicator's six-point clip-path: polygon(...). Native emission accepts a bounded default-fill-rule subset of 3–64 px/%/zero point pairs, resolves them against the border box, and stores one closed SVG path. Existing clip kind 12 uses an opt-in top flag bit plus the scene string index; kind 13 remains the balanced end. Avalonia and Uno use the shared Skia path clip, and Flutter uses its existing path parser. Existing inset/circle clips keep their prior zero-flag rounded geometry.

    This adds no scene struct, version, capability, or command-kind change. Fill-rule arguments, calc() and other units, ellipse/path/url clips, masks, foreground filters, backdrop effects, and effect-driven isolation remain open.

    Implementation throughput was the explicit priority. Tests, browser/native pixel contracts, performance/lifecycle benchmarks, hosted checks, CI monitoring, and exact-package visual acceptance were skipped and remain validation debt. No broader support or release claim is made.

  10. wieslawsoltes commented on Sep 18, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Focused foreground-filter child #463 is complete through PR #464 at merge d27290970ef4913b89a083da89a220726ee5e29b (source 88a820091f131738115790d8e50c534a473c98d6).

    The retained scene now paints single-function filter: brightness(<number-or-percentage>) values used by unchanged Code OSS release notes, issue reporter, Chat status/debug, and dictation surfaces. Native emission accepts a bounded 0–10 multiplier, wraps the element and descendants in the existing kind 30/31 group, and marks non-none foreground filters as atomic stacking contexts. Kind 30's top flag bit selects brightness and stroke_width carries the multiplier; zero-flag opacity groups retain their existing behavior. Avalonia/Uno and Flutter apply equivalent RGB color matrices.

    This adds no scene struct, version, capability, or command-kind change. Compound filters, filter animation/interpolation, blur and expanded damage, other filter functions, masks, backdrop sampling, and remaining isolation work stay open.

    Implementation throughput was the explicit priority. Tests, browser/native pixel contracts, performance/lifecycle benchmarks, hosted checks, CI monitoring, and exact-package visual acceptance were skipped and remain validation debt. No broader support or release claim is made.

  11. 4 remaining items

  12. wieslawsoltes commented on Sep 18, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Foreground blur slice #485 / PR #486 is merged at 9c6e3b98. The epic body now records the completed retained blur path and the remaining order: compound/function-valued filters, damage expansion, masks, backdrop sampling, remaining clip shapes, then cumulative visual/performance/memory/package/CI qualification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    vscode-oss/plannedPlanned for the AppScene/WebScene VS Code OSS integration

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions