Commit Graph
4073 Commits
Author SHA1 Message Date
swung0x48 239fc228fc [Fix] (DirectVulkan): retype gl_FragCoord access chains to Private when the y-flip pass redirects them to its copy 2026-10-02 13:34:16 -04:00
swung0x48 8da082f805 [Fix] (State): start the clear colour at GL's (0, 0, 0, 0), not opaque black 2026-10-02 12:50:36 -04:00
swung0x48 258b946086 [Fix] (P12): publish the server window's extent from the display on every resize, at once, and let eglQuerySurface take it in 2026-10-02 12:03:52 -04:00
swung0x48 16b07cf4b5 [Fix] (DirectVulkan): build offscreen targets of a window-created renderer through AImageReader instead of a null headless entry point 2026-10-02 11:42:14 -04:00
swung0x48 51c37bcbc9 [Fix] (Sampler): convert sampler parameters set through the other scalar type 2026-10-02 11:22:00 -04:00
swung0x48 5a7b23f661 [Feature] (P12): suspend the on-screen session when the server window goes, resume it on the next, and republish a resized window's extent 2026-10-02 11:14:27 -04:00
swung0x48 15f9b27a42 [Fix] (P14): publish a cached sampler CSO into each share group that names it 2026-10-02 10:35:44 -04:00
swung0x48 82d96a63c9 [Docs] (Anland): runbook and skill for bringing up MobileGL with anland and KDE Plasma 2026-10-02 10:31:35 -04:00
swung0x48 7520e53b5e [Feature] (SharedImage): GPU-side fences between sessions on Espryt and Magma, no CPU wait at present 2026-10-02 10:31:34 -04:00
swung0x48 b5cab44100 [Feature] (SharedImage): sync_file write/read fences per image, so sessions order their access without CPU waits 2026-10-02 09:40:12 -04:00
swung0x48 672261764e [Fix] (SharedImage): allocate and import ARGB8888/XRGB8888 images so KWin's offscreen Quick views get buffers 2026-10-02 09:37:17 -04:00
swung0x48 0e314f645e Remove a stray build log 2026-10-02 09:18:20 -04:00
swung0x48 350fc699a1 [Fix] (SharedImage): create dma-buf wl_buffers without create_immed, drain the ring before teardown ops, and decline Magma records after the renderer is gone 2026-10-02 09:18:05 -04:00
swung0x48 3d17e8c10b [Feature] (SharedImage): zero-copy Wayland windows via linux-dmabuf, EGL dma-buf import, GBM backend, and Espryt/Magma AHB present and texture binding 2026-10-02 08:39:59 -04:00
swung0x48 38842985f8 [Feature] (SharedImage): server-allocated AHB images over a shared_image pipe verb, with dma-buf fds on the aux socket 2026-10-02 07:52:25 -04:00
swung0x48 e06aabe812 [Docs] (Anland): plan for zero-copy windows via server-allocated AHB dma-bufs 2026-10-02 07:34:45 -04:00
swung0x48 67a97065b8 [Fix] (DirectVulkan): transpose quarter-turn viewports and scissors, rebuild a resized pbuffer's target, and leave out-of-range default-framebuffer reads unfilled 2026-10-02 07:15:47 -04:00
swung0x48 ec084959fa [Docs] (Anland): record the Magma bring-up to Espryt parity 2026-10-02 06:36:20 -04:00
swung0x48 4b388950e3 [Fix] (DirectVulkan): decline draws from storeless buffers and sample with defaults when a texture's sampler CSO is gone, as DirectGLES does 2026-10-02 06:33:53 -04:00
swung0x48 7e76a98d36 [Fix] (DirectVulkan): keep one renderer per session across its surfaces, follow bind_context to each context's surface, and keep the wire resource ops registered while any session lives 2026-10-02 06:24:13 -04:00
swung0x48 15dbe78ce6 [Fix] (DirectVulkan): give each served session its own renderer and Magma state 2026-10-02 05:52:38 -04:00
swung0x48 168808d1a7 [Fix] (DirectVulkan): advertise the GLSL 1.00-era ARB strings KWin gates on, and let a debug property pick the Android backend 2026-10-02 05:42:14 -04:00
swung0x48 75e1da4d1b [Docs] (Anland): record the lock-screen corruption root cause 2026-10-02 05:07:59 -04:00
swung0x48 cd610934d7 [Fix] (DirectGLES): scope object deaths to their session, and keep container objects and staging rings per native context 2026-10-02 05:07:59 -04:00
swung0x48 335637af38 [Docs] (Anland): record the GLX, Chrome and server-config fixes 2026-10-02 03:09:18 -04:00
swung0x48 4236b42a57 [Fix] (Server+Transpiler): configure the server once per process, and enable blend_func_extended for index-1 outputs 2026-10-02 03:09:17 -04:00
swung0x48 0b6842ac8b [Fix] (EGL+GL): let ANGLE's GL backend run on MobileGL (GBM displays, foreign wl_display, precision query, ES-free GL_VERSION) 2026-10-02 02:58:55 -04:00
swung0x48 47db68d557 [Feature] (GLX): serve as a glvnd GLX vendor and present remote X windows 2026-10-02 02:11:36 -04:00
swung0x48 ce11c9accd [Docs] (Anland): record the Chrome/dma-buf feedback fix 2026-10-02 01:45:03 -04:00
swung0x48 7bb9d9829f [Docs] (Anland): record the Plasma desktop milestone and the remaining issues 2026-10-02 01:38:57 -04:00
swung0x48 ccf8eb6571 [Fix] (Client): serialize multi-threaded GL streams, follow Wayland window resizes, export the KHR image aliases 2026-10-02 01:38:21 -04:00
swung0x48 0b314ddae7 [Fix] (P14): serialize sessions on one backend turn and give each client surface its own native surface 2026-10-02 01:38:20 -04:00
swung0x48 d5acece005 [Docs] (Anland): record the Plasma bring-up state after the P14 server-state fixes 2026-10-02 00:04:01 -04:00
swung0x48 30fef23d52 [Fix] (P14): scope the server staged stores and the context-live flag to the calling session 2026-10-02 00:04:00 -04:00
swung0x48 cbb87b968a [Docs] (Anland): drop the stale-glslang note and record d554c87c and the landed tooling 2026-10-01 23:36:27 -04:00
swung0x48 d554c87c45 [Fix] (Loader+Texture): tolerate drivers without EXT swap-with-damage, and pair stencil-only storage correctly
- eglSwapBuffersWithDamageEXT is an extension entry point that Android's
  framework libEGL does not export through dlsym; requiring it was a
  bring-up FATAL on TB321FU. Resolve EXT, fall back to the KHR spelling
  (same function, interchangeable signature), then to plain
  eglSwapBuffers (a zero-rectangle damage call is defined to be exactly
  that). The GLES dlsym fallback gains a self-reference guard for
  MobileGL installed under a GLES soname, where dlsym would otherwise
  hand the backend the frontend's own entry points and recurse forever.
- NormalizePixelFormat maps GL_STENCIL_INDEX8/GL_STENCIL_INDEX to
  GL_STENCIL_INDEX/GL_UNSIGNED_BYTE instead of falling through to
  RGBA/UBYTE, which no driver can pair with stencil-only storage.
- Tests pin the EXT->KHR->none preference order and the stencil pair.
- The anland handoff is rewritten to the post-P14 landed state: device
  evidence (win-smoke green screen, Konsole on screen, eglinfo/glxinfo),
  the remote-only recovery procedure, and the known gaps (Plasma session
  bring-up, cursor scale, the no-CPU-blit requirement, resize/surface
  loss, AVC audit).
2026-10-01 23:16:33 -04:00
swung0x48 7a48521d37 [Fix] (DirectGLES): destroy stale window surfaces before creating a new one
A session that dies without its teardown (crash, SIGKILLed client) leaks
its native window surface; the server-owned display window is one
ANativeWindow for the process's lifetime, and Adreno refuses a second
eglCreateWindowSurface on it with EGL_BAD_NATIVE_WINDOW - on TB321FU this
made every session after the first die with 'MobileGL could not acquire
the app Surface 300b'. InitWindowSurface now finds and destroys any
surface still bound to the window it is about to use, and the session
registry records the window with each surface to make that possible.
2026-10-01 22:32:53 -04:00
swung0x48 6946ff3a5c [Docs] (Anland): refresh the handoff to the post-P14 landed state
The document still described the state before the state-ownership work
landed: it called the unified server design unfinished, listed the
KernelSU grant as unsolved, said the directory bind had not taken effect,
and presented MobileGLAppsService plus the per-app fork worker as pending
drafts. None of that is true now.

Rewritten against the current tree and the device:

- header: architecture landed per the user's correction, acceptance still
  open; the rejected fork-worker/AppsService path is removed and the
  unified server lives in the MobileGL library (design 11-state-ownership,
  commits d52c031c / 4ed1c9ce / 5c6399e2 / ff212061 / 5a0f13fd, plus the
  landed 6fb880cd / ebc552a0 that used to be listed as uncommitted)
- MobileGL: HEAD moved to 5a0f13fd; the state-ownership section now records
  what S1-S6 landed and the debts that remain (process-level unit shadows,
  g_backendContextGeneration, per-record ContextSlot, the glIsBuffer probe,
  the window half of pbuffer->window)
- anland: 2ffa1f5 and 33e496c pushed; the draft inventory is now a landed
  inventory plus the three uncommitted KWin-acceptance fixes
- device: KernelSU grant resolved (reinstall changed the uid to 10270), the
  clone restarted with the directory bind effective, the 5a0f13fd APK
  serving @anland-mobilegl with six completed client sessions, and the
  client library installed with a stale build stamp
- new: concurrency warning (parallel sessions have overwritten the dist and
  the source tar), the current desktop-session.service failure state, and a
  rewritten continuation order

Verified: doc citations resolve (scripts/check_doc_citations.py), device
facts checked against HA27Q3LQ at refresh time.
2026-10-01 20:41:54 -04:00
swung0x48 5a0f13fdfa [Fix] (DirectGLES): advertise the GLSL 1.00-era ARB strings KWin gates on
GL_ARB_shader_objects/vertex_shader/fragment_shader and
GL_ARB_texture_non_power_of_two are core since GL 2.0 and trivially true
for the 4.6 this backend claims, but KWin 6's EglContext::checkSupported()
requires exactly these strings before it brings up compositing. Found on
TB321FU: kwin_wayland --anland failed with 'Could not initialize rendering
context' after a successful context create + makeCurrent on the
server-owned window surface.
2026-10-01 20:21:35 -04:00
swung0x48 ff2120616d [Feature] (P14): key the backend twin tables by session and share group
The last piece of state ownership this phase owed: the eight DirectGLES twin
tables resolved a handle process-wide, so two contexts of one session that do
NOT share a share group - which have independent name spaces, so the same
{slot, gen} in both is legal - were handed the SAME twin, driver ids,
persistent map and pooled store included. Two contexts that DO share a group
were served by whichever of them twinned first. Design and per-slice shape:
docs/Disaggregated/design/11-state-ownership.md (S6).

Key: DirectGLES.h's TwinKey{SessionKey, ShareGroupKey} - the same two words
the applier's object records are filed under, with the group derived by
MGPipeApplierShareGroupKeyFor so a record and the twin describing it can never
land in different buckets. Session is in the key because a twin names a driver
id and no driver id crosses a connection.

Resolution: SessionRuntime.cpp's ResolveThreadTwinKey, installed by
InstallSessionRuntimeHooks beside the S2 PipeInputs probe, the S4 native
tuple key and the S5 applier key. It reads the ThreadSessionScope's session
and CurrentContextToken() - apply-thread state only, never MG_State, so the
frontend-keyed-lookup prohibition on the apply thread still holds. A thread
that belongs to no session answers {0, 0}, which is the process singleton this
replaces; the monolith and every unit case are unchanged by construction.

Shape: SlotTables.h's SlotTableRegistry holds one SharedPtr bucket per key,
with a thread-local last-key memo. It forwards every handle-keyed entry -
GetOrCreate, FindByHandle, LiveGenAt, HandleOf, StateForHandle,
NoteStateForHandle, ReleaseByHandle, ForEachLive, the counters - to the
CALLING THREAD's bucket, so the ~150 call sites in Managers.cpp and
DirectGLES.cpp are literally unchanged. The holder list stays process-wide: a
death notice is about an object, not a bucket, and each shared holder is one
bucket. ForEachLive now walks the calling thread's bucket (what a context can
see is its own group); the death and diagnostic walks take the new
ForEachBucket.

DropEveryTwinForEndedServerSession is session-scoped: it runs on the apply
thread of the session that is ending, while S2 lets neighbour sessions keep
rendering in the same process. No session on the thread keeps the old
process-wide drop verbatim. Managers.h's "a texture is owned by exactly one
context (share groups are not implemented)" is corrected: a texture belongs to
a share group and its sibling contexts legitimately mutate it.

Tests: MG_Test/Wire/TwinOwnershipTest.cpp, five cases driving the real twin
tables with no EGL and no wire - the same handle in two nonshared groups is
two twins and neither overwrites the other; two contexts of one group resolve
ONE twin; a per-session drop takes only that session's; a thread with no
session still gets the process-wide table; and the six-registry template
repeats the first three. Negative control run and reverted: making the
registry answer a single {0, 0} bucket turns four of the five red.

Full host ctest against a stashed baseline, compared by test name: 0 new
failures. The one name in the difference set
(LogForwardChannel.APeerThatStopsReadingCostsWarnLinesNotTheCallersTime) is a
pre-existing flake, failing on the baseline too with the identical assertion.
The 103-case acceptance set plus the five new cases is 108/108 green.

Remaining debts (documented): the unit shadows (g_activeTextureUnit,
g_boundTexturesCache, g_boundSamplersCache) are still process-global; the
driver-level glIsBuffer probe is still not usable on this host, so sharing is
proven at the twin layer (the twin IS the object holding the driver id); the
backend context/sync generations are still process-wide; the per-record
ContextSlot is still S1's edge declaration.
2026-10-01 20:11:53 -04:00
swung0x48 5c6399e240 [Docs] (Design): record S5 landed shape and remaining twin-key debt 2026-10-01 19:23:57 -04:00
swung0x48 4ed1c9cef2 [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.
2026-10-01 19:16:41 -04:00
swung0x48 ebc552a048 [Fix] (WSI): report Wayland present failure and keep GLX drawables off XIDs
Wayland Present() failure now returns EGL_BAD_SURFACE instead of being
dropped. In spawn mode a GLX X drawable is backed by a remote pbuffer so
the XID is never mistaken for an Android ANativeWindow; X11 pixel present
and remote resize are still unimplemented.
2026-10-01 13:45:52 -04:00
swung0x48 6fb880cdf2 [Build] (Linux): alias libGL.so and libGL.so.1 to libMobileGL
GLX clients link against libGL; give the Linux build the same alias
treatment libEGL already had so glvnd-less clients can load MobileGL.
2026-10-01 13:45:51 -04:00
swung0x48 d52c031c50 [Docs] (Design): state ownership for multi-session/context/share-group (P14)
The whole stack assumes one process = one server = one session = one
context = one share group. The anland unified server needs that equation
broken in the library instead of fork-per-app workers. This document fixes
the four ownership layers (session, context, share group, thread current),
the wire changes (per-record context slot, CreateContext/DestroyContext
SurfaceOps, context-tagged reverse events), and the staged plan P14a-d
with acceptance tests.
2026-10-01 13:45:41 -04:00
swung0x48 4156ca6e36 [Docs] (Anland): hand off unified runtime work and record corrected state ownership requirements 2026-10-01 13:18:23 -04:00
swung0x48 2f64ede8c6 [Feature] (Remote): serve concurrent shared-memory clients in isolated workers 2026-10-01 12:53:27 -04:00
swung0x48 a5b463a5e8 [Feature] (Remote): expose a package-neutral embedded display server API 2026-10-01 12:31:57 -04:00
BZLZHH 32c79f4135 [Feature] (EGL): Wayland window surfaces, presented through wl_shm
A Wayland client's window is its own wl_surface, and what the compositor shows is the wl_buffer
attached to it - but the pixels of a MobileGL frame are drawn where the backend is, on a split
build in another process on another OS.  So far a wl_egl_window was taken for an X11 window and
its client-side address sent to the Android server (EGL_BAD_NATIVE_WINDOW at best), and under
glvnd a Wayland display never reached this vendor at all.

A window on a Wayland display - asked for as EGL_PLATFORM_WAYLAND, or a wl_display recognised by
its first word being wl_display_interface - is now a window surface in the EGL state at the
wl_egl_window's size with a pbuffer of that size behind it in the backend, whatever
MOBILEGL_IPC_SURFACE says.  At every swap the frame is read back out of the default framebuffer
through this library's own glReadPixels (the application's read framebuffer, pack buffer and pack
state put back as they were), its rows flipped and swizzled into a wl_shm buffer, and attached,
damaged and committed on the application's wl_surface.  Three buffers rotate on their release
events, dispatched on an event queue of the surface's own.  libwayland-client is loaded at run
time, so neither the build nor the library depends on it.  EGL_KHR_platform_wayland and
EGL_EXT_platform_wayland are announced on Linux.

Measured: glmark2-wayland runs its build scene at 13 FPS (400x300) and the window shows the frame
under kwin.  A window resize is not followed yet; the surface keeps its creation size.
2026-10-01 12:25:20 -04:00
gold f458924360 [Fix] (EGL): a second display is served, and glvnd gets its answers from one table
Two defects, both found by asking the client directly rather than by reading its log.

The backend refused to initialize any EGLDisplay but the first - "already bound to a different
EGLDisplay" - and the field it compared against has no reader anywhere else in the tree: the domain
rule was the whole of the rule.  What it cost was a compositor, which asks for the display it will
draw into AFTER probing another one.  The probe succeeded, the real display was refused, and the
caller reported the refusal one layer up as "no usable DRM render device" - a message that names
where it stopped, not why.

The second: glvnd asks a vendor for entry points from two places.  getProcAddress is how it builds
its own static EGL table, and getDispatchAddress is how it answers eglGetProcAddress for every name
it does not know itself - which is every extension entry point, the device queries among them.  This
side answered the second from a GL-only table, so an application asking for eglQueryDeviceStringEXT
got a null for a function the vendor implements.
2026-10-01 12:22:55 -04:00