[Fix] (trace-replay): stabilize GL4ES OpenRA validation

This commit is contained in:
2026-06-15 22:27:39 +08:00
parent bc8109b695
commit 4c2c4cb565
4 changed files with 51 additions and 6 deletions
@@ -1665,8 +1665,15 @@ void main() {
MOBILEGL_ASSERT(m_vertexInputStateFactory != nullptr, "VertexInputStateFactory creation failed.");
// Prime the first frame so Render() always targets an acquired swapchain image.
VK_VERIFY(m_frameContext.WaitAndAcquireNextImage(m_device, m_swapchainObject.GetHandle(), m_imageIndexAcquired),
"Initialize, WaitAndAcquireNextImage");
VkResult acquireResult =
m_frameContext.WaitAndAcquireNextImage(m_device, m_swapchainObject.GetHandle(), m_imageIndexAcquired);
if (acquireResult == VK_ERROR_OUT_OF_DATE_KHR || acquireResult == VK_SUBOPTIMAL_KHR) {
MGLOG_D("Initialize, vkAcquireNextImageKHR got %d, recreating swapchain", acquireResult);
RecreateSwapchain();
acquireResult =
m_frameContext.WaitAndAcquireNextImage(m_device, m_swapchainObject.GetHandle(), m_imageIndexAcquired);
}
VK_VERIFY(acquireResult, "Initialize, WaitAndAcquireNextImage");
m_textureManager->BeginFrame(m_frameContext.GetCurrentFrameIndex());
m_bufferManager.BeginFrame(m_frameContext.GetCurrentFrameIndex());
m_transientVertexIndexBufferSlicesThisFrame.clear();
@@ -3,6 +3,8 @@ package top.mobilegl.plugin.trace;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
@@ -24,6 +26,7 @@ public final class TraceReplayActivity extends Activity {
private TextView statusView;
private TraceReplayRequest request;
private boolean started;
private final Handler mainHandler = new Handler(Looper.getMainLooper());
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -58,11 +61,12 @@ public final class TraceReplayActivity extends Activity {
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
scheduleReplay(holder);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
startReplay(holder);
scheduleReplay(holder);
}
@Override
@@ -71,13 +75,21 @@ public final class TraceReplayActivity extends Activity {
});
}
private void scheduleReplay(SurfaceHolder holder) {
mainHandler.postDelayed(() -> startReplay(holder), 250);
}
private void startReplay(SurfaceHolder holder) {
if (started) {
return;
}
Surface surface = holder.getSurface();
if (surface == null || !surface.isValid()) {
return;
}
started = true;
statusView.setText("Running trace replay\n" + request.outputDir);
new Thread(() -> runRequest(request, holder.getSurface()), "MobileGLTraceReplay").start();
new Thread(() -> runRequest(request, surface), "MobileGLTraceReplay").start();
}
private void runRequest(TraceReplayRequest request, Surface surface) {
+22
View File
@@ -0,0 +1,22 @@
# GL4ES Trace Inventory
The GL4ES repository currently provides these apitrace fixtures under
`NG-GL4ES/NG-GL4ES/traces` with reference images under `NG-GL4ES/NG-GL4ES/refs`.
MobileGL's trace replay tests only use traces that exercise a core-profile style
OpenGL path. Compatibility/fixed-function traces are intentionally excluded.
| Trace | Status | Reason |
| --- | --- | --- |
| `openra` | Included | No fixed-function calls were detected in the trace scan, and it passes Linux replay on both `DirectGLES` and `DirectVulkan`. |
| `glsl_lighting` | Excluded | Uses compatibility matrix-stack calls (`glLoadIdentity`, `glPopMatrix`) and replays to a black image on MobileGL (`DirectGLES` mismatchPixels=30659 against the GL4ES reference). |
| `descent3` | Excluded | Uses fixed-function calls such as `glBegin`, `glEnd`, `glAlphaFunc`, `glOrtho`, and client arrays. |
| `foobillardplus` | Excluded | Uses display lists, matrix stack, material/fog state, and fixed-function client arrays. |
| `glxgears` | Excluded | Uses display lists, `glBegin`/`glEnd`, matrix stack, and material state. |
| `neverball` | Excluded | Uses display lists, `glBegin`/`glEnd`, fixed-function lighting/material state, clip planes, and matrix stack. |
| `pointsprite` | Excluded | Uses `glBegin`/`glEnd`, matrix stack, `glOrtho`, and fixed-function point state. |
| `stuntcarracer` | Excluded | Uses `glBegin`/`glEnd`, matrix stack, `glAlphaFunc`, and fixed-function client arrays. |
The scan is deliberately conservative: a trace is only added as a MobileGL
regression fixture after it replays and validates against its reference image on
Linux and Android. Traces that mainly test GL4ES compatibility behavior should
remain outside MobileGL core-profile CI.
+6 -2
View File
@@ -3,6 +3,10 @@
This directory builds a Linux command line replay runner for apitrace files. It is meant for CI coverage of MobileGL
without Android, APK packaging, FCL, or plugin runtime dependencies.
The bundled `openra` fixture comes from GL4ES' apitrace corpus. See
[GL4ES_TRACES.md](GL4ES_TRACES.md) for the current inventory and the traces that
were rejected because they rely on compatibility/fixed-function OpenGL.
Build from the MobileGL repository root:
```sh
@@ -39,5 +43,5 @@ build-test/tools/trace_replay/mobilegl_trace_replay \
--fuzz-percent 20
```
The Linux runner loads MobileGL by path with `dlopen`. It uses an EGL pbuffer for `DirectGLES` and an X11 window
surface for `DirectVulkan` so Magma can create a Vulkan swapchain under `xvfb-run` in CI.
The Linux runner loads MobileGL by path with `dlopen`. It uses an EGL pbuffer for `DirectGLES` and maps the pbuffer
path to `VK_EXT_headless_surface` for `DirectVulkan`, so CI does not need an X11 or Wayland window.