mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Fix] (trace-replay): use ANGLE for DirectGLES APK retrace
This commit is contained in:
@@ -75,6 +75,16 @@ jobs:
|
|||||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
|
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
|
||||||
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
|
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
|
- 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)"
|
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:
|
env:
|
||||||
@@ -444,6 +454,8 @@ jobs:
|
|||||||
--boot-timeout 300
|
--boot-timeout 300
|
||||||
|
|
||||||
- name: Retrace and validate
|
- name: Retrace and validate
|
||||||
|
env:
|
||||||
|
MOBILEGL_RETRACE_USE_ANGLE: ${{ matrix.backend.name == 'DirectGLES' && '1' || '0' }}
|
||||||
run: |
|
run: |
|
||||||
apk_file="$(find android-retrace-apks -name '${{ matrix.backend.apk }}' -print -quit)"
|
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 \
|
timeout "$(( ${{ matrix.case.timeout_seconds }} + 300 ))" sh android-plugin/trace-replay-ci.sh \
|
||||||
|
|||||||
@@ -22,4 +22,5 @@ MobileGL/MG*/cmake-build*
|
|||||||
/android-plugin/.gradle
|
/android-plugin/.gradle
|
||||||
/android-plugin/build
|
/android-plugin/build
|
||||||
/android-plugin/app/build
|
/android-plugin/app/build
|
||||||
|
/android-plugin/app/src/trace/jniLibs
|
||||||
tools/trace_replay/work/
|
tools/trace_replay/work/
|
||||||
|
|||||||
@@ -10,6 +10,11 @@
|
|||||||
#include "MG_Util/Types.h"
|
#include "MG_Util/Types.h"
|
||||||
|
|
||||||
namespace MobileGL::MG_Util::BackendLoader {
|
namespace MobileGL::MG_Util::BackendLoader {
|
||||||
|
static Bool UseRetraceAngle() {
|
||||||
|
const char* value = std::getenv("MOBILEGL_RETRACE_USE_ANGLE");
|
||||||
|
return value != nullptr && std::strcmp(value, "1") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void* OpenLib(const Vector<String>& names) {
|
static void* OpenLib(const Vector<String>& names) {
|
||||||
#if !defined(__WIN32) && !defined(_WIN32) && !defined(__APPLE__)
|
#if !defined(__WIN32) && !defined(_WIN32) && !defined(__APPLE__)
|
||||||
static const String LibPathPrefixes[] = {
|
static const String LibPathPrefixes[] = {
|
||||||
@@ -433,10 +438,15 @@ namespace MobileGL::MG_Util::BackendLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AcquireEGLFunctions(MG_External::EGLFunctionsTable& funcs) {
|
void AcquireEGLFunctions(MG_External::EGLFunctionsTable& funcs) {
|
||||||
static const Vector<String> EGLLibNames = {"libEGL.so"};
|
Vector<String> eglLibNames = {"libEGL.so"};
|
||||||
void* eglLib = OpenLib(EGLLibNames);
|
if (UseRetraceAngle()) {
|
||||||
|
OpenLib({"libGLESv2_angle.so"});
|
||||||
|
eglLibNames = {"libEGL_angle.so", "libEGL.so"};
|
||||||
|
}
|
||||||
|
|
||||||
|
void* eglLib = OpenLib(eglLibNames);
|
||||||
if (!eglLib) {
|
if (!eglLib) {
|
||||||
MGLOG_E("Failed to open libEGL.so");
|
MGLOG_E("Failed to open EGL library");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ crop_x optional compare crop x
|
|||||||
crop_y optional compare crop y
|
crop_y optional compare crop y
|
||||||
crop_width optional compare crop width
|
crop_width optional compare crop width
|
||||||
crop_height optional compare crop height
|
crop_height optional compare crop height
|
||||||
|
use_angle optional boolean; DirectGLES uses packaged ANGLE when true
|
||||||
```
|
```
|
||||||
|
|
||||||
Implementation notes:
|
Implementation notes:
|
||||||
@@ -48,6 +49,7 @@ Implementation notes:
|
|||||||
- `DirectGLES` replays on an EGL pbuffer by default, avoiding Android `SurfaceView` lifetime coupling. `DirectVulkan` still uses the Activity surface because it needs a native window-backed Vulkan swapchain.
|
- `DirectGLES` replays on an EGL pbuffer by default, avoiding Android `SurfaceView` lifetime coupling. `DirectVulkan` still uses the Activity surface because it needs a native window-backed Vulkan swapchain.
|
||||||
- Golden comparison is implemented in native C++ with libpng RGBA decode. The Java Activity only passes arguments and displays the native result, so the replay/compare core is not tied to Android UI or Bitmap APIs and can be ported to Linux.
|
- Golden comparison is implemented in native C++ with libpng RGBA decode. The Java Activity only passes arguments and displays the native result, so the replay/compare core is not tied to Android UI or Bitmap APIs and can be ported to Linux.
|
||||||
- The plugin profile still excludes `libtrace_replay_runner.so`; normal plugin APK behavior is preserved.
|
- The plugin profile still excludes `libtrace_replay_runner.so`; normal plugin APK behavior is preserved.
|
||||||
|
- Set `MOBILEGL_RETRACE_USE_ANGLE=1` when running `trace-replay-ci.sh` to pass `use_angle=true` for DirectGLES. The APK must include `libEGL_angle.so` and `libGLESv2_angle.so` under its x86_64 native libraries.
|
||||||
|
|
||||||
Example core-profile trace smoke command for a debug trace APK:
|
Example core-profile trace smoke command for a debug trace APK:
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,17 @@ bool Exists(const std::string& path) {
|
|||||||
return !path.empty() && stat(path.c_str(), &st) == 0 && S_ISREG(st.st_mode);
|
return !path.empty() && stat(path.c_str(), &st) == 0 && S_ISREG(st.st_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UseAngleForRequest(const Request& request) {
|
||||||
|
if (request.backend != "DirectGLES") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (request.useAngle) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const char* value = getenv("MOBILEGL_RETRACE_USE_ANGLE");
|
||||||
|
return value != nullptr && strcmp(value, "1") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool EnsureDirectory(const std::string& path) {
|
bool EnsureDirectory(const std::string& path) {
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -116,6 +127,9 @@ bool LoadMobileGL(const Request& request, std::string& error) {
|
|||||||
setenv("MOBILEGL_BACKEND_TYPE", request.backend.c_str(), 1);
|
setenv("MOBILEGL_BACKEND_TYPE", request.backend.c_str(), 1);
|
||||||
setenv("MOBILEGL_TRACE_LIBRARY", request.mobileGlLibrary.c_str(), 1);
|
setenv("MOBILEGL_TRACE_LIBRARY", request.mobileGlLibrary.c_str(), 1);
|
||||||
setenv("MOBILEGL_TRACE_SKIP_AUTODESTROY", "1", 1);
|
setenv("MOBILEGL_TRACE_SKIP_AUTODESTROY", "1", 1);
|
||||||
|
if (UseAngleForRequest(request)) {
|
||||||
|
setenv("MOBILEGL_RETRACE_USE_ANGLE", "1", 1);
|
||||||
|
}
|
||||||
|
|
||||||
void* handle = dlopen(request.mobileGlLibrary.c_str(), RTLD_NOW | RTLD_GLOBAL);
|
void* handle = dlopen(request.mobileGlLibrary.c_str(), RTLD_NOW | RTLD_GLOBAL);
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
@@ -734,6 +748,7 @@ bool WriteResultJson(const Request& request, const Result& result) {
|
|||||||
file << " \"cropHeight\": " << request.cropHeight << ",\n";
|
file << " \"cropHeight\": " << request.cropHeight << ",\n";
|
||||||
file << " \"tolerance\": " << request.tolerance << ",\n";
|
file << " \"tolerance\": " << request.tolerance << ",\n";
|
||||||
file << " \"fuzzPercent\": " << request.fuzzPercent << ",\n";
|
file << " \"fuzzPercent\": " << request.fuzzPercent << ",\n";
|
||||||
|
file << " \"useAngle\": " << (UseAngleForRequest(request) ? "true" : "false") << ",\n";
|
||||||
file << " \"mismatchPixels\": " << result.mismatchPixels << "\n";
|
file << " \"mismatchPixels\": " << result.mismatchPixels << "\n";
|
||||||
file << "}\n";
|
file << "}\n";
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ struct Request {
|
|||||||
int cropHeight = 0;
|
int cropHeight = 0;
|
||||||
int tolerance = 0;
|
int tolerance = 0;
|
||||||
int fuzzPercent = 20;
|
int fuzzPercent = 20;
|
||||||
|
bool useAngle = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Result {
|
struct Result {
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ Java_top_mobilegl_plugin_trace_TraceReplayActivity_nativeRunTraceReplay(JNIEnv*
|
|||||||
jint cropY,
|
jint cropY,
|
||||||
jint cropWidth,
|
jint cropWidth,
|
||||||
jint cropHeight,
|
jint cropHeight,
|
||||||
jint fuzzPercent) {
|
jint fuzzPercent,
|
||||||
|
jboolean useAngle) {
|
||||||
mobilegl_trace::Request request;
|
mobilegl_trace::Request request;
|
||||||
request.tracePath = ToString(env, tracePath);
|
request.tracePath = ToString(env, tracePath);
|
||||||
request.goldenPath = ToString(env, goldenPath);
|
request.goldenPath = ToString(env, goldenPath);
|
||||||
@@ -119,6 +120,7 @@ Java_top_mobilegl_plugin_trace_TraceReplayActivity_nativeRunTraceReplay(JNIEnv*
|
|||||||
request.cropWidth = cropWidth;
|
request.cropWidth = cropWidth;
|
||||||
request.cropHeight = cropHeight;
|
request.cropHeight = cropHeight;
|
||||||
request.fuzzPercent = fuzzPercent;
|
request.fuzzPercent = fuzzPercent;
|
||||||
|
request.useAngle = useAngle == JNI_TRUE;
|
||||||
|
|
||||||
ScopedTraceReplayState replayState;
|
ScopedTraceReplayState replayState;
|
||||||
mobilegl_trace_set_requested_size(request.width, request.height);
|
mobilegl_trace_set_requested_size(request.width, request.height);
|
||||||
|
|||||||
+10
-4
@@ -110,7 +110,8 @@ public final class TraceReplayActivity extends Activity {
|
|||||||
request.cropY,
|
request.cropY,
|
||||||
request.cropWidth,
|
request.cropWidth,
|
||||||
request.cropHeight,
|
request.cropHeight,
|
||||||
request.fuzzPercent
|
request.fuzzPercent,
|
||||||
|
request.useAngle
|
||||||
);
|
);
|
||||||
Log.i(TAG, result.toString());
|
Log.i(TAG, result.toString());
|
||||||
TraceReplayResult finalResult = result;
|
TraceReplayResult finalResult = result;
|
||||||
@@ -137,7 +138,8 @@ public final class TraceReplayActivity extends Activity {
|
|||||||
int cropY,
|
int cropY,
|
||||||
int cropWidth,
|
int cropWidth,
|
||||||
int cropHeight,
|
int cropHeight,
|
||||||
int fuzzPercent
|
int fuzzPercent,
|
||||||
|
boolean useAngle
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final class TraceReplayRequest {
|
private static final class TraceReplayRequest {
|
||||||
@@ -157,6 +159,7 @@ public final class TraceReplayActivity extends Activity {
|
|||||||
final int cropWidth;
|
final int cropWidth;
|
||||||
final int cropHeight;
|
final int cropHeight;
|
||||||
final int fuzzPercent;
|
final int fuzzPercent;
|
||||||
|
final boolean useAngle;
|
||||||
|
|
||||||
private TraceReplayRequest(
|
private TraceReplayRequest(
|
||||||
String tracePath,
|
String tracePath,
|
||||||
@@ -174,7 +177,8 @@ public final class TraceReplayActivity extends Activity {
|
|||||||
int cropY,
|
int cropY,
|
||||||
int cropWidth,
|
int cropWidth,
|
||||||
int cropHeight,
|
int cropHeight,
|
||||||
int fuzzPercent
|
int fuzzPercent,
|
||||||
|
boolean useAngle
|
||||||
) {
|
) {
|
||||||
this.tracePath = tracePath;
|
this.tracePath = tracePath;
|
||||||
this.goldenPath = goldenPath;
|
this.goldenPath = goldenPath;
|
||||||
@@ -192,6 +196,7 @@ public final class TraceReplayActivity extends Activity {
|
|||||||
this.cropWidth = cropWidth;
|
this.cropWidth = cropWidth;
|
||||||
this.cropHeight = cropHeight;
|
this.cropHeight = cropHeight;
|
||||||
this.fuzzPercent = fuzzPercent;
|
this.fuzzPercent = fuzzPercent;
|
||||||
|
this.useAngle = useAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TraceReplayRequest from(Intent intent, File filesDir, String defaultBackend) {
|
static TraceReplayRequest from(Intent intent, File filesDir, String defaultBackend) {
|
||||||
@@ -213,7 +218,8 @@ public final class TraceReplayActivity extends Activity {
|
|||||||
intent.getIntExtra("crop_y", 0),
|
intent.getIntExtra("crop_y", 0),
|
||||||
intent.getIntExtra("crop_width", 0),
|
intent.getIntExtra("crop_width", 0),
|
||||||
intent.getIntExtra("crop_height", 0),
|
intent.getIntExtra("crop_height", 0),
|
||||||
intent.getIntExtra("fuzz_percent", 20)
|
intent.getIntExtra("fuzz_percent", 20),
|
||||||
|
intent.getBooleanExtra("use_angle", false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ Usage:
|
|||||||
--crop-height N \
|
--crop-height N \
|
||||||
--fuzz-percent N \
|
--fuzz-percent N \
|
||||||
--timeout-seconds N
|
--timeout-seconds N
|
||||||
|
|
||||||
|
Set MOBILEGL_RETRACE_USE_ANGLE=1 to run DirectGLES replay with packaged ANGLE
|
||||||
|
instead of the device system GLES driver.
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,9 +198,13 @@ copy_fixture_to_app() {
|
|||||||
run_retrace() {
|
run_retrace() {
|
||||||
result_dir="${result_root}/${safe_case}-${backend}"
|
result_dir="${result_root}/${safe_case}-${backend}"
|
||||||
alternate_golden_app_path=""
|
alternate_golden_app_path=""
|
||||||
|
use_angle=0
|
||||||
if [ -n "${alternate_golden_path}" ]; then
|
if [ -n "${alternate_golden_path}" ]; then
|
||||||
alternate_golden_app_path="${app_dir}/input/alternate-golden.png"
|
alternate_golden_app_path="${app_dir}/input/alternate-golden.png"
|
||||||
fi
|
fi
|
||||||
|
if [ "${MOBILEGL_RETRACE_USE_ANGLE:-}" = "1" ] && [ "${backend}" = "DirectGLES" ]; then
|
||||||
|
use_angle=1
|
||||||
|
fi
|
||||||
|
|
||||||
mkdir -p "${result_dir}"
|
mkdir -p "${result_dir}"
|
||||||
"${ADB}" install -r "${apk_file}"
|
"${ADB}" install -r "${apk_file}"
|
||||||
@@ -211,6 +218,9 @@ run_retrace() {
|
|||||||
if [ -n "${alternate_golden_app_path}" ]; then
|
if [ -n "${alternate_golden_app_path}" ]; then
|
||||||
set -- "$@" --es alternate_golden_path "${alternate_golden_app_path}"
|
set -- "$@" --es alternate_golden_path "${alternate_golden_app_path}"
|
||||||
fi
|
fi
|
||||||
|
if [ "${use_angle}" -eq 1 ]; then
|
||||||
|
set -- "$@" --ez use_angle true
|
||||||
|
fi
|
||||||
set -- "$@" \
|
set -- "$@" \
|
||||||
--es output_dir "${app_dir}/output" \
|
--es output_dir "${app_dir}/output" \
|
||||||
--es diff_path "${app_dir}/output/${safe_case}-diff.png" \
|
--es diff_path "${app_dir}/output/${safe_case}-diff.png" \
|
||||||
|
|||||||
Reference in New Issue
Block a user