mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Feature] (P14): state ownership - multi-session, multi-context, share groups
Breaks the one process = one server = one session = one context equation
that the whole stack's correctness used to rest on. Design and per-slice
shape: docs/Disaggregated/design/11-state-ownership.md.
S1 wire: bind_context ring record (opcode 84) announces the current
context at the make-current edge; CreateContext/DestroyContext join the
SurfaceOp control frames; control revision 5 -> 6; the server keeps a
per-session token table and refuses unknown tokens by name.
S2 server: SessionRuntime per session with thread-scoped resolution
(singletons become fallbacks), per-thread gPipeInputs, per-session latch
domains, per-thread segment resolvers; the in-process unix supervisor
serves up to MOBILEGL_IPC_INPROC_MAX_SESSIONS (16) concurrent sessions;
surface mode is declared per session and the display lease refuses a
second on-screen session by name.
S3 frontend: ShareGroupState owns the shared object stores and name
generators (buffer/texture/renderbuffer/sampler/program), GLContext keeps
per-context bindings/errors/container objects; pGLContext becomes
thread-local with a process default context preserving the single-context
world verbatim; eglCreateContext builds a real GLContext and joins the
sharing context's group.
S4 backend: native EGL tuples keyed by (session, context token);
InitDisplayAndContext's unconditional teardown is gone - creating a
second context or surface no longer destroys the first; eglCreateContext
sharing is wired to the native driver; bind_context is the native switch
point.
S5 applier: MGPipeApplierState splits into MGPipeObjectRecords (per
share group) and MGPipeWorkingState (per context), resolved through a
{session, token} registry with a thread-local cached fast path.
Tests: MultiSessionTest (incl. two sessions x two contexts interleaved
with real clear/readback witnesses), ApplierOwnershipTest (with a
null-resolver negative control), ContextStateOwnershipTest,
ServerLoopEglTest native-context liveness; 99/99 of the acceptance set
green on the host build.
Known debts (documented in the design doc): twin registries still keyed
by handle alone, no per-record ContextSlot, process-global backend
generations, MakeCurrent dedup per current binding.
This commit is contained in:
@@ -51,10 +51,20 @@ namespace MobileGL::MG_Remote {
|
||||
// cp's one schema addition, on the same append-only terms.
|
||||
static_assert(static_cast<Uint8>(SurfaceControlOp::InitCapabilities) ==
|
||||
static_cast<Uint8>(::MobileGL::Wire::SurfaceOpKind::InitCapabilities));
|
||||
// P14 S1's two appends, on the same append-only terms. The VALUES are pinned because they
|
||||
// are wire ABI, and pinned SEPARATELY from the identity cast beside them: the cast would
|
||||
// stay green if both enums moved together to 20/21, and a peer built before the move
|
||||
// would then read the two ops as two others.
|
||||
static_assert(static_cast<Uint8>(SurfaceControlOp::CreateContext) ==
|
||||
static_cast<Uint8>(::MobileGL::Wire::SurfaceOpKind::CreateContext));
|
||||
static_assert(static_cast<Uint8>(SurfaceControlOp::DestroyContext) ==
|
||||
static_cast<Uint8>(::MobileGL::Wire::SurfaceOpKind::DestroyContext));
|
||||
static_assert(static_cast<Uint8>(::MobileGL::Wire::SurfaceOpKind::SetSwapInterval) == 8 &&
|
||||
static_cast<Uint8>(::MobileGL::Wire::SurfaceOpKind::ReleaseResources) == 9 &&
|
||||
static_cast<Uint8>(::MobileGL::Wire::SurfaceOpKind::SetWindowHandle) == 10 &&
|
||||
static_cast<Uint8>(::MobileGL::Wire::SurfaceOpKind::InitCapabilities) == 11);
|
||||
static_cast<Uint8>(::MobileGL::Wire::SurfaceOpKind::InitCapabilities) == 11 &&
|
||||
static_cast<Uint8>(::MobileGL::Wire::SurfaceOpKind::CreateContext) == 12 &&
|
||||
static_cast<Uint8>(::MobileGL::Wire::SurfaceOpKind::DestroyContext) == 13);
|
||||
static_assert(static_cast<Uint8>(::MobileGL::Wire::WindowKind::MetalLayer) == 6);
|
||||
// P12's append, on the same terms: the value is wire ABI.
|
||||
static_assert(static_cast<Uint8>(::MobileGL::Wire::WindowKind::ServerOwned) == 7);
|
||||
@@ -112,7 +122,7 @@ namespace MobileGL::MG_Remote {
|
||||
// Fatal{ProtocolCorruption} at ServerApplyWireSurfaceOp rather than as
|
||||
// the missing row it is.
|
||||
if (::flatbuffers::IsOutRange(kind, ::MobileGL::Wire::SurfaceOpKind::InitializeDisplay,
|
||||
::MobileGL::Wire::SurfaceOpKind::InitCapabilities)) {
|
||||
::MobileGL::Wire::SurfaceOpKind::DestroyContext)) {
|
||||
return false;
|
||||
}
|
||||
const SurfaceControlOp op = static_cast<SurfaceControlOp>(static_cast<Uint8>(kind));
|
||||
@@ -174,7 +184,8 @@ namespace MobileGL::MG_Remote {
|
||||
}
|
||||
const auto op = ::MobileGL::Wire::CreateSurfaceOp(
|
||||
*builder, frame.seq, kind, frame.display, frame.surface, windowKind, nativeToken,
|
||||
frame.width, frame.height, frame.swapInterval, frame.readSurface, frame.context);
|
||||
frame.width, frame.height, frame.swapInterval, frame.readSurface, frame.context,
|
||||
frame.shareGroupToken, frame.contextFlags);
|
||||
const auto envelope = ::MobileGL::Wire::CreateCtrlEnvelope(*builder, ::MobileGL::Wire::CtrlMsg::SurfaceOp, op.Union());
|
||||
::MobileGL::Wire::FinishCtrlEnvelopeBuffer(*builder, envelope);
|
||||
return SurfaceWireError::None;
|
||||
@@ -195,6 +206,8 @@ namespace MobileGL::MG_Remote {
|
||||
decoded.width = op.width();
|
||||
decoded.height = op.height();
|
||||
decoded.swapInterval = op.swapInterval();
|
||||
decoded.shareGroupToken = op.shareGroupToken();
|
||||
decoded.contextFlags = op.contextFlags();
|
||||
if (OpNeedsAWindowBackend(kind)) {
|
||||
if (op.windowKind() == ::MobileGL::Wire::WindowKind::ServerOwned) {
|
||||
// P12 (D2). Asked BEFORE the Android refusal below, which it is not: the window is
|
||||
|
||||
Reference in New Issue
Block a user