mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Docs] (Anland): the D1100 + Mali changes and why each one was needed
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
# 为了在天玑 1100 + Mali(内核 4.14)上跑起来,改了什么、为什么
|
||||
|
||||
> 本文只记**改动与动机**。参考机(Lenovo Y700 / Adreno 750 / 内核 6.1 / KernelSU / 有 systemd 的
|
||||
> Arch 容器)的完整操作手册见 [`runbook-plasma.md`](runbook-plasma.md);本文的改动都在分支
|
||||
> `feat/disaggregated-fix-d1100-mali` 上,两个在 MobileGL 里(本仓库),两个在 anland 的
|
||||
> consumer app 里。
|
||||
>
|
||||
> 判据:改之前 `screencap` 是 37 KB 的纯黑;改之后是 1.4 MB 的完整 Plasma 桌面
|
||||
> (壁纸 + 面板 + 时钟),client 日志的验收项从 `presented through wl_shm` 变成
|
||||
> `presented through linux-dmabuf shared images`。
|
||||
|
||||
## 这台机器与参考机的差异(每条改动都从这里来)
|
||||
|
||||
| 项 | 参考机 | 本机 |
|
||||
|---|---|---|
|
||||
| GPU / 驱动 | Adreno 750 | **Mali**(`/dev/mali0`) |
|
||||
| 内核 | 6.1 | **4.14.186**(cgroup v1) |
|
||||
| 容器 | Arch + **systemd** | Fedora 44,**无 systemd**(`custom_init=ds-init.sh`) |
|
||||
| 容器里的编译器 | 有 | **没有**,且无 DNS → 全部主机交叉编译 |
|
||||
| `/dev/dri` | 有 `renderD*` | 只有 `card0` |
|
||||
|
||||
---
|
||||
|
||||
# MobileGL 仓库(本分支)
|
||||
|
||||
## 改动 1:dma-buf 身份认不出来时,用导入自己的 extent + format 认领
|
||||
|
||||
**文件**:`MobileGL/MG_Remote/Server/SharedImageRegistry.{h,cpp}`、`MobileGL/MG_Remote/Server/PipeApplier.cpp`
|
||||
|
||||
**改了什么**:`Identify(int fd, …)` 增加 `width/height/fourcc` 三个参数(导入记录本来就有它们)。
|
||||
内核身份 `(st_dev, st_ino)` 仍然优先;只有当注册表已经发现身份**不唯一**时,才退化为:在该身份
|
||||
下已导出的活镜像里,挑 **extent 与 fourcc 都相同、且尚未被认领** 的那个,按 `Id` 从小到大
|
||||
(= 分配顺序 = 生产者交给合成器的顺序),认领一次。
|
||||
|
||||
**为什么必须改**:零拷贝的整条链是"server 分配 AHardwareBuffer → 导出 dma-buf fd → client 把它做成
|
||||
`wl_buffer` → 合成器 `eglCreateImageKHR` 导回 → server 认出是自己那块"。认的依据只有
|
||||
`(st_dev, st_ino)`。本机内核给**所有** dma-buf descriptor 发同一个身份(实测三个不同的 buffer):
|
||||
|
||||
```
|
||||
bo0: fd=15 dev=12 ino=10658 size=0 fdinfo[pos: 0 flags: 02000000 mnt_id: 12 ]
|
||||
bo1: fd=17 dev=12 ino=10658 size=0 …
|
||||
bo2: fd=19 dev=12 ino=10658 size=0 …
|
||||
```
|
||||
|
||||
`fdinfo` 里没有 name、没有别的唯一量——用户态拿不到任何能区分 buffer 的东西。注册表检测到
|
||||
"两块活镜像同一个身份"后**按设计 fail-closed**:
|
||||
|
||||
```
|
||||
[ERROR] two live shared images have one dma-buf identity (dev 12 ino 10658); this kernel does not
|
||||
keep dma-buf inodes unique …
|
||||
[WARN] a dma-buf import was refused: dma-buf identities are not unique on this kernel
|
||||
```
|
||||
|
||||
于是**每一个** linux-dmabuf 窗口都被拒:client 全退回 `wl_shm`(`8 presented through wl_shm`),
|
||||
合成器也没法采样它上不了屏的东西。fail-closed 本身是对的(猜错会把别人的像素当自己的),
|
||||
缺的只是**内核给不出身份时还有别的可用依据**——导入声明的尺寸和格式,加上 server 自己的分配顺序。
|
||||
|
||||
**验证**:自包含探针 `eglprobe4.c`(主机 clang+lld 编,容器里以 Gold 跑)——`gbm_bo_create`
|
||||
取一块 server shared image 的 fd,再走合成器的导入路径:修前
|
||||
`eglCreateImageKHR(EGL_LINUX_DMA_BUF_EXT) -> (nil)`,修后 `-> 0x1`;会话里
|
||||
refusal 归零、client 日志变成 `presented through linux-dmabuf shared images`。
|
||||
|
||||
## 改动 2:damage 变体被驱动拒绝时,回落普通 `eglSwapBuffers`
|
||||
|
||||
**文件**:`MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp` 的 `Present()`
|
||||
|
||||
**改了什么**:`eglSwapBuffersWithDamageEXT` 返回 EGL_FALSE 时,用 `eglSwapBuffers` 再试一次,
|
||||
并 `MGLOG_W_ONCE` 说明一次(没有该扩展的驱动照旧走普通入口)。
|
||||
|
||||
**为什么必须改**:server 的 `Present()` 原本优先用 WithDamage 变体(注释说"驱动提供哪个拼写就用
|
||||
哪个")。本机的 Mali/4.14 vendor EGL **暴露了这个入口,却对窗口面返回 EGL_FALSE 且不设 EGL 错误**:
|
||||
|
||||
```
|
||||
server window: 1080x2194 fmt=0x1 (pointer=0xb4000070d902ad00) ← ANativeWindow 是活的、尺寸对
|
||||
swap entry points: withDamage=0x71a0887040 plain=0x71a087c62c
|
||||
withDamage → swap=0 err=0x3000 ← 同一块 surface、同一线程
|
||||
plain → swap=1 err=0x3000
|
||||
```
|
||||
|
||||
排除了绑定问题(`session.Draw == eglGetCurrentSurface(EGL_DRAW)`、context 也 current),也不是窗口
|
||||
问题(`ANativeWindow_getWidth/Height/Format` 都正常)——就是驱动拒。信任那个指针的后果是
|
||||
**一帧都不入队**:SurfaceView 的 BLAST 层 `frame events` 全 0、`geomLayerBounds` 0×0,屏幕上只有
|
||||
`Background for SurfaceView` 那块纯黑占位;合成器又能采样但因为上不了屏,client 也跟着退回
|
||||
`wl_shm`。这条是"屏幕全黑"的最后一环。
|
||||
|
||||
**验证**:修后 `frame events` 出现真实时间戳,`screencap` 从 37 KB 变 1.4 MB 的完整桌面。
|
||||
|
||||
---
|
||||
|
||||
# anland 仓库(consumer app)
|
||||
|
||||
这两条不在本仓库里,但缺任何一条桌面都上不了屏。
|
||||
|
||||
## 改动 3:`:mobilegl` worker 设置 `MOBILEGL_IPC_SURFACE=server`
|
||||
|
||||
**文件**:`consumers/anland_v5/android_consumer/app/src/main/java/com/anland/consumer/MobileGLWorker.java`
|
||||
|
||||
**改了什么**:在 `Os.setenv("MOBILEGL_IPC_ROLE", "server", …)` 旁边加
|
||||
`Os.setenv("MOBILEGL_IPC_SURFACE", "server", true)`。
|
||||
|
||||
**为什么必须改**:`Config.h` 里 `IpcTable::Surface` 的默认值是 `IpcSurface::Offscreen`。
|
||||
client 侧(容器里的 `mobilegl-startup.sh`/`start-mobilegl-session.sh`)按 `server` 去要
|
||||
server 的窗口,而 **server 自己的进程没有任何 `MOBILEGL_IPC_SURFACE`**,于是它把 app 递过来的
|
||||
窗口 attach 了、却**从不创建 server-owned 窗口面、也从不往上面 swap**。日志上表现为只有一句
|
||||
`a ServerOwned window surface is served on its window`,没有真正的
|
||||
`surface=window … owner=server`。补上之后这一行立刻出现。
|
||||
|
||||
## 改动 4:几何回调不再把 Surface 塌成 0×0
|
||||
|
||||
**文件**:`…/MainActivity.java`(`MobileGLConnection` 的几何回调)
|
||||
|
||||
**改了什么**:回调收到 `(0,0)`("不指定尺寸")时,只有在视图**确实已有尺寸**时才
|
||||
`holder.setSizeFromLayout()`;否则什么都不做,保留现有 surface。
|
||||
|
||||
**为什么必须改**:这个回调可能在视图第一次布局之前被调用,此时 `setSizeFromLayout()` 会把
|
||||
`SurfaceHolder` 定成 0×0;0×0 的 surface 上任何生产者都无法 queue,之后每一帧
|
||||
`eglSwapBuffers` 都会失败——正是"BLAST 层 `geomLayerBounds` 0×0 且永远没有 buffer"的成因。
|
||||
|
||||
---
|
||||
|
||||
# 环境侧(不是代码,但缺了就起不来)
|
||||
|
||||
1. **`libatomic.so.1`**:主机交叉编出来的 KWin 需要它,而这个 Fedora 运行时镜像没有
|
||||
(`kwin_wayland: error while loading shared libraries: libatomic.so.1`)。从 sysroot 把
|
||||
`libatomic.so.1.2.0` + 软链补进 rootfs(容器停着时直接写
|
||||
`/data/local/Droidspaces/fedora-kde/usr/lib64/`)。`ldd` 其余 Qt6/KF6 依赖都齐。
|
||||
2. **无 systemd 的会话**:容器里 systemd 259 因"内核 4.14 + cgroup v1"直接拒绝启动,会话由
|
||||
`ds-init.sh` 自己拉起。等价物是把 `mobilegl-startup.sh plasma` 的那套 env 写进
|
||||
`/opt/mobilegl/bin/start-mobilegl-session.sh`(PATH 前置 `/opt/mobilegl/kwin/bin` 让
|
||||
`kwin_wayland_wrapper` 起我们的 KWin),再让 `ds-init.sh` 的最后一句 exec 它。**同时必须去掉
|
||||
`LIBGL_ALWAYS_SOFTWARE=1`/`GALLIUM_DRIVER=llvmpipe`**:MobileGL 对"要求软件渲染的进程"主动
|
||||
让位,留着它整个会话就还是 llvmpipe。
|
||||
3. **GBM 后端的路径**:Fedora 的 loader 搜 `/usr/lib64/gbm`(上游脚本写的是 Arch 的
|
||||
`/usr/lib/gbm`);`libGLX_mobilegl.so.0` 同理放 `/usr/lib64`。
|
||||
4. **`/dev/dri` 只有 `card0`**:`MOBILEGL_GBM_NODE` 退到 `/dev/null` —— 那个节点只当身份、
|
||||
后端从不对它 ioctl,这是 `mobilegl-startup.sh` 自己的回退路径,不需要改设备节点权限。
|
||||
5. **KWin 的构建**:pristine `kwin-6.7.5` + `Arch_v5/kwin.patch` + `anland_backend_Arch_v5` +
|
||||
顶层 `libdisplay_producer/`(后者的 `protocol.h`/`socket_utils.c` 是指向 `common/` 的符号链接,
|
||||
**拷贝时要 -L 解引用**;也**不要**把 `common/` 整个拷进 backend 目录,会让 `kde_clang_format`
|
||||
生成重名 target)。6.7.5 上只有 `src/opengl/eglcontext.cpp` 的 Hunk #2 打不上,按补丁原意手工把
|
||||
no-arg `makeCurrent()` 里的 `EGL_NO_SURFACE, EGL_NO_SURFACE` 换成
|
||||
`m_display->defaultSurface()`。
|
||||
|
||||
---
|
||||
|
||||
# 已知但未处理
|
||||
|
||||
- daemon 的 producer/consumer 每 ~5 s 抖一次(`producer connected/disconnected`、
|
||||
`consumer re-deposited 5 fds`,kwin 侧 `consumer disconnected, entering fallback`)。MobileGL
|
||||
模式下合成不受影响(窗口与默认 framebuffer 属于 KWin),桌面照常上屏,成因未查。
|
||||
- 桌面静止时两次 `screencap` 的 md5 相同(时钟只到分钟、无动画);判断"活着"要看 server 的
|
||||
`P65ServerFrame` 计数或 SurfaceView 的 frame events。
|
||||
- **Magma(DirectVulkan)未复验**。上面三条代码改动都与后端无关,两个后端都会撞到。
|
||||
@@ -1,185 +0,0 @@
|
||||
# Runbook:D1100 + Mali、内核 4.14 的设备上起 MobileGL + anland + KDE Plasma(2026-10-03)
|
||||
|
||||
> 第二台设备的实测记录。参考机(Lenovo Y700 / Adreno 750 / 内核 6.1 / KernelSU)见
|
||||
> [`runbook-plasma.md`](runbook-plasma.md);本文只写**与它不同的地方**、以及那台机器上不会
|
||||
> 遇到的坑。台面上的三个修复随分支 `feat/disaggregated-fix-d1100-mali` 提交:两个在 MobileGL
|
||||
> 里(本仓库),两个在 anland 的 consumer app 里。
|
||||
|
||||
## 设备与容器(与参考机的全部差异)
|
||||
|
||||
| 项 | 参考机 | 本机 |
|
||||
|---|---|---|
|
||||
| SoC / GPU | 骁龙 8 Gen 3 / **Adreno 750** | 天玑 1100 / **Mali**(droidspaces 镜像 `/dev/mali0`) |
|
||||
| 内核 | 6.1 | **4.14.186**(+ cgroup v1) |
|
||||
| root | KernelSU | **Magisk**(`su -c` 可用;`/data/adb/magisk`) |
|
||||
| 系统 | Android 15 | **TrebleDroid GSI, Android 14 (SDK 34)** |
|
||||
| adb | USB `HA27Q3LQ` | USB `aikjs4s8cys8ba7l` |
|
||||
| 容器 | `arch-kde-mgl`(Arch,**systemd**) | `fedora-kde`(Fedora 44 Container Image,**无 systemd**) |
|
||||
| 容器 init | `desktop-session.service` | `custom_init=/usr/local/sbin/ds-init.sh`(`exec setpriv … dbus-run-session -- startplasma-wayland`) |
|
||||
| 桌面用户 | `swung0x48` | `Gold`(uid 1000) |
|
||||
| 容器里的编译器 | 有(gcc/cmake/ninja) | **没有**(运行时镜像,且容器无 DNS) |
|
||||
| `/dev/dri` | 有 renderD\* | **只有 `card0`(600 root:root)** |
|
||||
| 容器截图/构建 | 容器内构建 client 与 KWin | **全部在主机(PC)交叉编译**,只把产物送进容器 |
|
||||
|
||||
容器里 systemd 起不来的原因很直接(`/data/local/Droidspaces/Logs/fedora-kde/console`):
|
||||
|
||||
```
|
||||
systemd 259.9-1.fc44 … Warning! Reported kernel version 4.14.186 is older than systemd's required
|
||||
baseline kernel version 5.7.
|
||||
Detected cgroup v1 hierarchy at /sys/fs/cgroup/, which is no longer supported…
|
||||
[!!!!!!] Detected unsupported legacy cgroup hierarchy, refusing execution.
|
||||
```
|
||||
|
||||
所以本机**没有** `desktop-session.service`/`plasma-kwin_wayland.service` 这条链路,
|
||||
`mobilegl-startup.sh plasma` 里那几行 `systemctl --user` 也没有意义。等价物见下文"会话"。
|
||||
|
||||
## 一次性准备
|
||||
|
||||
1. **容器 bind**:`container.config` 的 `bind_mounts` 要有两条——
|
||||
`/data/local/tmp/display_daemon.sock:/run/display.sock` 与
|
||||
`/data/local/tmp/anland-mobilegl:/run/anland-mobilegl`(后者镜像里默认没有,缺了客户端就看不到
|
||||
daemon socket)。`net_mode=host` 必须有(`@anland-mobilegl` 是抽象 socket)。
|
||||
Android 侧 `mkdir -p /data/local/tmp/anland-mobilegl && chmod 777`。
|
||||
2. **client 库**(主机交叉编译):容器运行时是 glibc 2.43 / GLIBCXX 3.4.36,和 Fedora 44 aarch64
|
||||
sysroot 一致,所以用 `scripts/xsysroot/aarch64-arch.cmake` 的等价物(clang + lld +
|
||||
`--gcc-install-dir=<sysroot>/usr/lib/gcc/aarch64-redhat-linux/16`)编
|
||||
`libMobileGL.so` + `mobilegl_gbm.so`,参数与 `xbuild.sh` 相同。**注意 64 位发行版的路径**:
|
||||
`/usr/lib64/gbm/mobilegl_gbm.so`、`/usr/lib64/libGLX_mobilegl.so.0`(`xdeploy.sh` 写的是 Arch 的
|
||||
`/usr/lib`,两条都放最省事)。
|
||||
3. **KWin**:pristine `kwin-6.7.5`(`download.kde.org/stable/plasma/6.7.5/kwin-6.7.5.tar.xz`)
|
||||
+ `producers/kde/Arch_v5/kwin.patch` + `anland_backend_Arch_v5` + 顶层 `libdisplay_producer/`
|
||||
(后者里的 `protocol.h`/`socket_utils.c` 是指向 `common/` 的符号链接,**拷的时候要 -L 解引用**,
|
||||
否则 configure 报 "Cannot find source file … socket_utils.c";也**不要**把 `common/` 整个拷进
|
||||
backend 目录,那会让 `kde_clang_format` 生成重名的 clang-format target 而 configure 失败)。
|
||||
7.7.5 的树上 `kwin.patch` 只有 `src/opengl/eglcontext.cpp` 的 Hunk #2 打不上(6.7.5 里
|
||||
`makeCurrent()` 的上下文不同),按补丁原意手工改:no-arg `makeCurrent()` 里把
|
||||
`EGL_NO_SURFACE, EGL_NO_SURFACE` 换成 `m_display->defaultSurface()`。
|
||||
装到 `/opt/mobilegl/kwin/{bin,lib}`,screencast 插件就地替换
|
||||
`/usr/lib64/qt6/plugins/kwin/plugins/screencast.so`(留 `.orig`)。
|
||||
4. **容器缺的运行时库**:交叉编出来的 KWin 需要 `libatomic.so.1`,这个运行时镜像没有。
|
||||
从 sysroot 把 `libatomic.so.1.2.0` + 软链补进 rootfs(容器停着时直接写
|
||||
`/data/local/Droidspaces/fedora-kde/usr/lib64/` 最方便)。`ldd` 其余依赖 Qt6/KF6 都齐。
|
||||
|
||||
## 会话(无 systemd 的等价物)
|
||||
|
||||
镜像原来的 `ds-init.sh` 用 **llvmpipe 软件渲染**起 Plasma,且 export 了
|
||||
`LIBGL_ALWAYS_SOFTWARE=1` —— MobileGL 对"要求软件渲染的进程"主动让位,所以那一行必须去掉。
|
||||
把这个脚本装到容器 `/opt/mobilegl/bin/start-mobilegl-session.sh`:
|
||||
|
||||
```sh
|
||||
# 复刻 mobilegl-startup.sh plasma 的 env(KWin 用 server,其余 client 用 offscreen),
|
||||
# 然后 exec startplasma-wayland —— PATH 前置 /opt/mobilegl/kwin/bin,
|
||||
# kwin_wayland_wrapper 就会 exec 我们的 KWin。
|
||||
export KWIN_BIN_DIR=/opt/mobilegl/kwin/bin KWIN_LIB_DIR=/opt/mobilegl/kwin/lib
|
||||
export __EGL_VENDOR_LIBRARY_FILENAMES=/opt/mobilegl/share/glvnd/egl_vendor.d/50_mobilegl.json
|
||||
export __GLX_VENDOR_LIBRARY_NAME=mobilegl GBM_BACKEND=mobilegl ANLAND_MOBILEGL=1
|
||||
export ANLAND_SOCKET=/run/anland-mobilegl/display.sock
|
||||
export MOBILEGL_TRANSPORT=spawn MOBILEGL_IPC_DATA=shm MOBILEGL_IPC_CONTROL=unix:@anland-mobilegl
|
||||
export MOBILEGL_IPC_SURFACE=server MOBILEGL_BACKEND_TYPE=$(cat /etc/mobilegl/backend)
|
||||
export MOBILEGL_GBM_NODE=/dev/null MOBILEGL_DEVICE_DRM_NODE=/dev/null
|
||||
export KWIN_DISABLE_VULKAN=1 KWIN_NO_TIMER_QUERY=1 KWIN_PERSISTENT_VBO=0 KWIN_DISABLE_UDMABUF_IMPORT=1
|
||||
export PATH="$KWIN_BIN_DIR:$PATH" LD_LIBRARY_PATH="$KWIN_LIB_DIR"
|
||||
unset LIBGL_ALWAYS_SOFTWARE GALLIUM_DRIVER MESA_LOADER_DRIVER_OVERRIDE
|
||||
exec /usr/bin/startplasma-wayland
|
||||
```
|
||||
|
||||
`/dev/dri` 里没有 `renderD*` 时 `MOBILEGL_GBM_NODE` 取 `/dev/null`:那个节点只是身份,
|
||||
后端从不对它 ioctl(`mobilegl-startup.sh` 自己也是这么退的),不需要改设备节点权限。
|
||||
|
||||
`ds-init.sh` 最后的 `exec … startplasma-wayland` 换成 `dbus-run-session -- /opt/mobilegl/bin/start-mobilegl-session.sh`,
|
||||
并去掉 `LIBGL_ALWAYS_SOFTWARE`/`GALLIUM_DRIVER`。**会话在容器启动时就起**,所以 bring-up 顺序是
|
||||
**app → display daemon → 容器重启**(不是 runbook 里那条 systemd 顺序)。
|
||||
|
||||
## 本机独有的三个坑(都已修,随分支提交)
|
||||
|
||||
### 1. 内核不保证 dma-buf inode 唯一 → 零拷贝被整体拒绝
|
||||
|
||||
参考机靠 `(st_dev, st_ino)` 认"这块 dma-buf 是不是 server 自己发的"。本机**所有** dma-buf
|
||||
descriptor 报同一个身份:
|
||||
|
||||
```
|
||||
bo0: fd=15 dev=12 ino=10658 size=0 fdinfo[pos: 0 flags: 02000000 mnt_id: 12 ]
|
||||
bo1: fd=17 dev=12 ino=10658 size=0 …
|
||||
bo2: fd=19 dev=12 ino=10658 size=0 …
|
||||
```
|
||||
|
||||
`/proc/self/fdinfo` 里也没有 name / 任何唯一量,也就是用户态**拿不到**能区分 buffer 的东西。
|
||||
`SharedImageRegistry` 正确地检测到冲突并按设计 fail-closed:
|
||||
|
||||
```
|
||||
[ERROR] two live shared images have one dma-buf identity (dev 12 ino 10658); this kernel does not
|
||||
keep dma-buf inodes unique …
|
||||
[WARN] a dma-buf import was refused: dma-buf identities are not unique on this kernel
|
||||
```
|
||||
|
||||
后果是**所有** linux-dmabuf 窗口都被拒,client 全部退回 `wl_shm`(`8 presented through wl_shm`),
|
||||
合成器也就没法采样它上不了屏的东西。
|
||||
|
||||
**修复**(`feat/disaggregated-fix-d1100-mali` 的第一个提交):身份仍然优先由内核给;不唯一时按
|
||||
**导入记录自己带的 extent + fourcc**,在该身份下已导出的活镜像里取"最早且未被认领"的那个
|
||||
(分配顺序 = 生产者交给合成器的顺序)。`Identify()` 多收 `width/height/fourcc` 三个参数,
|
||||
`PipeApplier` 的导入分支本来就有它们。
|
||||
|
||||
修好后 client 日志变成验收项要的那句,且 refusal 归零:
|
||||
|
||||
```
|
||||
8 presented through linux-dmabuf shared images
|
||||
```
|
||||
|
||||
自包含复现(主机用 clang+lld 编,容器里以 Gold 跑):`eglprobe4.c`——`gbm_bo_create` 拿一块
|
||||
server shared image 的 dma-buf fd,再走 KWin 的导入路径 `eglCreateImageKHR(EGL_LINUX_DMA_BUF_EXT)`。
|
||||
修前 `-> (nil)`,修后 `-> 0x1`。
|
||||
|
||||
### 2. 驱动暴露 `eglSwapBuffersWithDamageEXT` 却对它返回 EGL_FALSE
|
||||
|
||||
这条是"屏幕全黑"的最后一环。server 的 `Present()` 在两个入口里优先用 WithDamage 变体;
|
||||
本机驱动(Mali / 4.14 vendor EGL)对**窗口面**返回 EGL_FALSE 且**不设 EGL 错误**:
|
||||
|
||||
```
|
||||
server window: 1080x2194 fmt=0x1 (pointer=0xb4000070d902ad00) ← ANativeWindow 是活的
|
||||
swap entry points: withDamage=0x71a0887040 plain=0x71a087c62c
|
||||
withDamage → swap=0 err=0x3000 ; plain → swap=1 err=0x3000 ← 同一块 surface、同一个线程
|
||||
```
|
||||
|
||||
surface 在当前线程上是 current、context 也是 current、窗口尺寸格式都对,所以不是绑定问题——
|
||||
就是驱动拒绝。信任那个指针等于**一帧都不入队**:SurfaceView 的 BLAST 层 `frame events` 全 0、
|
||||
`geomLayerBounds` 0×0,屏幕上只有 `Background for SurfaceView` 那块纯黑占位。
|
||||
|
||||
**修复**(第二个提交):damage 变体返回 EGL_FALSE 时回落普通 `eglSwapBuffers`,并
|
||||
`MGLOG_W_ONCE` 说明一次。修好后 `frame events` 出现真实时间戳,`screencap` 从 37 KB(纯黑)
|
||||
变成 1.4 MB 的完整桌面。
|
||||
|
||||
### 3. app 侧两处(在 anland 仓库,不在本仓库)
|
||||
|
||||
- **`:mobilegl` worker 从没设 `MOBILEGL_IPC_SURFACE=server`**。`IpcTable::Surface` 的默认是
|
||||
`Offscreen`,而 client 侧(会话脚本)按 `server` 去要 server 的窗口,于是 server **把窗口
|
||||
attach 了却从不创建 server-owned 窗口面**——日志里只有
|
||||
`a ServerOwned window surface is served on its window`,没有真正的
|
||||
`surface=window … owner=server`。在 `MobileGLWorker.java` 的 `MOBILEGL_IPC_ROLE` 旁边加一行
|
||||
`Os.setenv("MOBILEGL_IPC_SURFACE", "server", true)` 即可。
|
||||
- **`MobileGLConnection` 的几何回调**在收到 (0,0) 时会 `setSizeFromLayout()`;若此时视图还没
|
||||
第一次布局,surface 会被定成 **0×0**,之后任何生产者都无法 queue。改成"视图确实有尺寸时才
|
||||
回到布局"。
|
||||
|
||||
## 验收(本机实测结论)
|
||||
|
||||
- 会话:`kwin_wayland`(`/proc/<pid>/exe -> /opt/mobilegl/kwin/bin/kwin_wayland`)+ `plasmashell`
|
||||
常驻;client 日志 `Renderer Name: Espryt`、`CapsMirror generation N adopted`、
|
||||
`P65ClientPace present=N`;server 日志 `P65ServerFrame frame=N`(空闲桌面约 1 帧/分钟,
|
||||
只在有 damage 时合成)。
|
||||
- 上屏:`screencap` 得到 1080×2400 的完整 Plasma 桌面(壁纸 + 面板 + 时钟),不再是纯黑。
|
||||
SurfaceView 的 BLAST 层有真实 `frame events`。
|
||||
- 验收项 `presented through linux-dmabuf shared images` **达成**(8/8,0 refusal)。
|
||||
|
||||
## 仍未解决 / 未验证
|
||||
|
||||
- **daemon 的 producer/consumer 每 ~5 s 抖一次**(`daemon: producer connected/disconnected`、
|
||||
`consumer re-deposited 5 fds`,kwin 侧 `kwin_backend_anland: consumer disconnected, entering
|
||||
fallback`)。在 MobileGL 模式下合成不受影响(窗口和默认 framebuffer 属于 KWin),所以桌面
|
||||
照常上屏,但这条抖动本身的成因没查。
|
||||
- 桌面静止时两次截图 md5 相同(时钟只到分钟、无动画),要证明"活着"看 server 的 frame 计数
|
||||
或 `testImportBuffer`;参考机的 `shot.sh` 两帧哈希法在这台机器上需要先制造 damage。
|
||||
- **Magma(DirectVulkan)未复验**:`setprop debug.mobilegl.backend DirectVulkan` +
|
||||
`/etc/mobilegl/backend=DirectVulkan` 后重启 app 与容器即可。上面三个坑与后端无关,
|
||||
两个后端都会撞到(都已在 DirectGLES 上验证过修复路径)。
|
||||
- 容器无 DNS、无编译器,所以"容器内构建"这条上游路线在本机不适用;本机全部交叉编译。
|
||||
Reference in New Issue
Block a user