Skip to content

Simulator reported the host machine's pixel ratio instead of the simulated device's - #5728

Merged
shai-almog merged 1 commit into
masterfrom
fix-simulator-device-pixel-ratio
Sep 7, 2026
Merged

Simulator reported the host machine's pixel ratio instead of the simulated device's#5728
shai-almog merged 1 commit into
masterfrom
fix-simulator-device-pixel-ratio

Conversation

@shai-almog

Copy link
Copy Markdown
Collaborator

What is wrong

JavaSEPort.getDevicePixelRatio() returns the host display's backing scale
unconditionally. In the simulator that describes the wrong machine: a loaded
skin means the process is standing in for another device, so a 2x desktop
showing a 3x phone skin reports 2.

Anything that lays out in the platform's logical units is then two thirds of its
intended size. The method is new in #5686, so this is a regression introduced
there rather than long-standing behaviour.

The fix

Report the backing scale only when no skin is loaded — which is a real desktop
application on this display, and exactly what the API asks.

With a skin, answer the documented "not reported" value. That sends the caller
to the density bucket, which describes the device being simulated rather than
the machine simulating it, and is what this call resolved to before the platform
reported a scale at all.

Why the logic moved into a helper

JavaSEPort's constructor initialises a look and feel that needs a native
library which is not present on every machine — several existing tests in this
module cannot run because of it. The part that was wrong is the decision, and a
decision needs no port, so it sits in a package-private
devicePixelRatioFor(desktop, hostScale, notReported) that the accessor
delegates to.

Verification

JavaSEPortDevicePixelRatioTest pins three cases: a skinned simulator must not
report the host scale, a desktop application must, and a host reporting no scale
falls back to "not reported" rather than a ratio of zero.

Confirmed by removing the check again — the skinned case then reports 2.0
where 0 is expected, which is the regression. Restored, 3/3 pass.

🤖 Generated with Claude Code

getDevicePixelRatio on JavaSE returned the host display's backing scale
unconditionally. In the simulator that is the wrong machine: a loaded skin means
the process is standing in for another device, and a 2x desktop showing a 3x
phone skin reported 2. Anything laying out in the platform's logical units then
came out two thirds of its size.

The scale is now reported only when no skin is loaded, which is a real desktop
application on this display and exactly what the API asks. With a skin it
answers the "not reported" value, which the documented contract already defines:
the caller derives the ratio from the density bucket, which describes the device
being simulated rather than the machine simulating it -- and is what this call
resolved to before the platform reported a scale at all.

The decision sits in a package-private helper rather than inline, so it can be
tested. JavaSEPort's constructor initialises a look and feel that needs a native
library which is not present on every machine, and several existing tests in
this module cannot run because of it; the part that was wrong here is the
decision, and that needs no port.

Verified by removing the check again: the skinned case then reports 2.0 where 0
is expected, which is the regression.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-07T04:38:39.702066Z 70c2db3 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 70c2db3cd3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Override
public float getDevicePixelRatio() {
return retinaScale > 0 ? (float) retinaScale : super.getDevicePixelRatio();
return devicePixelRatioFor(isDesktop(), retinaScale, super.getDevicePixelRatio());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the stale backing-scale documentation

When a device skin is loaded, this return now deliberately yields the notReported sentinel, but the method-level documentation immediately above still says a skin reports the host retinaScale, honors its overrides, and always matches the renderer. This directly contradicts both the implementation and the new helper documentation, so readers cannot reliably determine the JavaSE contract; revise or remove the obsolete skin-specific paragraphs together with this behavior change.

Useful? React with 👍 / 👎.

@shai-almog

shai-almog commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

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

@shai-almog

shai-almog commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 151 screenshots: 151 matched.

Native Android coverage

  • 📊 Line coverage: 9.21% (9146/99286 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.97% (47024/524433), branch 3.53% (1751/49663), complexity 3.51% (1858/52966), method 5.40% (1505/27866), class 10.85% (405/3731)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1187 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • okio.okio.Buffer – 0.00% (0/687 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.Frame – 0.00% (0/570 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 9.21% (9146/99286 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.97% (47024/524433), branch 3.53% (1751/49663), complexity 3.51% (1858/52966), method 5.40% (1505/27866), class 10.85% (405/3731)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1187 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • okio.okio.Buffer – 0.00% (0/687 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.Frame – 0.00% (0/570 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 231ms / native 196ms = 1.1x speedup
SIMD float-mul (64K x300) java 237ms / native 142ms = 1.6x 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 73.000 ms
Base64 CN1 decode 84.000 ms
Base64 native encode 356.000 ms
Base64 encode ratio (CN1/native) 0.205x (79.5% faster)
Base64 native decode 286.000 ms
Base64 decode ratio (CN1/native) 0.294x (70.6% faster)
Image encode benchmark status skipped (SIMD unsupported)

@github-actions

github-actions Bot commented Sep 7, 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)
    • build-hint-catalog: 0 findings (no issues)
    • build-hint-tools: 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 Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

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

@shai-almog
shai-almog merged commit 005655d into master Sep 7, 2026
34 checks passed
@shai-almog
shai-almog deleted the fix-simulator-device-pixel-ratio branch September 7, 2026 05:49
@shai-almog

shai-almog commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

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

Benchmark Results

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

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 54ms / native 3ms = 18.0x speedup
SIMD float-mul (64K x300) java 49ms / native 3ms = 16.3x 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 active (NEON-accelerated)
Base64 CN1 encode 158.000 ms
Base64 CN1 decode 86.000 ms
Image encode benchmark iterations 100
Image createMask (SIMD off) 6.000 ms
Image createMask (SIMD on) 2.000 ms
Image createMask ratio (SIMD on/off) 0.333x (66.7% faster)
Image applyMask (SIMD off) 32.000 ms
Image applyMask (SIMD on) 23.000 ms
Image applyMask ratio (SIMD on/off) 0.719x (28.1% faster)
Image modifyAlpha (SIMD off) 25.000 ms
Image modifyAlpha (SIMD on) 22.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.880x (12.0% faster)
Image modifyAlpha removeColor (SIMD off) 28.000 ms
Image modifyAlpha removeColor (SIMD on) 22.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.786x (21.4% faster)

@shai-almog

shai-almog commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

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

Benchmark Results

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

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 52ms / native 2ms = 26.0x 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 187.000 ms
Base64 CN1 decode 127.000 ms
Base64 native encode 925.000 ms
Base64 encode ratio (CN1/native) 0.202x (79.8% faster)
Base64 native decode 596.000 ms
Base64 decode ratio (CN1/native) 0.213x (78.7% faster)
Base64 SIMD encode 85.000 ms
Base64 encode ratio (SIMD/CN1) 0.455x (54.5% faster)
Base64 SIMD decode 62.000 ms
Base64 decode ratio (SIMD/CN1) 0.488x (51.2% faster)
Base64 encode ratio (SIMD/native) 0.092x (90.8% faster)
Base64 decode ratio (SIMD/native) 0.104x (89.6% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 12.000 ms
Image createMask (SIMD on) 14.000 ms
Image createMask ratio (SIMD on/off) 1.167x (16.7% slower)
Image applyMask (SIMD off) 88.000 ms
Image applyMask (SIMD on) 94.000 ms
Image applyMask ratio (SIMD on/off) 1.068x (6.8% slower)
Image modifyAlpha (SIMD off) 87.000 ms
Image modifyAlpha (SIMD on) 42.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.483x (51.7% faster)
Image modifyAlpha removeColor (SIMD off) 74.000 ms
Image modifyAlpha removeColor (SIMD on) 82.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 1.108x (10.8% slower)

@shai-almog

shai-almog commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

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

@shai-almog

shai-almog commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 89000 ms
Simulator Boot (Run) 1000 ms
App Install 22000 ms
App Launch 70000 ms
Test Execution 627000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 122ms / native 5ms = 24.4x speedup
SIMD float-mul (64K x300) java 130ms / native 3ms = 43.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 437.000 ms
Base64 CN1 decode 101.000 ms
Base64 native encode 1129.000 ms
Base64 encode ratio (CN1/native) 0.387x (61.3% faster)
Base64 native decode 759.000 ms
Base64 decode ratio (CN1/native) 0.133x (86.7% faster)
Base64 SIMD encode 61.000 ms
Base64 encode ratio (SIMD/CN1) 0.140x (86.0% faster)
Base64 SIMD decode 60.000 ms
Base64 decode ratio (SIMD/CN1) 0.594x (40.6% faster)
Base64 encode ratio (SIMD/native) 0.054x (94.6% faster)
Base64 decode ratio (SIMD/native) 0.079x (92.1% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 10.000 ms
Image createMask (SIMD on) 1.000 ms
Image createMask ratio (SIMD on/off) 0.100x (90.0% faster)
Image applyMask (SIMD off) 387.000 ms
Image applyMask (SIMD on) 454.000 ms
Image applyMask ratio (SIMD on/off) 1.173x (17.3% slower)
Image modifyAlpha (SIMD off) 234.000 ms
Image modifyAlpha (SIMD on) 286.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.222x (22.2% slower)
Image modifyAlpha removeColor (SIMD off) 669.000 ms
Image modifyAlpha removeColor (SIMD on) 478.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.714x (28.6% faster)

@shai-almog

shai-almog commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 78000 ms
Simulator Boot (Run) 31000 ms
App Install 18000 ms
App Launch 39000 ms
Test Execution 439000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 91ms / native 6ms = 15.1x speedup
SIMD float-mul (64K x300) java 63ms / native 3ms = 21.0x 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 267.000 ms
Base64 CN1 decode 129.000 ms
Base64 native encode 1137.000 ms
Base64 encode ratio (CN1/native) 0.235x (76.5% faster)
Base64 native decode 637.000 ms
Base64 decode ratio (CN1/native) 0.203x (79.7% faster)
Base64 SIMD encode 93.000 ms
Base64 encode ratio (SIMD/CN1) 0.348x (65.2% faster)
Base64 SIMD decode 56.000 ms
Base64 decode ratio (SIMD/CN1) 0.434x (56.6% faster)
Base64 encode ratio (SIMD/native) 0.082x (91.8% faster)
Base64 decode ratio (SIMD/native) 0.088x (91.2% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 10.000 ms
Image createMask (SIMD on) 2.000 ms
Image createMask ratio (SIMD on/off) 0.200x (80.0% faster)
Image applyMask (SIMD off) 43.000 ms
Image applyMask (SIMD on) 178.000 ms
Image applyMask ratio (SIMD on/off) 4.140x (314.0% slower)
Image modifyAlpha (SIMD off) 152.000 ms
Image modifyAlpha (SIMD on) 222.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.461x (46.1% slower)
Image modifyAlpha removeColor (SIMD off) 142.000 ms
Image modifyAlpha removeColor (SIMD on) 500.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 3.521x (252.1% slower)

@shai-almog

shai-almog commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

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

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