kwin never creates an EGL window surface. Its undefined libgbm symbols are seventeen entry points
whose whole purpose is to hand out gbm_bo fds, and those fds are what Anland's display producer
sends to the daemon on the phone - so the question "whose pixels are on the screen" is answered by
"who allocated the bo", and today that is Mesa. The client can be loaded, initialized and rendering
through glvnd with no window surface ever created, which is exactly what was measured.
This is a complete GBM: every public entry point of the vendored Mesa header, with the semantics a
compositor relies on - fds the caller owns, real mmap with refcounting, a swapchain that refuses to
hand out a busy buffer, import by fd, and teardown that leaves no descriptor or mapping behind. The
buffers come from the display host's frames; where there is no host, the device allocates from the
dma-buf heap, falling back to an uncached heap and then to memfd, so the library stands on its own.
The vendored gbm.h is Mesa's, verbatim: the entry points are the ABI, not our idea of it.
Two MIT headers from libglvnd, verbatim, because MobileGL is about to implement the vendor half of
glvnd's EGL ABI and the distribution ships the runtime without them.
- 3rdparty/flatbuffers submodule pinned to the latest release tag v25.12.19 (7e163021). The runtime is header-only, so only 3rdparty/flatbuffers/include is ever used and no library is linked; CMake never calls add_subdirectory on it and flatc is not in the build graph (plan B section 8.1, inheriting the earlier plan's section 7.1).
- MobileGL/MG_Remote/Protocol/protocol.fbs carries the CONTROL PLANE only: SegmentRef, Hello, Welcome, CapsSnapshot, DefaultFramebufferInfo, SurfaceOp, SurfaceReply, ResyncRequest, ResyncDone, AuxRequest, Fatal, LogLine, union CtrlMsg and the CtrlEnvelope root with a file_identifier. Hot-path records are FlatBuffers structs generated from MG_Pipe/PipeCalls.def in a later package and are deliberately absent here, so record numbering never churns.
- Two deviations from the earlier plan's section 7.1 sketch, both deliberate: (a) ProgramReflection is not a union member - plan B ships program artifacts inside the create_shader_state CSO blob (section 8.2), and union tags are wire values that may only ever be appended, so reserving a tag for a message that may never exist is worse than appending one later; (b) maxComputeWorkGroupCount/Size are vectors, not [int:3] - fixed-size arrays are legal only in FlatBuffers structs, never in tables.
- scripts/gen_protocol.py resolves flatc as MOBILEGL_FLATC_EXECUTABLE, otherwise builds the pinned flatc ONCE into <repo>/../flatc-build (override with MOBILEGL_FLATC_BUILD_DIR), outside the project build graph. A flatc found on PATH is deliberately refused and a version mismatch against the pinned runtime is a hard error: the generated header static_asserts FLATBUFFERS_VERSION, so a stray flatc either fails to compile or churns the committed file on every machine. The earlier branch did the opposite - Protocol/CMakeLists.txt:22-38 add_subdirectory'd the FlatBuffers tree with FLATBUFFERS_BUILD_FLATC=ON whenever MOBILEGL_FLATC_EXECUTABLE was unset, which is exactly the NDK trap it claimed to avoid (cross-compile an arm64 flatc, then run it on the host).
- protocol_generated.h is committed with the project source header prepended by the generator, so regeneration is byte-identical: verified by running gen_protocol.py twice and by perturbing the file and regenerating it back.
- Reuse from Feat/CS-Delta-IPC: MobileGL/Protocol/mg_protocol_base.h, kept as the shared C vocabulary (result codes, byte spans, shm region, id typedefs) and keeping the structSize-first versioning discipline that section 14.2 calls the answer to risk B-R10. Dropped from it: MobileGLObjectKind / MobileGLObjectScope / MobileGLObjectHandle - plan B never puts GL object identity on the wire (the frontend allocates {slot, generation} handles in MG_Pipe, section 4.2.1), so a second identity vocabulary would be a drift surface with no reader. Added MOBILEGL_ERR_BUFFER_TOO_SMALL as an append-only code for the receive contract.
Standalone Asio (submodule, asio-1-38-2 @ 8806a680, ASIO_STANDALONE +
ASIO_NO_DEPRECATED, header-only - no linked artifact) and the job machinery
the async shader pipeline will run on: JobNode (state machine with deferred
errors, continuations firing exactly once, dependency counters, cancel
semantics split into request vs outcome) and ShaderCompilePool
(asio::thread_pool behind a pimpl so no header leaks asio; big-core count
via cpufreq at >=85% of peak clamped to [1,4]; lazily constructed, so with
the flag off no worker thread ever exists; StopAndDrain leads DestroyImpl).
MOBILEGL_ASYNC_SHADER_COMPILE / _THREADS config knobs, default OFF. Nothing
in the GL pipeline references the pool yet - grep-verified; the full
DirectGLES retrace and compile benches are byte- and time-identical. 25
threaded unit tests, clean across 20x gtest_repeat.
Pulls the glslang change that downgrades the 'defined in macro
expansion' diagnostic to a portability warning with normal evaluation.
KHR-GL33.shaders.preprocessor.conditional_inclusion.basic_2_* pass; the
whole preprocessor family (482 cases, including every negative
invalid_defined_* case) stays green.
Moves snapshot capture entirely into the apitrace retrace layer (glReadPixels + PNG encode). Drops the MOBILEGL_PRESENT_DUMP_PATH / MOBILEGL_PRESENT_STATS / MOBILEGL_PRESENT_DUMP_CALL / MOBILEGL_PRESENT_CURRENT_CALL / MOBILEGL_TRACE_CURRENT_CALL_OVERRIDE plumbing from Config, ConfigLoader, VulkanRenderer (GetPresentedDumpPixel/WritePresentedDumpPpm + present-stats readback), the EGL/GLX/Android ws shims, and the Android trace_replay_core PPM reader.
DirectVulkan ReadPixels on the default framebuffer now remaps raw swapchain pixels (top-left origin, preTransform-rotated) to GL orientation (bottom-left origin) so the retrace snapshot matches the golden; SwapchainObject also resizes the default-FBO stencil attachment to the swapchain extent to fix GL_INVALID_FRAMEBUFFER_OPERATION under the glReadPixels completeness check.