mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
Reword the permanent client-window refusal text and drop the stale P12 tag.
This commit is contained in:
@@ -532,10 +532,11 @@ jobs:
|
||||
# MOBILEGL_IPC_SERVER_PATH IS DELIBERATELY ABSENT. nativeLibraryDir carries an
|
||||
# install-time hash, so nothing off the device can spell it; TraceReplayActivity
|
||||
# resolves it from getApplicationInfo() when the env asks for spawn, and an explicit
|
||||
# value would override that. --use-pbuffer is NOT optional here: until P12 a spawned
|
||||
# server cannot be handed a window at all, because an ANativeWindow* is a pointer
|
||||
# value would override that. --use-pbuffer is NOT optional here: a spawned
|
||||
# server cannot be handed the client's window, because an ANativeWindow* is a pointer
|
||||
# into the CLIENT's process and SetWindowHandle is refused on the way across with
|
||||
# Fatal{UnmigratedSurface, "AndroidNativeWindow@P12"} (Rule H).
|
||||
# Fatal{UnmigratedSurface, "AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server"} (Rule H, permanent;
|
||||
# a windowed client uses MOBILEGL_IPC_SURFACE=server instead).
|
||||
extra_retrace_args+=(
|
||||
--env "MOBILEGL_TRANSPORT=spawn;MOBILEGL_IPC_ROLE_SPLIT_STATE=1;MOBILEGL_IPC_STRICT_ERRORS=1;MOBILEGL_IPC_RUN_AHEAD=1;MOBILEGL_GPU_HANG_BUDGET_MS=${MOBILEGL_GPU_HANG_BUDGET_MS}"
|
||||
--use-pbuffer
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
#define MGL_FATAL_FAMILY_LIST(X) \
|
||||
X(ProtocolCorruption, ProtocolCorruption, "a record's bounds or self-describing length was violated") \
|
||||
X(UnmigratedVerb, ProtocolCorruption, "a wire verb slot P5/P6 does not implement was reached") \
|
||||
X(UnmigratedSurface, ProtocolCorruption, "a surface op named a client-process handle that means nothing here (P12)") \
|
||||
X(UnmigratedSurface, ProtocolCorruption, "a surface op named a client-process handle that means nothing here (a windowed client uses MOBILEGL_IPC_SURFACE=server)") \
|
||||
X(UnmigratedPipeInput, ProtocolCorruption, "a PipeInputs field with no field-ownership row was read across the boundary") \
|
||||
X(UnmigratedEmulation, ProtocolCorruption, "an emulation path the applier has no migrated arm for was reached") \
|
||||
X(RoleViolation, ProtocolCorruption, "a call ran on the wrong role/thread - an invariant the two roles must hold") \
|
||||
|
||||
@@ -228,8 +228,9 @@ namespace MobileGL::MG_Remote {
|
||||
}
|
||||
if (op.windowKind() == ::MobileGL::Wire::WindowKind::AndroidNativeWindow) {
|
||||
// The one refusal that is not corruption: the window kind is LEGAL and the token
|
||||
// is an ANativeWindow*, which names memory in the CLIENT's process. Real window
|
||||
// arrival is P12; until then this is refused by name at ServerApplyWireSurfaceOp.
|
||||
// is an ANativeWindow*, which names memory in the CLIENT's process. This is a
|
||||
// permanent rule (Rule H): such a handle can never cross, so it is refused by name
|
||||
// at ServerApplyWireSurfaceOp. A windowed client uses MOBILEGL_IPC_SURFACE=server.
|
||||
return SurfaceWireError::AndroidNativeWindowArrived;
|
||||
}
|
||||
if (op.windowKind() == ::MobileGL::Wire::WindowKind::MetalLayer) {
|
||||
@@ -315,16 +316,19 @@ namespace MobileGL::MG_Remote {
|
||||
static_cast<unsigned long long>(op.nativeToken()));
|
||||
} else if (error == SurfaceWireError::AndroidNativeWindowArrived) {
|
||||
(void)SessionLatch(MGFatalFamily::UnmigratedSurface,
|
||||
"MGPipe: Fatal{UnmigratedSurface, \"AndroidNativeWindow@P12\"} - a wire "
|
||||
"MGPipe: Fatal{UnmigratedSurface, \"AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server\"} - a wire "
|
||||
"SurfaceOp (%s) named an ANativeWindow*, which is a pointer into the "
|
||||
"CLIENT's process and means nothing here. Real window arrival is P12; "
|
||||
"until then the spawn surface path is pbuffer/surfaceless only",
|
||||
"CLIENT's process and means nothing here. A client-process window "
|
||||
"handle can never cross processes: a windowed out-of-process client must "
|
||||
"use MOBILEGL_IPC_SURFACE=server (the server owns the window); "
|
||||
"otherwise it is pbuffer/surfaceless only",
|
||||
::MobileGL::Wire::EnumNameSurfaceOpKind(op.kind()));
|
||||
} else if (error == SurfaceWireError::MetalLayerArrived) {
|
||||
(void)SessionLatch(MGFatalFamily::UnmigratedSurface,
|
||||
"MGPipe: Fatal{UnmigratedSurface, \"MetalLayer@P12\"} - a wire "
|
||||
"MGPipe: Fatal{UnmigratedSurface, \"MetalLayer:use-MOBILEGL_IPC_SURFACE=server\"} - a wire "
|
||||
"SurfaceOp named a CAMetalLayer* in the CLIENT's process. "
|
||||
"Real window arrival is P12");
|
||||
"A client-process window handle can never cross processes: use "
|
||||
"MOBILEGL_IPC_SURFACE=server (the server owns the window)");
|
||||
} else {
|
||||
(void)SessionLatch(MGFatalFamily::ProtocolCorruption,
|
||||
"MGPipe: Fatal{ProtocolCorruption, \"SurfaceOp\"} - a wire surface op "
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
// ERROR SEMANTICS. Decode is pure: it answers a SurfaceWireError. The FATALS live at the server
|
||||
// entry point, ServerApplyWireSurfaceOp, because "a wire op the server cannot honour" is a
|
||||
// contract violation, not a data problem: AndroidNativeWindowArrived dies
|
||||
// Fatal{UnmigratedSurface, "AndroidNativeWindow@P12"} (the ANativeWindow* means nothing in the
|
||||
// server's process; real window arrival is P12) and everything else dies
|
||||
// Fatal{UnmigratedSurface, "AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server"} (the ANativeWindow* means nothing in the
|
||||
// server's process, permanently - a windowed client uses MOBILEGL_IPC_SURFACE=server) and everything else dies
|
||||
// Fatal{ProtocolCorruption, "SurfaceOp"}. P6's control pump is the intended caller; P5f's unit
|
||||
// tests drive it directly. MetalLayerArrived likewise dies
|
||||
// Fatal{UnmigratedSurface, "MetalLayer@P12"}: CAMetalLayer* is also process-local.
|
||||
// Fatal{UnmigratedSurface, "MetalLayer:use-MOBILEGL_IPC_SURFACE=server"}: CAMetalLayer* is also process-local.
|
||||
//
|
||||
// P12 (on-screen server window). WindowKind::ServerOwned is the one window kind whose window is
|
||||
// NOT the client's: the server substitutes its own (ServerLoop.cpp's ServerOwned arm). The codec
|
||||
@@ -62,8 +62,8 @@ namespace MobileGL::MG_Remote {
|
||||
InprocOnlyOpOnTheWire, // a kind that may ride the inproc channel but never the wire
|
||||
WindowKindNamesNoBackend,// Surfaceless/Pbuffer where a window backend is required
|
||||
UnknownWindowKind, // a WindowKind the mapping table does not know
|
||||
MetalLayerArrived, // -> Fatal{UnmigratedSurface, "MetalLayer@P12"}
|
||||
AndroidNativeWindowArrived, // -> Fatal{UnmigratedSurface, "AndroidNativeWindow@P12"}
|
||||
MetalLayerArrived, // -> Fatal{UnmigratedSurface, "MetalLayer:use-MOBILEGL_IPC_SURFACE=server"}
|
||||
AndroidNativeWindowArrived, // -> Fatal{UnmigratedSurface, "AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server"}
|
||||
// P12 (on-screen server window), D2. WindowKind::ServerOwned is legal on
|
||||
// CreateWindowSurface only, and only with nativeToken 0:
|
||||
ServerOwnedTokenNotZero, // -> Fatal{ProtocolCorruption, "SurfaceOp.nativeToken"}, latched
|
||||
|
||||
@@ -30,8 +30,9 @@
|
||||
//
|
||||
// PROCESS-LOCAL WINDOW OBJECTS ARE REFUSED BY NAME on the wire: ANativeWindow* and
|
||||
// CAMetalLayer* mean nothing in the server process. SurfaceOpCodec names their refusals
|
||||
// AndroidNativeWindow@P12 and MetalLayer@P12, and they stay (Rule H): P12 does not carry a
|
||||
// client's window across, it gives the SERVER a window of its own (kServerOwnedWindowBackend
|
||||
// AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server and MetalLayer:use-MOBILEGL_IPC_SURFACE=server,
|
||||
// and they are permanent (Rule H): a client's window never crosses, a windowed client uses
|
||||
// MOBILEGL_IPC_SURFACE=server, which gives the SERVER a window of its own (kServerOwnedWindowBackend
|
||||
// below, WindowKind::ServerOwned on the wire).
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace {
|
||||
}
|
||||
|
||||
void LatchTheSession(Remote::Client::ClientSession& client, PeerReport& r) {
|
||||
// A CAMetalLayer* on the wire: Fatal{UnmigratedSurface, "MetalLayer@P12"}, latched.
|
||||
// A CAMetalLayer* on the wire: Fatal{UnmigratedSurface, "MetalLayer:use-MOBILEGL_IPC_SURFACE=server"}, latched.
|
||||
(void)SendSurfaceOp(client, r, static_cast<Uint8>(::MobileGL::Wire::SurfaceOpKind::CreateWindowSurface),
|
||||
static_cast<Uint8>(::MobileGL::Wire::WindowKind::MetalLayer), 0x1234);
|
||||
}
|
||||
|
||||
@@ -1298,14 +1298,14 @@ namespace {
|
||||
[](Transport::RingRecordHeader& h) { h.size = 12; });
|
||||
}},
|
||||
// ===== SurfaceOpCodec.cpp: the three wire refusals
|
||||
{"SurfaceOpAndroidNativeWindow", "SurfaceOpCodec.cpp", "AndroidNativeWindow@P12", Outcome::Latched,
|
||||
"Fatal{UnmigratedSurface, \"AndroidNativeWindow@P12\"}", false,
|
||||
{"SurfaceOpAndroidNativeWindow", "SurfaceOpCodec.cpp", "AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server", Outcome::Latched,
|
||||
"Fatal{UnmigratedSurface, \"AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server\"}", false,
|
||||
[](Client::ClientSession& c, PeerReport& r) {
|
||||
return SendSurfaceOp(c, r, kCreateWindowSurface,
|
||||
static_cast<Uint8>(::MobileGL::Wire::WindowKind::AndroidNativeWindow));
|
||||
}},
|
||||
{"SurfaceOpMetalLayer", "SurfaceOpCodec.cpp", "MetalLayer@P12", Outcome::Latched,
|
||||
"Fatal{UnmigratedSurface, \"MetalLayer@P12\"}", false,
|
||||
{"SurfaceOpMetalLayer", "SurfaceOpCodec.cpp", "MetalLayer:use-MOBILEGL_IPC_SURFACE=server", Outcome::Latched,
|
||||
"Fatal{UnmigratedSurface, \"MetalLayer:use-MOBILEGL_IPC_SURFACE=server\"}", false,
|
||||
[](Client::ClientSession& c, PeerReport& r) {
|
||||
return SendSurfaceOp(c, r, kCreateWindowSurface,
|
||||
static_cast<Uint8>(::MobileGL::Wire::WindowKind::MetalLayer));
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// agreement with the schema is pinned, not assumed;
|
||||
// * every framed op round-trips through a REAL CtrlEnvelope{SurfaceOp} buffer byte-for-byte;
|
||||
// * the wire entry refuses by NAME: an ANativeWindow* arriving over the wire dies
|
||||
// Fatal{UnmigratedSurface, "AndroidNativeWindow@P12"} (real windows are P12), and a kind the
|
||||
// Fatal{UnmigratedSurface, "AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server"} (a client window never crosses), and a kind the
|
||||
// schema does not define dies Fatal{ProtocolCorruption, "SurfaceOp"}.
|
||||
//
|
||||
// The inproc blocking path itself - posting, parking, the reply half coming back - is gated by
|
||||
@@ -446,7 +446,7 @@ TEST(SurfaceControlFrameTest, AnAndroidNativeWindowOnTheWireIsRefusedByName) {
|
||||
|
||||
EXPECT_EXIT(ServerApplyWireSurfaceOp(*wireOp, nullptr), ::testing::KilledBySignal(SIGABRT), ".*");
|
||||
const std::string log = ReadLog();
|
||||
EXPECT_NE(log.find("Fatal{UnmigratedSurface, \"AndroidNativeWindow@P12\"}"), std::string::npos)
|
||||
EXPECT_NE(log.find("Fatal{UnmigratedSurface, \"AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server\"}"), std::string::npos)
|
||||
<< "the abort happened but not for this rule's reason; the log says: " << log;
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ TEST(SurfaceControlFrameTest, AMetalLayerOnTheWireIsRefusedByName) {
|
||||
SurfaceControlFrame frame;
|
||||
EXPECT_EQ(DecodeWireSurfaceOp(*wireOp, &frame), SurfaceWireError::MetalLayerArrived);
|
||||
EXPECT_EXIT(ServerApplyWireSurfaceOp(*wireOp, nullptr), ::testing::KilledBySignal(SIGABRT), ".*");
|
||||
EXPECT_NE(ReadLog().find("Fatal{UnmigratedSurface, \"MetalLayer@P12\"}"), std::string::npos);
|
||||
EXPECT_NE(ReadLog().find("Fatal{UnmigratedSurface, \"MetalLayer:use-MOBILEGL_IPC_SURFACE=server\"}"), std::string::npos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -176,10 +176,10 @@ Java_top_mobilegl_plugin_trace_TraceReplayActivity_nativeRunTraceReplay(JNIEnv*
|
||||
// (apitrace_glws_android.cpp's createSurface), so handing Magma a window was the same as
|
||||
// asking for one.
|
||||
//
|
||||
// P6 needs the pbuffer path on BOTH backends. Until P12 a spawned server cannot be given a
|
||||
// window at all - an ANativeWindow* is a pointer into the CLIENT's process, and
|
||||
// P6 needs the pbuffer path on BOTH backends. A spawned server cannot be given the client's
|
||||
// window - an ANativeWindow* is a pointer into the CLIENT's process, and
|
||||
// SetWindowHandle is refused on the way across with Fatal{UnmigratedSurface,
|
||||
// "AndroidNativeWindow@P12"} (Rule H). Measured: the DirectVulkan spawn arm died on exactly
|
||||
// "AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server"} (Rule H, permanent; a windowed client uses MOBILEGL_IPC_SURFACE=server). Measured: the DirectVulkan spawn arm died on exactly
|
||||
// that, one op after the server had come up green, while DirectGLES with the same flag passed.
|
||||
//
|
||||
// Every existing caller is unaffected: nobody asks for a Vulkan pbuffer today, and
|
||||
|
||||
@@ -451,9 +451,10 @@ run_retrace() {
|
||||
fi
|
||||
# PBUFFER IS A SURFACE SHAPE, NOT A BACKEND PROPERTY, and the DirectGLES condition that used to
|
||||
# guard this line made it one. It was harmless while the only caller was the ANGLE lane; P6 needs
|
||||
# it on BOTH backends, because until P12 the spawn arm can only use pbuffer/surfaceless - an
|
||||
# it on BOTH backends, because the spawn arm can only use pbuffer/surfaceless (a windowed client
|
||||
# uses MOBILEGL_IPC_SURFACE=server) - an
|
||||
# ANativeWindow* is a pointer into the CLIENT's process and SetWindowHandle is refused by name
|
||||
# with Fatal{UnmigratedSurface, "AndroidNativeWindow@P12"} on the way across. Magma creates an
|
||||
# with Fatal{UnmigratedSurface, "AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server"} on the way across. Magma creates an
|
||||
# EGL pbuffer exactly as Espryt does.
|
||||
if [ "${use_pbuffer}" -eq 1 ]; then
|
||||
set -- "$@" --ez use_pbuffer true
|
||||
|
||||
@@ -116,7 +116,7 @@ indistinguishable from a run that produced none.
|
||||
as an explicit `--env MOBILEGL_TRANSPORT=…` and verifies it from the library's log.
|
||||
- **`MOBILEGL_RETRACE_USE_PBUFFER` must be in the CI script's environment**, not passed as `--env` —
|
||||
`trace-replay-ci.sh` reads it itself to decide the surface shape. Without it the `spawn` arm dies
|
||||
with `Fatal{UnmigratedSurface, "AndroidNativeWindow@P12"}`, because an `ANativeWindow*` means
|
||||
with `Fatal{UnmigratedSurface, "AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server"}`, because an `ANativeWindow*` means
|
||||
nothing in the server's process (Rule H).
|
||||
- **`MOBILEGL_TRACE_SKIP_INSTALL=1`** keeps the script's own `adb install` out of the window. The
|
||||
session installs once itself and waits for `dex2oat` to exit first: an `am_kill … due to
|
||||
|
||||
@@ -491,7 +491,7 @@ class Arm:
|
||||
|
||||
That is fatal on the spawn arm and only there: an ANativeWindow* is a pointer into the
|
||||
CLIENT's process and the wire refuses it by name (Rule H). Measured on this tree - the spawn
|
||||
arm died with `Fatal{UnmigratedSurface, "AndroidNativeWindow@P12"}` published as a
|
||||
arm died with `Fatal{UnmigratedSurface, "AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server"}` published as a
|
||||
SessionFault, and the same run passes as soon as the variable is in the script's environment.
|
||||
"""
|
||||
return {"MOBILEGL_RETRACE_USE_PBUFFER": "1"}
|
||||
|
||||
@@ -605,9 +605,9 @@ def parse_args():
|
||||
"--use-pbuffer",
|
||||
action="store_true",
|
||||
help="Render into a pbuffer instead of the Activity's window surface. REQUIRED with "
|
||||
"--transport spawn until P12: an ANativeWindow* is a pointer into the CLIENT's "
|
||||
"--transport spawn (a windowed client uses MOBILEGL_IPC_SURFACE=server instead): an ANativeWindow* is a pointer into the CLIENT's "
|
||||
"process and means nothing in the server's, so SetWindowHandle is refused by name "
|
||||
"with Fatal{UnmigratedSurface, \"AndroidNativeWindow@P12\"} (Rule H). The desktop "
|
||||
"with Fatal{UnmigratedSurface, \"AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server\"} (Rule H). The desktop "
|
||||
"retrace has always run pbuffer and matches the same goldens.",
|
||||
)
|
||||
parser.add_argument(
|
||||
|
||||
@@ -121,7 +121,7 @@ a window the **server** owns: the plugin's on-screen display server.
|
||||
|
||||
Without that, a `spawn` client that creates a window surface fails. With the default
|
||||
`MOBILEGL_IPC_SURFACE=offscreen`, the server rejects the window with
|
||||
`Fatal{UnmigratedSurface, "AndroidNativeWindow@P12"}`. With `MOBILEGL_IPC_SURFACE=server` and an
|
||||
`Fatal{UnmigratedSurface, "AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server"}`. With `MOBILEGL_IPC_SURFACE=server` and an
|
||||
offscreen server, the client logs `Refuse ServerOwned (NoServerDisplay)`.
|
||||
|
||||
Steps (client in FCL, server in the plugin, same device):
|
||||
|
||||
@@ -59,7 +59,7 @@ The renderer string does not mention Espryt or Magma.
|
||||
|
||||
| Message | Cause | Fix |
|
||||
|---|---|---|
|
||||
| `Fatal{UnmigratedSurface, "AndroidNativeWindow@P12"} ... until then the spawn surface path is pbuffer/surfaceless only` | A `spawn` client created a window surface with `MOBILEGL_IPC_SURFACE=offscreen`. An Android window cannot cross processes. (The text mentions a development phase; the limitation itself is permanent.) | Use the on-screen display server and `MOBILEGL_IPC_SURFACE=server` ([android-plugin.md](android-plugin.md#out-of-process-rendering-with-a-window)), or use `inproc` |
|
||||
| `Fatal{UnmigratedSurface, "AndroidNativeWindow:use-MOBILEGL_IPC_SURFACE=server"}` (a `MetalLayer:use-MOBILEGL_IPC_SURFACE=server` twin exists for macOS) | A `spawn` client created a window surface with `MOBILEGL_IPC_SURFACE=offscreen`. An Android window cannot cross processes. The limitation is permanent. (Servers older than this fix print `AndroidNativeWindow@P12` and mention a development phase; it means the same thing.) | Use the on-screen display server and `MOBILEGL_IPC_SURFACE=server` ([android-plugin.md](android-plugin.md#out-of-process-rendering-with-a-window)), or use `inproc` |
|
||||
| `Refuse ServerOwned (NoServerDisplay)` | `MOBILEGL_IPC_SURFACE=server`, but the server is offscreen (the plugin's service, a spawned server, any Linux server) | Start the plugin's server with **On-screen window** ticked |
|
||||
| `Refuse ServerOwned (NoServerWindow) ... is the display's surface visible?` | The display server's window was not visible when the client created its window surface | Bring the MobileGL display window to the front, then start the game |
|
||||
| `SurfaceModeMismatch` | The session's first surface was a pbuffer, so the session is offscreen; a later server window surface is refused | The application must create its window surface first |
|
||||
|
||||
Reference in New Issue
Block a user