Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions .github/workflows/scripts-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:
pull-requests: write
issues: write
runs-on: macos-15 # pinning macos-15 avoids surprises during the cutover window
timeout-minutes: 45 # only sample app build + UI tests now; iOS port build runs in build-port
timeout-minutes: 60 # only sample app build + UI tests now; bumped from 45 to accommodate the 45-min test-step cap
concurrency: # ensure only one mac build runs at once
group: mac-ci-${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: true
Expand Down Expand Up @@ -182,6 +182,28 @@ jobs:
key: ${{ needs.build-port.outputs.cn1_built_cache_key }}
fail-on-cache-miss: true

- name: Force GL backend for hellocodenameone
# IPhoneBuilder defaults ios.metal to true. The GL job exists to
# exercise the legacy OpenGL ES 2 path, so pin the hint to false
# explicitly. Mirror of the Metal-enabling step in build-ios-metal.
run: |
set -euo pipefail
SETTINGS=scripts/hellocodenameone/common/codenameone_settings.properties
if grep -q '^codename1\.arg\.ios\.metal=' "$SETTINGS"; then
sed -i '' 's|^codename1.arg.ios.metal=.*|codename1.arg.ios.metal=false|' "$SETTINGS"
else
awk '
/^codename1\.arg\.ios\.applicationQueriesSchemes=/ {
print
print "codename1.arg.ios.metal=false"
next
}
{ print }
' "$SETTINGS" > "$SETTINGS.tmp" && mv "$SETTINGS.tmp" "$SETTINGS"
fi
echo "--- codenameone_settings.properties (ios.* keys after patch) ---"
grep -n 'codename1\.arg\.ios' "$SETTINGS" || true

- name: Build sample iOS app and compile workspace
id: build-ios-app
run: ./scripts/build-ios-app.sh -q -DskipTests
Expand All @@ -201,7 +223,11 @@ jobs:
"${{ steps.build-ios-app.outputs.workspace }}" \
"" \
"${{ steps.build-ios-app.outputs.scheme }}"
timeout-minutes: 30
# Bumped from 30 to 45: the Metal screenshot suite has been
# bumping up against the prior 30-min cap on master (timing out
# at the CN1SS:SUITE:FINISHED wait), and the GL job has the
# same envelope so it stays symmetric.
timeout-minutes: 45

- name: Upload iOS artifacts
if: always()
Expand All @@ -222,7 +248,7 @@ jobs:
pull-requests: write
issues: write
runs-on: macos-15
timeout-minutes: 45
timeout-minutes: 60
concurrency:
group: mac-ci-${{ github.workflow }}-metal-${{ github.ref_name }}
cancel-in-progress: true
Expand Down Expand Up @@ -406,7 +432,10 @@ jobs:
"${{ steps.build-ios-app.outputs.workspace }}" \
"" \
"${{ steps.build-ios-app.outputs.scheme }}"
timeout-minutes: 30
# See the matching note on the GL job: 30-min cap was being
# hit on master while the simulator was still draining the
# screenshot suite.
timeout-minutes: 45

- name: Publish Metal screenshot summary
# Surfaces run-ios-ui-tests.sh's comparison result in the job's
Expand Down
7 changes: 7 additions & 0 deletions docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,12 @@ Only supported for App Store builds. See https://www.codenameone.com/developer-g
|ios.testFlight
|Boolean true/false defaults to false and works only for pro accounts. Enables the testflight support in the release binaries for easy beta testing. Notice that the IDE plugin has a "Test Flight" check box you *should* use under the iOS section.

|ios.metal
|Boolean true/false defaults to true. Selects the Metal rendering backend (`CAMetalLayer`) over the legacy OpenGL ES 2 path (`CAEAGLLayer`). Metal is the supported iOS graphics API; OpenGL ES is deprecated. Set to `false` to opt out if you hit a Metal-only rendering regression. See link:#_metal_renderer[Working with iOS / Metal renderer] for details.

|ios.metal.colorSpace
|Selects the `CAMetalLayer.colorspace` for the Metal renderer. Accepts `sRGB` (default), `displayP3`, `deviceRGB`, `linearSRGB`, `extendedSRGB`, `extendedLinearSRGB`, or `none`. Has no effect when `ios.metal=false`. See link:#_choosing_a_color_space_for_the_metal_renderer[Working with iOS / Choosing a color space] for the full table.

|ios.generateSplashScreens
|Boolean true/false defaults to false as of 5.0. Enable legacy generation of splash screen images for use when launching the app. These have been replaced now by the new launch storyboards.

Expand Down Expand Up @@ -1692,6 +1698,7 @@ ios.locationUsageDescription
ios.bundleVersion
ios.objC
ios.testFlight
ios.metal
desktop.width
desktop.height
desktop.adaptToRetina
Expand Down
18 changes: 16 additions & 2 deletions docs/developer-guide/Working-With-iOS.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,24 @@ NOTE: This is supported for pro users as part of the crash protection feature.
To take advantage of that capability use the build hint `ios.testFlight=true` and then submit the app to the store for
beta testing. Make sure to use a release build target.

=== Metal renderer

// vale-skip: Microsoft.Avoid: "rendering backend" is Apple's term of art for an alternate Metal/OpenGL rendering pipeline, not a back-end server.
iOS builds use the Metal rendering backend by default. The Metal pipeline drives a `CAMetalLayer`, replacing the legacy OpenGL ES 2 path on `CAEAGLLayer`. OpenGL ES is deprecated on iOS and Metal is the supported graphics API going forward, so new projects pick it up automatically.

To opt out and fall back to the OpenGL ES 2 backend, set the build hint:

[source]
-----
codename1.arg.ios.metal=false
-----

If you hit a rendering regression after the default flip, opting out with `ios.metal=false` is a safe escape hatch, but please file an issue with a reproducer so the Metal path can be fixed.

=== Choosing a color space for the Metal renderer

// vale-skip: Microsoft.Avoid: "rendering backend" is Apple's term of art for an alternate Metal/OpenGL rendering pipeline, not a back-end server.
When the Metal rendering backend is enabled with `ios.metal=true`, the `CAMetalLayer` is configured with the sRGB color space by default. This matches the behavior of the legacy OpenGL ES 2 backend on `CAEAGLLayer`: CG-rasterized images and gradients (which are tagged `DeviceRGB` in their `CGBitmapContext`) end up displayed with the same brightness on both backends.
With the Metal renderer (the default), the `CAMetalLayer` is configured with the sRGB color space. This matches the behavior of the legacy OpenGL ES 2 backend on `CAEAGLLayer`: CG-rasterized images and gradients (which are tagged `DeviceRGB` in their `CGBitmapContext`) end up displayed with the same brightness on both backends.

// vale-skip: Microsoft.Adverbs: "strictly device-RGB" is a precise color-pipeline qualifier (excluding sRGB conversion), not a softener.
For most apps the default is the right choice. Apps that need a different color profile -- for example, wide-gamut artwork that should be displayed in Display P3, or a strictly device-RGB pipeline that matches a custom rendering toolchain -- can override the choice with the `ios.metal.colorSpace` build hint:
Expand Down Expand Up @@ -212,7 +226,7 @@ For most apps the default is the right choice. Apps that need a different color
|===

// vale-skip: Microsoft.Avoid: "OpenGL ES 2 backend" names the alternate rendering pipeline, not a server.
NOTE: The hint only takes effect when `ios.metal=true`. With the OpenGL ES 2 backend the layer is `CAEAGLLayer` and the color space is fixed by the system.
NOTE: The hint only takes effect on the Metal backend (the default). If you have opted out with `ios.metal=false`, the layer is `CAEAGLLayer` and the color space is fixed by the system.

=== Accessing insecure URLs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ public boolean build(File sourceZip, BuildRequest request) throws BuildException
detectJailbreak = request.getArg("ios.detectJailbreak", "false").equals("true");
defaultEnvironment.put("LANG", "en_US.UTF-8");
tmpFile = tmpDir = getBuildDirectory();
useMetal = "true".equals(request.getArg("ios.metal", "false"));
useMetal = "true".equals(request.getArg("ios.metal", "true"));
log("Request Args: ");
log("-----------------");
for (String arg : request.getArgs()) {
Expand Down
Loading