Skip to content

Fix JavaScript glass tab lens rendering#5388

Open
shai-almog wants to merge 14 commits into
masterfrom
fix-javascript-glass-tabs-lens
Open

Fix JavaScript glass tab lens rendering#5388
shai-almog wants to merge 14 commits into
masterfrom
fix-javascript-glass-tabs-lens

Conversation

@shai-almog

@shai-almog shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • implement the missing glassRegion in the JavaSE port — a step-for-step mirror of IOSImplementation's offscreen Liquid Glass branch (padded edge-replicated backdrop read, affine colour material, Gaussian blur, SDF optics: edge refraction + specular rim + AA shape mask)
  • replace the JavaScript glass-tab lens fallback (uniform zoom + flat tint) with the same per-pixel lens and full glass recipe used by JavaSE and iOS
  • lock all four backends (JavaScript, JavaSE, iOS CPU reference, Metal shader) together with a constant-parity + pixel-CRC script; the JS lens output is bit-identical to JavaSEPort.applyLensBuffer at all seven probe points
  • add a deterministic JavaSE frame probe and an opt-in cn1.javase.pixelMilliRatio density override for reference-resolution captures
  • keep the shared morph model, Metal shader, and iOS-modern theme at master's blessed tuning (the committed ios-26-metal-frames goldens and the developer-guide fidelity image)
  • record the native tab-morph reference videos with REAL taps (XCUITest tap driver): UIKit plays the full Liquid Glass morph only for touch-driven selection, and the old programmatic recording captured a flat platter that had misled tuning
  • refine the RoundBorder gradient stroke: the hairline ring is now three clip-registered passes (background, gradient over it, interior restored) that render a uniform luminous rim on every port -- the old two-fill construction read as broken muddy segments, and a multi-contour winding ring broke on the iOS/Metal clip rasterizer
  • refresh JavaScript / iOS / watchOS screenshot goldens from their CI artifacts for the new glass pipeline and stroke

Root cause

The simulator and JavaScript port looked wrong for two independent reasons, neither of which was the shared morph model:

  1. JavaSE had no glassRegion implementation. The tab bar's Liquid Glass material silently fell back to a plain blur, leaving the bar a flat grey (156) where the device renders a bright frost (240). The selection lens then magnified that grey substrate, so every in-flight frame read as a murky smudge regardless of tuning.
  2. The JavaScript port discarded the material parameters, reducing the foreground lens to a uniform zoom and flat tint, and glassRegion to a plain blur.

An earlier iteration of this PR instead re-tuned the shared model against the grey-backdrop phone recording (goldens/ios-26-metal-anim/native-tabs-light.mov), which flattened the effect on every port including iOS and diverged from the committed Metal goldens. That re-tuning is reverted; the recording and the fidelity capture disagree about the material and the goldens are the canonical target.

Validation

  • JavaSE render of TabsMorph_t050_light now matches the committed Metal golden at matched anatomy to ~1 LSB: bar (240,240,240) vs (240,240,240), bubble interior (234,236,240) vs (235,237,240); settled and dark frames match equivalently
  • node scripts/verify-javascript-lens-parity.mjs: 14 constants pinned across 4 backends; JS lens CRCs bit-identical to JavaSE at t=0/10/25/50/75/90/100; glass material + optics CRCs pass
  • full JavaSE port rebuild + 14-frame light/dark probe render completed locally
  • git diff --check

@github-actions

Copy link
Copy Markdown
Contributor

Cloudflare Preview

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 176 screenshots: 176 matched.
✅ JavaScript-port screenshot tests passed.

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

✅ ByteCodeTranslator Quality Report

Test & Coverage

  • Tests: 395 total, 0 failed, 14 skipped

Benchmark Results

  • Execution Time: 19216 ms

  • Hotspots (Top 20 sampled methods):

    • 24.43% java.util.ArrayList.indexOf (406 samples)
    • 8.42% com.codename1.tools.translator.BytecodeMethod.addToConstantPool (140 samples)
    • 2.95% com.codename1.tools.translator.ByteCodeClass.hasDeclaredMethod (49 samples)
    • 2.77% com.codename1.tools.translator.Parser.cn1EnsureSubclassIndex (46 samples)
    • 2.71% org.objectweb.asm.tree.analysis.Analyzer.findSubroutine (45 samples)
    • 2.53% java.lang.StringBuilder.append (42 samples)
    • 2.35% com.codename1.tools.translator.Parser.generateClassAndMethodIndexHeader (39 samples)
    • 1.99% com.codename1.tools.translator.BytecodeMethod.optimize (33 samples)
    • 1.93% org.objectweb.asm.tree.analysis.Analyzer.analyze (32 samples)
    • 1.81% com.codename1.tools.translator.BytecodeMethod.equals (30 samples)
    • 1.68% java.lang.String.equals (28 samples)
    • 1.62% java.util.HashMap.hash (27 samples)
    • 1.56% java.lang.System.identityHashCode (26 samples)
    • 1.50% com.codename1.tools.translator.bytecodes.Invoke.resolveDirectTarget (25 samples)
    • 1.38% com.codename1.tools.translator.BytecodeMethod.appendCMethodPrefix (23 samples)
    • 1.26% com.codename1.tools.translator.Parser.isMethodUsed (21 samples)
    • 1.14% java.lang.Object.hashCode (19 samples)
    • 0.96% java.util.TreeMap.getEntry (16 samples)
    • 0.90% com.codename1.tools.translator.BytecodeMethod.updateInlinableFieldDependencies (15 samples)
    • 0.90% com.codename1.tools.translator.bytecodes.Invoke.findMethodUp (15 samples)
  • ⚠️ Coverage report not generated.

Static Analysis

  • ✅ SpotBugs: no findings (report was not generated by the build).
  • ⚠️ PMD report not generated.
  • ⚠️ Checkstyle report not generated.

Generated automatically by the PR CI workflow.

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 145 screenshots: 145 matched.
Native Windows port, REAL shipping pipeline: the hellocodenameone screenshot suite rendered by a binary CROSS-COMPILED on Linux (clang-cl + xwin, WebView2 linked) and RUN on a Windows x64 runner. Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 73ms / native 5ms = 14.6x speedup
SIMD float-mul (64K x300) java 68ms / native 4ms = 17.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 201.000 ms
Base64 CN1 decode 139.000 ms
Base64 SIMD encode 128.000 ms
Base64 encode ratio (SIMD/CN1) 0.637x (36.3% faster)
Base64 SIMD decode 87.000 ms
Base64 decode ratio (SIMD/CN1) 0.626x (37.4% faster)
Image encode benchmark iterations 100

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 145 screenshots: 145 matched.
Native Windows port (x64 / Intel-AMD): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, SSE2 SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 68ms / native 5ms = 13.6x speedup
SIMD float-mul (64K x300) java 80ms / native 5ms = 16.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 191.000 ms
Base64 CN1 decode 130.000 ms
Base64 SIMD encode 101.000 ms
Base64 encode ratio (SIMD/CN1) 0.529x (47.1% faster)
Base64 SIMD decode 89.000 ms
Base64 decode ratio (SIMD/CN1) 0.685x (31.5% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 22.000 ms

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 145 screenshots: 145 matched.
Native Windows port (arm64 / Apple Silicon - Arm): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, NEON SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 57ms / native 3ms = 19.0x speedup
SIMD float-mul (64K x300) java 57ms / native 3ms = 19.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 248.000 ms
Base64 CN1 decode 130.000 ms
Base64 SIMD encode 63.000 ms
Base64 encode ratio (SIMD/CN1) 0.254x (74.6% faster)
Base64 SIMD decode 57.000 ms
Base64 decode ratio (SIMD/CN1) 0.438x (56.2% faster)
Image encode benchmark iterations 100

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 146 screenshots: 146 matched.
Native Linux port (x64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub x64 runner. Baseline: scripts/linux/screenshots.

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 146 screenshots: 146 matched.
Native Linux port (arm64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub arm64 runner. Baseline: scripts/linux/screenshots-arm.

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 148 screenshots: 148 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 400 seconds

Build and Run Timing

Metric Duration
Simulator Boot 103000 ms
Simulator Boot (Run) 1000 ms
App Install 12000 ms
App Launch 3000 ms
Test Execution 375000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 58ms / native 3ms = 19.3x speedup
SIMD float-mul (64K x300) java 59ms / native 3ms = 19.6x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 168.000 ms
Base64 CN1 decode 163.000 ms
Base64 native encode 328.000 ms
Base64 encode ratio (CN1/native) 0.512x (48.8% faster)
Base64 native decode 863.000 ms
Base64 decode ratio (CN1/native) 0.189x (81.1% faster)
Base64 SIMD encode 52.000 ms
Base64 encode ratio (SIMD/CN1) 0.310x (69.0% faster)
Base64 SIMD decode 49.000 ms
Base64 decode ratio (SIMD/CN1) 0.301x (69.9% faster)
Base64 encode ratio (SIMD/native) 0.159x (84.1% faster)
Base64 decode ratio (SIMD/native) 0.057x (94.3% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 8.000 ms
Image createMask (SIMD on) 3.000 ms
Image createMask ratio (SIMD on/off) 0.375x (62.5% faster)
Image applyMask (SIMD off) 43.000 ms
Image applyMask (SIMD on) 96.000 ms
Image applyMask ratio (SIMD on/off) 2.233x (123.3% slower)
Image modifyAlpha (SIMD off) 66.000 ms
Image modifyAlpha (SIMD on) 117.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.773x (77.3% slower)
Image modifyAlpha removeColor (SIMD off) 119.000 ms
Image modifyAlpha removeColor (SIMD on) 106.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.891x (10.9% faster)

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 143 screenshots: 143 matched.
✅ Native Apple TV (tvOS, Metal) screenshot tests passed.

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 147 screenshots: 147 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 168 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 53ms / native 3ms = 17.6x speedup
SIMD float-mul (64K x300) java 52ms / native 3ms = 17.3x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 164.000 ms
Base64 CN1 decode 143.000 ms
Base64 native encode 1016.000 ms
Base64 encode ratio (CN1/native) 0.161x (83.9% faster)
Base64 native decode 547.000 ms
Base64 decode ratio (CN1/native) 0.261x (73.9% faster)
Base64 SIMD encode 79.000 ms
Base64 encode ratio (SIMD/CN1) 0.482x (51.8% faster)
Base64 SIMD decode 46.000 ms
Base64 decode ratio (SIMD/CN1) 0.322x (67.8% faster)
Base64 encode ratio (SIMD/native) 0.078x (92.2% faster)
Base64 decode ratio (SIMD/native) 0.084x (91.6% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 23.000 ms
Image createMask (SIMD on) 24.000 ms
Image createMask ratio (SIMD on/off) 1.043x (4.3% slower)
Image applyMask (SIMD off) 169.000 ms
Image applyMask (SIMD on) 199.000 ms
Image applyMask ratio (SIMD on/off) 1.178x (17.8% slower)
Image modifyAlpha (SIMD off) 194.000 ms
Image modifyAlpha (SIMD on) 178.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.918x (8.2% faster)
Image modifyAlpha removeColor (SIMD off) 155.000 ms
Image modifyAlpha removeColor (SIMD on) 172.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 1.110x (11.0% slower)

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 142 screenshots: 142 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 429 seconds

Build and Run Timing

Metric Duration
Simulator Boot 96000 ms
Simulator Boot (Run) 0 ms
App Install 15000 ms
App Launch 1000 ms
Test Execution 475000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 83ms / native 3ms = 27.6x speedup
SIMD float-mul (64K x300) java 178ms / native 15ms = 11.8x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 503.000 ms
Base64 CN1 decode 244.000 ms
Base64 native encode 1656.000 ms
Base64 encode ratio (CN1/native) 0.304x (69.6% faster)
Base64 native decode 951.000 ms
Base64 decode ratio (CN1/native) 0.257x (74.3% faster)
Base64 SIMD encode 69.000 ms
Base64 encode ratio (SIMD/CN1) 0.137x (86.3% faster)
Base64 SIMD decode 126.000 ms
Base64 decode ratio (SIMD/CN1) 0.516x (48.4% faster)
Base64 encode ratio (SIMD/native) 0.042x (95.8% faster)
Base64 decode ratio (SIMD/native) 0.132x (86.8% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 7.000 ms
Image createMask (SIMD on) 5.000 ms
Image createMask ratio (SIMD on/off) 0.714x (28.6% faster)
Image applyMask (SIMD off) 118.000 ms
Image applyMask (SIMD on) 63.000 ms
Image applyMask ratio (SIMD on/off) 0.534x (46.6% faster)
Image modifyAlpha (SIMD off) 112.000 ms
Image modifyAlpha (SIMD on) 121.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.080x (8.0% slower)
Image modifyAlpha removeColor (SIMD off) 116.000 ms
Image modifyAlpha removeColor (SIMD on) 46.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.397x (60.3% faster)

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 216 screenshots: 216 matched.
✅ Native Apple Watch (watchOS, Core Graphics) screenshot tests passed.

@shai-almog

shai-almog commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator Author

Native fidelity (Android, Material 3)

54 pairs compared -- median 95.6%, worst 91.3% (FlatButton_pressed_dark), 25th pct 94.9%, mean 95.7%.

Distribution -- >=99%: 2 | 95-99%: 37 | 90-95%: 15 | <90%: 0

Component State Appearance Material Fidelity SSIM mean delta vs base Geometry
FlatButton pressed dark normal 91.3% 0.899 3.10 0.0 ok
Tabs normal light normal 92.3% 0.914 3.05 0.0 ok
Button pressed dark normal 92.6% 0.949 4.32 0.0 ok
FlatButton normal dark normal 93.2% 0.938 2.69 0.0 ok
Button disabled dark normal 93.3% 0.928 2.20 0.0 ok
Button pressed light normal 93.3% 0.952 3.68 0.0 ok
FlatButton normal light normal 93.7% 0.941 2.29 0.0 ok
FlatButton pressed light normal 93.8% 0.942 2.56 0.0 ok
FloatingActionButton pressed light normal 94.4% 0.927 2.82 0.0 OFF (h 0.88)
RadioButton normal dark normal 94.5% 0.963 2.19 0.0 ok
RadioButton normal light normal 94.7% 0.964 1.85 0.0 ok
CheckBox selected dark normal 94.7% 0.950 2.60 0.0 ok
RadioButton selected dark normal 94.8% 0.963 2.42 0.0 ok
CheckBox normal dark normal 94.9% 0.952 2.69 0.0 ok
Button normal dark normal 94.9% 0.949 3.16 0.0 ok
CheckBox normal light normal 95.0% 0.953 2.30 0.0 ok
Toolbar normal dark normal 95.1% 0.906 1.60 0.0 ok
RaisedButton pressed dark normal 95.2% 0.950 2.39 0.0 ok
CheckBox disabled dark normal 95.2% 0.954 1.47 0.0 ok
CheckBox disabled light normal 95.2% 0.956 1.34 0.0 ok
Tabs normal dark normal 95.2% 0.913 3.65 0.0 ok
RadioButton disabled dark normal 95.3% 0.963 1.18 0.0 ok
RadioButton selected light normal 95.3% 0.964 1.84 0.0 ok
CheckBox selected light normal 95.4% 0.952 2.06 0.0 ok
Switch selected light normal 95.4% 0.966 1.59 0.0 ok
Switch selected dark normal 95.5% 0.966 1.86 0.0 ok
RadioButton disabled light normal 95.5% 0.966 1.08 0.0 ok
Switch disabled dark normal 95.6% 0.961 0.85 0.0 ok
Dialog normal light normal 95.7% 0.930 2.30 0.0 ok
RaisedButton pressed light normal 95.8% 0.958 2.16 0.0 ok
Button normal light normal 95.8% 0.953 2.46 0.0 ok
Dialog normal dark normal 95.8% 0.932 2.30 0.0 ok
Switch normal light normal 96.0% 0.961 1.45 0.0 ok
FloatingActionButton normal light normal 96.1% 0.937 1.14 0.0 ok
FloatingActionButton pressed dark normal 96.2% 0.951 2.45 0.0 ok
Switch normal dark normal 96.2% 0.962 1.39 0.0 ok
TextField disabled dark normal 96.2% 0.965 0.76 0.0 ok
RaisedButton normal dark normal 96.4% 0.952 1.78 0.0 ok
Switch disabled light normal 96.4% 0.970 0.61 0.0 ok
Button disabled light normal 96.8% 0.960 1.06 0.0 ok
ProgressBar normal dark normal 96.9% 0.967 2.03 0.0 OFF (h 1.50)
RaisedButton disabled dark normal 97.0% 0.955 0.89 0.0 ok
FloatingActionButton normal dark normal 97.1% 0.952 1.43 0.0 ok
ProgressBar normal light normal 97.3% 0.974 1.53 0.0 OFF (h 1.50)
RaisedButton disabled light normal 97.3% 0.961 0.79 0.0 ok
TextField disabled light normal 97.3% 0.965 0.79 0.0 ok
RaisedButton normal light normal 97.3% 0.961 1.40 0.0 ok
TextField normal dark normal 97.6% 0.958 1.83 0.0 ok
TextField normal light normal 97.6% 0.958 1.63 0.0 ok
Slider normal dark normal 98.4% 0.990 0.87 0.0 ok
Toolbar normal light normal 98.7% 0.974 1.28 0.0 ok
Slider normal light normal 99.0% 0.991 0.47 0.0 ok
Slider disabled dark normal 99.6% 0.993 0.22 0.0 ok
Slider disabled light normal 99.6% 0.993 0.18 0.0 ok
Geometry vs native (bbox offset / size ratio / center offset / corner radius) -- gated separately from the visual score
Component State Appearance bbox dx,dy (px) w ratio h ratio center off (px) radius native->cn1 (px)
FloatingActionButton pressed light +0,+0 0.929 0.881 4.0 -
FloatingActionButton normal light +0,+0 0.946 0.912 2.9 -
Button pressed dark +0,+0 0.947 0.975 2.6 -
Button disabled dark +0,+0 0.947 0.975 2.6 -
Button pressed light +0,+0 0.947 0.975 2.6 -
Button normal dark +0,+0 0.947 0.975 2.6 -
RaisedButton pressed dark +0,+0 0.945 0.975 2.6 -
RaisedButton pressed light +0,+0 0.945 0.975 2.6 -
Button normal light +0,+0 0.947 0.975 2.6 -
RaisedButton normal dark +0,+0 0.945 0.975 2.6 -
Button disabled light +0,+0 0.947 0.975 2.6 -
RaisedButton disabled dark +0,+0 0.945 0.975 2.6 -
RaisedButton disabled light +0,+0 0.945 0.975 2.6 -
RaisedButton normal light +0,+0 0.945 0.975 2.6 -
RadioButton normal dark +1,+1 1.029 1.000 2.2 -
RadioButton normal light +1,+1 1.029 1.000 2.2 -
RadioButton selected dark +1,+1 1.029 1.000 2.2 -
RadioButton disabled dark +1,+1 1.029 1.000 2.2 -
RadioButton selected light +1,+1 1.029 1.000 2.2 -
Switch selected light +0,+0 1.080 1.063 2.2 -
RadioButton disabled light +1,+1 1.029 1.000 2.2 -
CheckBox selected dark +1,+1 1.013 1.000 1.8 -
CheckBox normal dark +1,+1 1.013 1.000 1.8 -
CheckBox normal light +1,+1 1.013 1.000 1.8 -
CheckBox disabled dark +1,+1 1.013 1.000 1.8 -
CheckBox disabled light +1,+1 1.013 1.000 1.8 -
CheckBox selected light +1,+1 1.013 1.000 1.8 -
Switch selected dark +0,+0 1.060 1.031 1.6 -
Switch disabled dark +0,-1 1.060 1.031 1.6 -
Dialog normal light +0,+0 1.007 0.982 1.6 -
Dialog normal dark +0,+0 1.007 0.982 1.6 -
Switch normal light +0,-1 1.060 1.031 1.6 -
Switch normal dark +0,-1 1.060 1.031 1.6 -
Switch disabled light +0,-1 1.060 1.031 1.6 -
FloatingActionButton pressed dark +0,+0 0.963 0.963 1.4 -
FloatingActionButton normal dark +0,+0 0.963 0.963 1.4 -
Toolbar normal light -1,+1 1.000 1.000 1.4 -
FlatButton pressed dark +0,+0 0.977 0.975 1.1 -
FlatButton normal dark +0,+0 0.977 0.975 1.1 -
FlatButton normal light +0,+0 0.977 0.975 1.1 -
FlatButton pressed light +0,+0 0.977 0.975 1.1 -
TextField normal dark +0,+0 1.015 1.036 1.1 -
TextField normal light +0,+0 1.015 1.036 1.1 -
Toolbar normal dark +0,+0 1.000 1.032 1.0 -
ProgressBar normal dark +0,+0 1.000 1.500 1.0 -
ProgressBar normal light +0,+0 1.000 1.500 1.0 -
TextField disabled dark +0,+0 1.015 1.018 0.7 -
TextField disabled light +0,+0 1.015 1.018 0.7 -
Tabs normal light +0,+1 1.000 0.984 0.5 -
Slider normal dark +1,+0 0.996 1.000 0.5 -
Slider normal light +1,+0 0.996 1.000 0.5 -
Tabs normal dark +0,+0 1.000 1.000 0.0 -
Slider disabled dark +0,+0 1.000 1.000 0.0 -
Slider disabled light +0,+0 1.000 1.000 0.0 -

Side-by-side comparisons (worst first)

  • FlatButton_pressed_dark -- 91.25% fidelity (SSIM 0.8985) (no change)

    native FlatButton_pressed_dark cn1 FlatButton_pressed_dark
    Left: native widget. Right: Codename One render.

  • Tabs_normal_light -- 92.28% fidelity (SSIM 0.9140) (no change)

    native Tabs_normal_light cn1 Tabs_normal_light
    Left: native widget. Right: Codename One render.

  • Button_pressed_dark -- 92.61% fidelity (SSIM 0.9485) (no change)

    native Button_pressed_dark cn1 Button_pressed_dark
    Left: native widget. Right: Codename One render.

  • FlatButton_normal_dark -- 93.24% fidelity (SSIM 0.9381) (no change)

    native FlatButton_normal_dark cn1 FlatButton_normal_dark
    Left: native widget. Right: Codename One render.

  • Button_disabled_dark -- 93.26% fidelity (SSIM 0.9278) (no change)

    native Button_disabled_dark cn1 Button_disabled_dark
    Left: native widget. Right: Codename One render.

  • Button_pressed_light -- 93.34% fidelity (SSIM 0.9521) (no change)

    native Button_pressed_light cn1 Button_pressed_light
    Left: native widget. Right: Codename One render.

  • FlatButton_normal_light -- 93.72% fidelity (SSIM 0.9410) (no change)

    native FlatButton_normal_light cn1 FlatButton_normal_light
    Left: native widget. Right: Codename One render.

  • FlatButton_pressed_light -- 93.77% fidelity (SSIM 0.9424) (no change)

    native FlatButton_pressed_light cn1 FlatButton_pressed_light
    Left: native widget. Right: Codename One render.

  • FloatingActionButton_pressed_light -- 94.44% fidelity (SSIM 0.9273) (no change)

    native FloatingActionButton_pressed_light cn1 FloatingActionButton_pressed_light
    Left: native widget. Right: Codename One render.

  • RadioButton_normal_dark -- 94.46% fidelity (SSIM 0.9630) (no change)

    native RadioButton_normal_dark cn1 RadioButton_normal_dark
    Left: native widget. Right: Codename One render.

  • RadioButton_normal_light -- 94.69% fidelity (SSIM 0.9643) (no change)

    native RadioButton_normal_light cn1 RadioButton_normal_light
    Left: native widget. Right: Codename One render.

  • CheckBox_selected_dark -- 94.71% fidelity (SSIM 0.9502) (no change)

    native CheckBox_selected_dark cn1 CheckBox_selected_dark
    Left: native widget. Right: Codename One render.

  • RadioButton_selected_dark -- 94.79% fidelity (SSIM 0.9630) (no change)

    native RadioButton_selected_dark cn1 RadioButton_selected_dark
    Left: native widget. Right: Codename One render.

  • CheckBox_normal_dark -- 94.93% fidelity (SSIM 0.9516) (no change)

    native CheckBox_normal_dark cn1 CheckBox_normal_dark
    Left: native widget. Right: Codename One render.

  • Button_normal_dark -- 94.94% fidelity (SSIM 0.9491) (no change)

    native Button_normal_dark cn1 Button_normal_dark
    Left: native widget. Right: Codename One render.

  • CheckBox_normal_light -- 95.03% fidelity (SSIM 0.9531) (no change)

    native CheckBox_normal_light cn1 CheckBox_normal_light
    Left: native widget. Right: Codename One render.

  • Toolbar_normal_dark -- 95.07% fidelity (SSIM 0.9059) (no change)

    native Toolbar_normal_dark cn1 Toolbar_normal_dark
    Left: native widget. Right: Codename One render.

  • RaisedButton_pressed_dark -- 95.19% fidelity (SSIM 0.9501) (no change)

    native RaisedButton_pressed_dark cn1 RaisedButton_pressed_dark
    Left: native widget. Right: Codename One render.

  • CheckBox_disabled_dark -- 95.20% fidelity (SSIM 0.9538) (no change)

    native CheckBox_disabled_dark cn1 CheckBox_disabled_dark
    Left: native widget. Right: Codename One render.

  • CheckBox_disabled_light -- 95.21% fidelity (SSIM 0.9562) (no change)

    native CheckBox_disabled_light cn1 CheckBox_disabled_light
    Left: native widget. Right: Codename One render.

  • Tabs_normal_dark -- 95.23% fidelity (SSIM 0.9125) (no change)

    native Tabs_normal_dark cn1 Tabs_normal_dark
    Left: native widget. Right: Codename One render.

  • RadioButton_disabled_dark -- 95.29% fidelity (SSIM 0.9630) (no change)

    native RadioButton_disabled_dark cn1 RadioButton_disabled_dark
    Left: native widget. Right: Codename One render.

  • RadioButton_selected_light -- 95.33% fidelity (SSIM 0.9642) (no change)

    native RadioButton_selected_light cn1 RadioButton_selected_light
    Left: native widget. Right: Codename One render.

  • CheckBox_selected_light -- 95.37% fidelity (SSIM 0.9524) (no change)

    native CheckBox_selected_light cn1 CheckBox_selected_light
    Left: native widget. Right: Codename One render.

  • Switch_selected_light -- 95.37% fidelity (SSIM 0.9658) (no change)

    native Switch_selected_light cn1 Switch_selected_light
    Left: native widget. Right: Codename One render.

  • Switch_selected_dark -- 95.45% fidelity (SSIM 0.9656) (no change)

    native Switch_selected_dark cn1 Switch_selected_dark
    Left: native widget. Right: Codename One render.

  • RadioButton_disabled_light -- 95.46% fidelity (SSIM 0.9657) (no change)

    native RadioButton_disabled_light cn1 RadioButton_disabled_light
    Left: native widget. Right: Codename One render.

  • Switch_disabled_dark -- 95.57% fidelity (SSIM 0.9613) (no change)

    native Switch_disabled_dark cn1 Switch_disabled_dark
    Left: native widget. Right: Codename One render.

  • Dialog_normal_light -- 95.65% fidelity (SSIM 0.9300) (no change)

    native Dialog_normal_light cn1 Dialog_normal_light
    Left: native widget. Right: Codename One render.

  • RaisedButton_pressed_light -- 95.78% fidelity (SSIM 0.9578) (no change)

    native RaisedButton_pressed_light cn1 RaisedButton_pressed_light
    Left: native widget. Right: Codename One render.

  • Button_normal_light -- 95.79% fidelity (SSIM 0.9528) (no change)

    native Button_normal_light cn1 Button_normal_light
    Left: native widget. Right: Codename One render.

  • Dialog_normal_dark -- 95.79% fidelity (SSIM 0.9322) (no change)

    native Dialog_normal_dark cn1 Dialog_normal_dark
    Left: native widget. Right: Codename One render.

  • Switch_normal_light -- 95.97% fidelity (SSIM 0.9612) (no change)

    native Switch_normal_light cn1 Switch_normal_light
    Left: native widget. Right: Codename One render.

  • FloatingActionButton_normal_light -- 96.09% fidelity (SSIM 0.9367) (no change)

    native FloatingActionButton_normal_light cn1 FloatingActionButton_normal_light
    Left: native widget. Right: Codename One render.

  • FloatingActionButton_pressed_dark -- 96.16% fidelity (SSIM 0.9513) (no change)

    native FloatingActionButton_pressed_dark cn1 FloatingActionButton_pressed_dark
    Left: native widget. Right: Codename One render.

  • Switch_normal_dark -- 96.17% fidelity (SSIM 0.9616) (no change)

    native Switch_normal_dark cn1 Switch_normal_dark
    Left: native widget. Right: Codename One render.

  • TextField_disabled_dark -- 96.21% fidelity (SSIM 0.9648) (no change)

    native TextField_disabled_dark cn1 TextField_disabled_dark
    Left: native widget. Right: Codename One render.

  • RaisedButton_normal_dark -- 96.41% fidelity (SSIM 0.9516) (no change)

    native RaisedButton_normal_dark cn1 RaisedButton_normal_dark
    Left: native widget. Right: Codename One render.

  • Switch_disabled_light -- 96.43% fidelity (SSIM 0.9698) (no change)

    native Switch_disabled_light cn1 Switch_disabled_light
    Left: native widget. Right: Codename One render.

  • Button_disabled_light -- 96.80% fidelity (SSIM 0.9596) (no change)

    native Button_disabled_light cn1 Button_disabled_light
    Left: native widget. Right: Codename One render.

  • ProgressBar_normal_dark -- 96.91% fidelity (SSIM 0.9669) (no change)

    native ProgressBar_normal_dark cn1 ProgressBar_normal_dark
    Left: native widget. Right: Codename One render.

  • RaisedButton_disabled_dark -- 97.02% fidelity (SSIM 0.9549) (no change)

    native RaisedButton_disabled_dark cn1 RaisedButton_disabled_dark
    Left: native widget. Right: Codename One render.

  • FloatingActionButton_normal_dark -- 97.07% fidelity (SSIM 0.9521) (no change)

    native FloatingActionButton_normal_dark cn1 FloatingActionButton_normal_dark
    Left: native widget. Right: Codename One render.

  • ProgressBar_normal_light -- 97.26% fidelity (SSIM 0.9739) (no change)

    native ProgressBar_normal_light cn1 ProgressBar_normal_light
    Left: native widget. Right: Codename One render.

  • RaisedButton_disabled_light -- 97.26% fidelity (SSIM 0.9611) (no change)

    native RaisedButton_disabled_light cn1 RaisedButton_disabled_light
    Left: native widget. Right: Codename One render.

  • TextField_disabled_light -- 97.29% fidelity (SSIM 0.9649) (no change)

    native TextField_disabled_light cn1 TextField_disabled_light
    Left: native widget. Right: Codename One render.

  • RaisedButton_normal_light -- 97.32% fidelity (SSIM 0.9613) (no change)

    native RaisedButton_normal_light cn1 RaisedButton_normal_light
    Left: native widget. Right: Codename One render.

  • TextField_normal_dark -- 97.61% fidelity (SSIM 0.9583) (no change)

    native TextField_normal_dark cn1 TextField_normal_dark
    Left: native widget. Right: Codename One render.

  • TextField_normal_light -- 97.62% fidelity (SSIM 0.9582) (no change)

    native TextField_normal_light cn1 TextField_normal_light
    Left: native widget. Right: Codename One render.

  • Slider_normal_dark -- 98.39% fidelity (SSIM 0.9900) (no change)

    native Slider_normal_dark cn1 Slider_normal_dark
    Left: native widget. Right: Codename One render.

  • Toolbar_normal_light -- 98.69% fidelity (SSIM 0.9739) (no change)

    native Toolbar_normal_light cn1 Toolbar_normal_light
    Left: native widget. Right: Codename One render.

  • Slider_normal_light -- 98.95% fidelity (SSIM 0.9908) (no change)

    native Slider_normal_light cn1 Slider_normal_light
    Left: native widget. Right: Codename One render.

  • Slider_disabled_dark -- 99.56% fidelity (SSIM 0.9927) (no change)

    native Slider_disabled_dark cn1 Slider_disabled_dark
    Left: native widget. Right: Codename One render.

  • Slider_disabled_light -- 99.59% fidelity (SSIM 0.9932) (no change)

    native Slider_disabled_light cn1 Slider_disabled_light
    Left: native widget. Right: Codename One render.

@shai-almog

shai-almog commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 12 screenshots: 12 matched.
✅ JavaSE simulator integration screenshots matched stored baselines.

@shai-almog

shai-almog commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 149 screenshots: 149 matched.

Native Android coverage

  • 📊 Line coverage: 11.24% (11753/104572 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 10.04% (58173/579278), branch 5.11% (2701/52900), complexity 4.88% (2706/55471), method 7.35% (2099/28552), class 11.45% (464/4052)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 11.24% (11753/104572 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 10.04% (58173/579278), branch 5.11% (2701/52900), complexity 4.88% (2706/55471), method 7.35% (2099/28552), class 11.45% (464/4052)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 241ms / native 79ms = 3.0x speedup
SIMD float-mul (64K x300) java 104ms / native 85ms = 1.2x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 190.000 ms
Base64 CN1 decode 255.000 ms
Base64 native encode 624.000 ms
Base64 encode ratio (CN1/native) 0.304x (69.6% faster)
Base64 native decode 919.000 ms
Base64 decode ratio (CN1/native) 0.277x (72.3% faster)
Image encode benchmark status skipped (SIMD unsupported)

shai-almog and others added 10 commits July 16, 2026 11:40
…Region)

The previous commits re-derived the whole material+motion model from the
committed grey-backdrop phone recording, which flattened the effect on every
port including iOS -- diverging from the doc-blessed fidelity target and the
committed ios-26-metal-frames goldens. Revert the shared model
(TabSelectionMorph tokens/curve), Tabs paint behaviour, the Metal shader and
CPU reference constants, and the iOS-modern theme back to master's tuning.

The actual reason the simulator looked wrong was never the model: JavaSE had
NO glassRegion implementation, so the bar's Liquid Glass material fell back to
a plain blur. The lens then sampled a flat grey bar instead of the bright
frost, and every in-flight frame read as a murky smudge. Implement
JavaSEPort.glassRegion as a step-for-step mirror of IOSImplementation's
offscreen branch (padded edge-replicated backdrop, affine colour material,
Gaussian blur, SDF optics: edge refraction + specular rim + AA mask). With it
the JavaSE render of TabsMorph_t050 matches the committed Metal golden to
~1 LSB at matched anatomy (bar 240/240/240, bubble interior within 2).

Keep the good parts of this PR: the JavaScript port's real per-pixel lens and
full glass recipe (replacing the uniform-zoom fallback), re-pinned to master's
constants and bit-identical to JavaSE at all seven probe points; the
four-backend constant/CRC parity script (regenerated against
JavaSEPort.applyLensBuffer); the deterministic JavaSE frame probe; and the
opt-in cn1.javase.pixelMilliRatio density override for reference-resolution
captures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Re-record native-tabs-{light,dark}.mov from the live UITabBar on the current
iOS 26.3 simulator runtime. The fresh recordings confirm the old video was not
stale: Apple toned the Liquid Glass tab drop down in later 26.x updates, so
current UIKit shows a flat compact drop -- the frosted refracting bubble from
the original iOS 26 design (the developer-guide fidelity image and the
committed TabsMorph frame goldens) can no longer be captured natively.

Codename One deliberately keeps the original frosted-bubble design, so add
cn1-tabs-{light,dark}.mov: the shipped morph in motion, rendered
deterministically from the JavaSE simulator at the reference density (60fps,
the theme's 480ms timeline, 1088x290 tile) with the restored model and the new
glassRegion material. A README in the anim goldens dir now states which video
is authoritative for what: natives for timing/travel, the CN1 baseline and the
frame goldens for material -- never tune against the flat native material.

Also note in verify-javascript-lens-parity.mjs that the glass material/optics
CRC pins are shared by three CPU implementations (iOS, JavaSE, browser bridge);
JavaSE's new glassMaterialInPlace/applyGlassOptics reproduce them bit-exactly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s interaction-only

The flat drop in the previous native-tabs recordings was a recording artifact,
not Apple toning the effect down: UIKit plays the full Liquid Glass selection
morph (the frosted refracting bubble with chromatic rims that bulges past the
bar) only for genuine touch-driven selection on a UITabBarController.
Programmatic selectedIndex changes play a flat simplified platter slide, and
the old bare-UITabBar + custom-appearance path never showed the effect at all.
Verified by XCUITest-tapping both the Files app and a plain UITabBarController
on the same iOS 26.3 runtime over the same grey backdrop -- both show the full
bubble that the committed Metal frame goldens and the developer-guide fidelity
image depict.

- NativeRef animate mode now hosts a real UITabBarController (the bare bar
  also crashed under a controller: selectedItem writes are forbidden)
- add the tap-driver XCUITest harness (xcodegen project, like the
  input-validation iOS driver); record-ios-native-anim.sh drives real taps
  through it for the tabs recording (build-for-testing, then record during
  test-without-building) and keeps the self-animating path for the switch
- re-record native-tabs-{light,dark}.mov: they now show the true frosted
  morph, matching the CN1 baseline instead of contradicting it
- rewrite the anim-goldens README accordingly (the earlier toned-down claim
  was wrong)
- Playground: the Tabs sample now uses addTab(title, materialIcon, size,
  content) so tab icons are theme-driven and recolor with selection; the old
  manual FontImage.createMaterial icons stayed one colour

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Merge origin/master (#5387 Liquid Glass theme fidelity) into the branch.

Refine the RaisedButton gradient stroke: the ring was painted as an outer
gradient fill with the background filled over an inset contour, and at the
theme's 0.1mm hairline width the two independently-rasterized edges
misregistered -- the stroke read as broken segments and muddy grey arcs that
mixed with the backdrop (clearly visible in the ButtonTheme goldens). The ring
is now a single two-contour shape (inner contour programmatically reversed so
the default non-zero winding leaves a ring -- even-odd is not plumbed through
the JavaScript port's canvas fill) painted OVER the background fill, giving a
uniform, luminous rim: white glint at the top-left flowing to the cyan tint at
the bottom-right, on every port from the same shared code.

Add the Codename One copyright header to the tap-driver sources, NativeRef and
PlaygroundExamples (check-copyright-headers CI failure).

Screenshot goldens that include the dark/light RaisedButton hairline stroke
will need a refresh cycle; the JavaScript ones are regenerated in the next
commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The JavaScript port now renders the genuine Liquid Glass material and
selection lens (and the refined gradient stroke), so the iOS-theme screenshots
legitimately changed. Goldens are taken from the javascript-ui-tests artifact
of CI run 29512910274 (commit 5131184) -- the runner's own Chromium
rendering -- because locally-rendered pixels do not match the CI environment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…inding ring

The multi-contour non-zero ring rendered correctly on JavaSE and the
JavaScript port but the iOS/Metal clip rasterizer unions subpaths, so on
Mac/iOS the whole pill filled with the stroke gradient (caught by the
build-mac-native screenshot diff). Replace it with three passes that hold on
every port: the background fills the full shape, the translucent gradient
paints over it clipped to the same shape, and the interior is restored through
a solid Paint clipped to the inset shape. The two clipped passes share one
rasterizer, so the leftover hairline ring keeps registration-stable edges (the
original defect), and the background beneath keeps it luminous. JavaSE render
verified identical to the ring construction at 4x zoom.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ortable stroke

Taken from the javascript-ui-tests artifact of CI run 29531928085 (commit
1cf9e06) -- the three-pass gradient stroke shifts the raised-button rim by
a few pixels relative to the ring-construction renders these goldens froze.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Taken from the ios-ui-tests / watch-ui-tests artifacts of CI run 29536263092
(commit df3d40a): the RaisedButton/FlatButton hairline rim now renders as a
clean uniform ring on the device pipeline instead of the broken segments the
old goldens froze. Metal and tvOS jobs passed against their existing goldens.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant