Skip to content

[Fix] (MG_Backend/DirectGLES): clamp UNORM fallback writes #132

[Fix] (MG_Backend/DirectGLES): clamp UNORM fallback writes

[Fix] (MG_Backend/DirectGLES): clamp UNORM fallback writes #132

Workflow file for this run

name: MobileGL APK
on:
push:
branches:
- dev
- Feat/Backend-Direct-GLES
- Feat/Backend-Direct-Vulkan
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
env:
CCACHE_BASEDIR: ${{ github.workspace }}
CCACHE_COMPRESS: "true"
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_MAXSIZE: 4G
CCACHE_NOHASHDIR: "true"
MOBILEGL_CMAKE_COMPILER_LAUNCHER: ccache
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set artifact metadata
run: |
echo "date_today=$(date +'%Y-%m-%d')" >> "$GITHUB_ENV"
echo "short_sha=${GITHUB_SHA::7}" >> "$GITHUB_ENV"
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: zulu
java-version: '17'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-version: 8.10.2
- name: Restore ccache
uses: actions/cache@v4
with:
path: .ccache
key: ${{ runner.os }}-apk-${{ github.job }}-ccache-${{ github.ref_name }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-apk-${{ github.job }}-ccache-${{ github.ref_name }}-
${{ runner.os }}-apk-${{ github.job }}-ccache-
- name: Install ccache
run: |
sudo apt-get update
sudo apt-get install -y ccache
ccache --version
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Install Android NDK
run: |
sdkmanager "ndk;27.3.13750724"
echo "ndk.dir=$ANDROID_HOME/ndk/27.3.13750724" >> android-plugin/local.properties
- name: Update glslang external sources
working-directory: 3rdparty/glslang
run: python update_glslang_sources.py
- name: Build plugin APKs
run: gradle --no-daemon -p android-plugin :app:assembleEsprytPluginRelease :app:assembleMagmaPluginRelease -Pmobilegl.logLevel=MOBILEGL_LOG_LEVEL_INFO --parallel --max-workers "$(nproc)"
env:
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
- name: Download ANGLE x86_64 libraries
run: |
angle_dir="android-plugin/app/src/trace/jniLibs/x86_64"
angle_base="https://raw.githubusercontent.com/FCL-Team/FoldCraftLauncher/main/FCLauncher/src/main/jniLibs/x86_64"
mkdir -p "${angle_dir}"
curl -L --fail --retry 3 -o "${angle_dir}/libEGL_angle.so" "${angle_base}/libEGL_angle.so"
curl -L --fail --retry 3 -o "${angle_dir}/libGLESv2_angle.so" "${angle_base}/libGLESv2_angle.so"
test -s "${angle_dir}/libEGL_angle.so"
test -s "${angle_dir}/libGLESv2_angle.so"
- name: Build retrace APKs
run: gradle --no-daemon -p android-plugin :app:assembleEsprytTraceRelease :app:assembleMagmaTraceRelease -Pmobilegl.abis=all -Pmobilegl.debuggableRelease=true -Pmobilegl.logLevel=MOBILEGL_LOG_LEVEL_INFO --parallel --max-workers "$(nproc)"
env:
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
- name: Show ccache stats
if: always()
run: ccache --show-stats
- name: Verify signed APKs
run: |
APKSIGNER="$(find "$ANDROID_HOME/build-tools" -name apksigner -type f | sort -V | tail -n 1)"
mapfile -t APKS < <(find android-plugin/app/build/outputs/apk -type f -path '*/release/*.apk' | sort)
if [ "${#APKS[@]}" -eq 0 ]; then
echo "::error::No release APKs found under android-plugin/app/build/outputs/apk"
find android-plugin/app/build/outputs/apk -type f -print || true
exit 1
fi
for APK in "${APKS[@]}"; do
if [[ "$APK" == *-unsigned.apk ]]; then
echo "::error::Unsigned release APK produced: $APK"
exit 1
fi
"$APKSIGNER" verify --verbose "$APK"
done
- name: Upload plugin APK
uses: actions/upload-artifact@v4
with:
name: MobileGL-plugin-${{ env.date_today }}-${{ env.short_sha }}
path: android-plugin/app/build/outputs/apk/*Plugin/release/*.apk
if-no-files-found: error
- name: Upload retrace APK
uses: actions/upload-artifact@v4
with:
name: MobileGL-retrace-apk-${{ env.date_today }}-${{ env.short_sha }}
path: android-plugin/app/build/outputs/apk/*Trace/release/*.apk
if-no-files-found: error
retrace:
name: retrace (${{ matrix.backend.name }}, ${{ matrix.case.name }})
runs-on: ubuntu-latest
needs: build
timeout-minutes: 75
env:
AVD_NAME: mobilegl-${{ matrix.backend.id }}
strategy:
fail-fast: false
max-parallel: 4
matrix:
backend:
- name: DirectGLES
id: espryt
apk: MobileGL-EsprytTrace-release.apk
package: top.mobilegl.plugin.espryt.trace
gpu: software
- name: DirectVulkan
id: magma
apk: MobileGL-MagmaTrace-release.apk
package: top.mobilegl.plugin.magma.trace
gpu: lavapipe
case:
- name: OpenRA
trace_archive: tools/trace_replay/fixtures/openra.tgz
trace_file: openra.trace
golden: tools/trace_replay/fixtures/openra.0000031249.png
target_call: 31249
width: 640
height: 480
crop_x: 1
crop_y: 1
crop_width: 638
crop_height: 478
timeout_seconds: 180
- name: minecraft-1.21.4-startup
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-startup.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-startup.0000092195.png
target_call: 92195
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 180
- name: minecraft-1.21.4-main-menu
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-main-menu.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-main-menu.0000481787.png
alternate_golden: tools/trace_replay/fixtures/minecraft-1.21.4-main-menu.0000481787-mali.png
target_call: 481787
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 180
- name: minecraft-1.21.4-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-in-world.0000280000.png
target_call: 280000
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-sodium-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-sodium-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-sodium-in-world.0000923340.png
target_call: 923340
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 1800
- name: minecraft-1.21.4-fabric-iris-bsl-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-bsl-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-bsl-in-world.0000110725.png
alternate_golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-bsl-in-world.0000110725-mali.png
target_call: 110725
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-makeup-ultrafast-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-makeup-ultrafast-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-makeup-ultrafast-in-world.0000095322.png
target_call: 95322
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-super-duper-vanilla-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-super-duper-vanilla-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-super-duper-vanilla-in-world.0000141559.png
target_call: 141559
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-sundial-lite-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-sundial-lite-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-sundial-lite-in-world.0000150023.png
target_call: 150023
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-complementary-reimagined-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-complementary-reimagined-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-complementary-reimagined-in-world.0000151297.png
target_call: 151297
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-complementary-unbound-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-complementary-unbound-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-complementary-unbound-in-world.0000146559.png
target_call: 146559
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-mellow-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-mellow-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-mellow-in-world.0000096143.png
target_call: 96143
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-nostalgia-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-nostalgia-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-nostalgia-in-world.0000153808-linux-mesa.png
alternate_golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-nostalgia-in-world.0000153808.png
target_call: 153808
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-bliss-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-bliss-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-bliss-in-world.0000113511.png
target_call: 113511
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-chocapic-v6-lite-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-chocapic-v6-lite-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-chocapic-v6-lite-in-world.0000125124-linux-mesa.png
target_call: 125124
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-iterationt-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-iterationt-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-iterationt-in-world.0000110538.png
target_call: 110538
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-iterationt-nodsa-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-iterationt-nodsa-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-iterationt-nodsa-in-world.0000115019.png
target_call: 115019
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-photon-v1.1-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-photon-v1.1-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-photon-v1.1-in-world.0000159866.png
target_call: 159866
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-photon-v1.3b-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-photon-v1.3b-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-photon-v1.3b-in-world.0000172128.png
target_call: 172128
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
- name: minecraft-1.21.4-fabric-iris-derivative-main-d24.4.14-in-world
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-derivative-main-d24.4.14-in-world.tgz
trace_file: trace.trace
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-derivative-main-d24.4.14-in-world.0000145353.png
target_call: 145353
width: 854
height: 480
crop_x: 0
crop_y: 0
crop_width: 0
crop_height: 0
timeout_seconds: 900
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
submodules: recursive
- name: Fetch trace fixture
run: bash .github/scripts/fetch-trace-fixture-lfs.sh '${{ matrix.case.name }}'
- name: Set artifact metadata
run: |
echo "date_today=$(date +'%Y-%m-%d')" >> "$GITHUB_ENV"
echo "short_sha=${GITHUB_SHA::7}" >> "$GITHUB_ENV"
echo "EMULATOR_LOG=${RUNNER_TEMP}/mobilegl-emulator.log" >> "$GITHUB_ENV"
echo "EMULATOR_PID_FILE=${RUNNER_TEMP}/mobilegl-emulator.pid" >> "$GITHUB_ENV"
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Download retrace APKs
uses: actions/download-artifact@v4
with:
pattern: MobileGL-retrace-apk-*
path: android-retrace-apks
merge-multiple: true
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Create AVD
run: |
sh android-plugin/run-avd-ci.sh create \
--api-level 35 \
--target google_apis \
--arch x86_64 \
--profile pixel_6 \
--avd-name "${AVD_NAME}"
- name: Launch Emulator
run: |
sh android-plugin/run-avd-ci.sh start \
--avd-name "${AVD_NAME}" \
--gpu "${{ matrix.backend.gpu }}" \
--emulator-log "${EMULATOR_LOG}" \
--pid-file "${EMULATOR_PID_FILE}" \
--boot-timeout 300
- name: Retrace and validate
env:
MOBILEGL_RETRACE_USE_ANGLE: ${{ matrix.backend.name == 'DirectGLES' && '1' || '0' }}
run: |
apk_file="$(find android-retrace-apks -name '${{ matrix.backend.apk }}' -print -quit)"
timeout "$(( ${{ matrix.case.timeout_seconds }} + 300 ))" sh android-plugin/trace-replay-ci.sh \
--apk-file "${apk_file}" \
--package "${{ matrix.backend.package }}" \
--backend "${{ matrix.backend.name }}" \
--result-root android-retrace-result \
--fixture-root android-retrace-fixture \
--case "${{ matrix.case.name }}" \
--trace-archive "${{ matrix.case.trace_archive }}" \
--trace-file "${{ matrix.case.trace_file }}" \
--golden "${{ matrix.case.golden }}" \
--alternate-golden "${{ matrix.case.alternate_golden || '' }}" \
--target-call "${{ matrix.case.target_call }}" \
--width "${{ matrix.case.width }}" \
--height "${{ matrix.case.height }}" \
--ssim-threshold "${{ matrix.case.ssim_threshold || '0.99' }}" \
--crop-x "${{ matrix.case.crop_x }}" \
--crop-y "${{ matrix.case.crop_y }}" \
--crop-width "${{ matrix.case.crop_width }}" \
--crop-height "${{ matrix.case.crop_height }}" \
--timeout-seconds "${{ matrix.case.timeout_seconds }}"
- name: Collect retrace summary inputs
if: always()
run: |
safe_case="$(printf '%s' '${{ matrix.case.name }}' | sed 's/[^A-Za-z0-9._-]/_/g')"
result_dir="android-retrace-result/${safe_case}-${{ matrix.backend.name }}"
mkdir -p "${result_dir}"
if [ -s "${{ matrix.case.golden }}" ]; then
cp "${{ matrix.case.golden }}" "${result_dir}/${safe_case}-${{ matrix.backend.name }}-golden.png"
fi
if [ -n "${{ matrix.case.alternate_golden || '' }}" ] && [ -s "${{ matrix.case.alternate_golden || '' }}" ]; then
cp "${{ matrix.case.alternate_golden || '' }}" "${result_dir}/${safe_case}-${{ matrix.backend.name }}-alternate-golden.png"
fi
- name: Collect emulator diagnostics
if: always()
run: |
mkdir -p android-retrace-result/diagnostics
adb devices -l > android-retrace-result/diagnostics/adb-devices.txt || true
timeout 30 adb logcat -d -t 1000 > android-retrace-result/diagnostics/logcat.txt || true
if [ -f "${EMULATOR_LOG}" ]; then
cp "${EMULATOR_LOG}" android-retrace-result/diagnostics/emulator.log
fi
- name: Stop Emulator
if: always()
run: |
sh android-plugin/run-avd-ci.sh stop \
--avd-name "${AVD_NAME}" \
--emulator-log "${EMULATOR_LOG}" \
--pid-file "${EMULATOR_PID_FILE}"
- name: Upload Android retrace result
if: always()
uses: actions/upload-artifact@v4
with:
name: MobileGL-android-retrace-result-${{ env.date_today }}-${{ env.short_sha }}-${{ matrix.backend.name }}-${{ matrix.case.name }}
path: android-retrace-result/**
if-no-files-found: warn
retrace-summary:
name: retrace summary
runs-on: ubuntu-latest
needs: retrace
if: always()
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set artifact metadata
run: |
echo "date_today=$(date +'%Y-%m-%d')" >> "$GITHUB_ENV"
echo "short_sha=${GITHUB_SHA::7}" >> "$GITHUB_ENV"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Download Android retrace results
uses: actions/download-artifact@v4
with:
pattern: MobileGL-android-retrace-result-*
path: retrace-artifacts
- name: Render retrace summary
run: |
node tools/trace_replay/render_retrace_summary.mjs \
--input retrace-artifacts \
--output-dir android-retrace-summary \
--title "MobileGL Android retrace overview" \
--group-label "Android Emulator" \
--html mobilegl-android-retrace-overview.html
- name: Upload Android retrace summary
uses: actions/upload-artifact@v7
with:
path: android-retrace-summary/mobilegl-android-retrace-overview.html
archive: false
if-no-files-found: error