termux-packages icon indicating copy to clipboard operation
termux-packages copied to clipboard

[Feature]: using proprietary EGL/GLES/vulkan drivers with X11/vulkan

Open twaik opened this issue 1 year ago • 14 comments

Shortly: I want to use some low-level interface normally not allowed to be used by non-vendor android apps, but wine used it before android devs broke some other low-level stuff so I believe it will work.

Long:

I am aware about xMeM projects (vulkan-wsi-layer, mesa-vulkan-icd-wrapper) and tareksander's termux-gfx-wrapper, they implement vulkan and EGL in the right way (which will work even on Treble-incompatible devices), but implementing all needed features will take a lot of time and effort.

This idea is a bit wider because it will work with both EGL/GLES{1,2,3} and vulkan and will take less code and effort for implementation since it will use Android's native mechanisms created for working with native windows, and will use all vendor's optimisations and other stuff. Also it will let us use ffmpeg, mpv (and probably chromium and firefox too, not so sure about it because of their complexity) and other packages working with MediaCodec API so we will have fully accelerated programs. Also it may allow us using Wayland compositors requiring EGL/GLES (wlroots, kwin, others) and Xorg with glamor since we will have correct EGL implementation.

We can go libhybris and wine (see wineandroid.drv code) way and write our own ANativeWindow implementation. I am aware it is kinda non-public (non-SDK?) API and it can be broken on a wide range of devices, but partial support is much better than no support at all, right? Also UBPorts/Sailfish dev said me that after introducing Treble feature most vendors stopped touching basic system headers and most ROMs (at least Treble-compatible) will support our implementation.

The idea is pretty much simple. We can copy code from cs.android.com with ANativeWindow definition to some header in package and implement a GLVND backend working with it. We can install it by default with libglvnd, run some test in postint script and disable our backend in the case if vendor changed ANativeWindow definition in the ROM (in this case the test program will fail with segfault or similar error), so it will fall back to llvmpipe/lavapipe.

I implemented a small demo for using with Termux:X11. I tested it only on Samsung S20FE (SM-G780F/DSM) with Android 13, but it should work on other devices too (not so sure about it, must be checked). It is a Bash+C polyglot script, run it like chmod +x demo.c; ./demo.c, no configuration needed. demo.zip

old

demo.zip

I posted a demo only as a proof of concept, it is not considered to work on a wide range of devices. It contains libhybris's GLESv2 test, android system headers and some sources and self-contained GLVND backend (see // EGL implementation, the most interesting part is here line). The code is fast and dirty, with some debug lines (did not clean them up, sorry) and contain some hacks to make GLVND force open GLVND backend it (demo) implements. Again, it is only a demo and proof of concept.

Will be happy to discuss it. No bug reports related to the demo please. Again, it is not considered to work on wide range of devices, I am planning to test (and fix) it on AVDs of Android 8+ later.

twaik avatar Nov 16 '24 21:11 twaik

I have no idea what most of that means. But I'm all for a lower-effort way to get "native" windowing working on Termux.

The important thing here I think is that this will let us get things going while "proper" implementations like those you mentioned at the beginning continue to develop.

TomJo2000 avatar Nov 16 '24 22:11 TomJo2000

It is a Bash+C polyglot script, run it like chmod +x demo.c; ./demo.c, no configuration needed.

ld.lld: error: undefined symbol: AHardwareBuffer_allocate ?

Biswa96 avatar Nov 17 '24 06:11 Biswa96

ld.lld: error: undefined symbol: AHardwareBuffer_allocate ?

It is weird, I can not reproduce it locally.

twaik avatar Nov 17 '24 07:11 twaik

ld.lld: error: undefined symbol: AHardwareBuffer_allocate ?

Try -lnativewindow.

licy183 avatar Nov 17 '24 07:11 licy183

May work on device, but it is not a NDK library.

twaik avatar Nov 17 '24 07:11 twaik

Try -lnativewindow.

Thanks, it worked.

$ ./demo.c
found AHardwareBuffer_to_ANativeWindowBuffer, returned 16
termuxEGL_GetPlatformDisplay: platform 0x31D5 nativeDisplay 0xb40000797d817010 attrib_list 0x0
eglChooseConfig returned 1 configs
termuxEGL_CreateWindowSurface invoked
New context 0xb4000077fd81c4f0
OpenGL ES 3.2 [email protected] (GIT@03dd3ba, I13854cb805, 1603903465) (Date:10/28/20)
frame:0
frame:60

I see some glitches in the spiral demo window in termux-x11.

Biswa96 avatar Nov 17 '24 08:11 Biswa96

@twaik How about implementing OpenGL & OpenGL ES using Google ANGLE combined with mesa-vulkan-icd-wrapper in a wihtout virgl? This approach is expected to deliver much stronger performance and compatibility compared to the existing angle-android + virglrenderer-android method.

Since mesa zink does not guarantee compatibility with most GPUs' official Vulkan drivers, this could serve as an excellent alternative.

https://github.com/xMeM/vulkan-wsi-layer/issues/35

hansm629 avatar Nov 17 '24 10:11 hansm629

@hansm629 please, stay on topic. virglrenderer, mesa, mesa-vulkan-icd-wrapper are out of scope of this issue. Also virglrenderer-android currently not able to connect X server, virgl backend does not share pixmap id or something. The feature you ask for will require both virgl and virglrenderer.

twaik avatar Nov 17 '24 10:11 twaik

I see some glitches in the spiral demo window in termux-x11.

It is weird, I forced waiting for buffer to be blitted until the code continues execution. But the most important thing (rendering to AHardwareBuffer and output to X server) works.

twaik avatar Nov 17 '24 11:11 twaik

Suggested Change?

--- a/demo.c
+++ b/demo.c
@@ -1,6 +1,9 @@
 #if 0
 # This file is a Bash+C script. Just run it as `chmod +x ./cscript; ./cscript`
-pkg i libglvnd libglvnd-dev xorgproto libx11 libxcb
+pkg i x11-repo
+pkg i libglvnd libglvnd-dev xorgproto libx11 libxcb termux-x11-nightly build-essential
+termux-x11 &
+sleep 5
 clang "$(realpath "$0")" --target=aarch64-linux-android26 -landroid -lxcb -lxcb-dri3 -lxcb-present -lX11 -lX11-xcb -lGLESv2 -lEGL -lm -ggdb -Wl,-E -fPIC -pie -o "${TMPDIR:-/tmp}/$(basename "$0")" && \
        exec "${TMPDIR:-/tmp}/$(basename "$0")" || exit 1
 #endif

demo.c.txt

curl -L https://github.com/user-attachments/files/17791486/demo.c.txt -o demo.c
chmod +x demo.c
./demo.c

robertkirkman avatar Nov 17 '24 16:11 robertkirkman

Samsung Galaxy A70 SM-A705FN

SM-A70QFN-twaikdemo.webm

demo log
~ $ ./demo.c 
No mirror or mirror group selected. You might want to select one by running 'termux-change-repo'
Checking availability of current mirror:
[*] https://mirrors.aliyun.com/termux/termux-main: ok
Hit:2 https://nohajc.github.io termux InRelease
Hit:1 https://turdl.kcubeterm.com tur-packages InRelease                     
Hit:3 https://mirrors.aliyun.com/termux/termux-main stable InRelease         
Hit:4 https://mirrors.aliyun.com/termux/termux-x11 x11 InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
4 packages can be upgraded. Run 'apt list --upgradable' to see them.
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
x11-repo is already the newest version (8.4-1).
0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.
No mirror or mirror group selected. You might want to select one by running 'termux-change-repo'
Checking availability of current mirror:
[*] https://mirrors.aliyun.com/termux/termux-main: ok
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
libglvnd is already the newest version (1.7.0).
libglvnd-dev is already the newest version (1.7.0).
xorgproto is already the newest version (2024.1).
libx11 is already the newest version (1.8.10).
libxcb is already the newest version (1.17.0).
termux-x11-nightly is already the newest version (1.03.01).
0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.
found AHardwareBuffer_to_ANativeWindowBuffer, returned 16
termuxEGL_GetPlatformDisplay: platform 0x31D5 nativeDisplay 0xb40000781eed27b0 attrib_list 0x0
eglChooseConfig returned 1 configs
termuxEGL_CreateWindowSurface invoked
New context 0xb40000771eedff80
OpenGL ES 3.2 [email protected] (GIT@5fa70b0888, I2c4b6824f1, 1632903783) (Date:09/29/21)
frame:0
frame:60
frame:120
frame:180
frame:240
frame:300
frame:360
frame:420
^C
~ $ 
termux-info log
Termux Variables:
TERMUX_APP_PACKAGE_MANAGER=apt
TERMUX_APP__APK_FILE=/data/app/~~gVwKanLEt3onhDQBKcUZQA==/com.termux-Jepd-I809CuxEnnuONZ6_Q==/base.apk
TERMUX_APP__APK_RELEASE=F_DROID
TERMUX_APP__APP_VERSION_CODE=1020
TERMUX_APP__APP_VERSION_NAME=0.119.0-beta.1
TERMUX_APP__DATA_DIR=/data/user/0/com.termux
TERMUX_APP__IS_DEBUGGABLE_BUILD=false
TERMUX_APP__IS_INSTALLED_ON_EXTERNAL_STORAGE=false
TERMUX_APP__PACKAGE_NAME=com.termux
TERMUX_APP__PID=29177
TERMUX_APP__TARGET_SDK=28
TERMUX_VERSION=0.119.0-beta.1
TERMUX__SE_FILE_CONTEXT=u:object_r:app_data_file:s0:c237,c256,c512,c768
TERMUX__SE_INFO=default:targetSdkVersion=28:complete
TERMUX__SE_PROCESS_CONTEXT=u:r:untrusted_app_27:s0:c237,c256,c512,c768
TERMUX__UID=10237
TERMUX__USER_ID=0
Packages CPU architecture:
aarch64
Subscribed repositories:
# sources.list
deb https://mirrors.aliyun.com/termux/termux-main stable main
# tur-repo (sources.list.d/tur.list)
deb https://tur.kcubeterm.com tur-packages tur tur-on-device tur-continuous
# sources.list.d/termux-adb.list
deb https://nohajc.github.io termux extras
# x11-repo (sources.list.d/x11.list)
deb https://mirrors.aliyun.com/termux/termux-x11 x11 main
Updatable packages:
debianutils/stable 5.21 aarch64 [upgradable from: 5.20]
firefox/x11 131.0.3-1 aarch64 [upgradable from: 131.0.3-1]
gst-plugins-good/stable 1.24.9-1 aarch64 [upgradable from: 1.24.9]
plantuml/stable 1.2024.8 all [upgradable from: 1.2024.7]
termux-tools version:
1.44.3
Android version:
13
Kernel build information:
Linux localhost 4.14.190-lineage-gef0cb31b13 #4 SMP PREEMPT Fri Jun 23 13:11:47 CEST 2023 aarch64 Android
Device manufacturer:
samsung
Device model:
SM-A705FN
LD Variables:
LD_LIBRARY_PATH=
LD_PRELOAD=/data/data/com.termux/files/usr/lib/libtermux-exec.so
Installed termux plugins:
com.termux.api versionCode:51
com.termux.x11 versionCode:15

robertkirkman avatar Nov 17 '24 16:11 robertkirkman

As I said before it was expected to not work on some devices. I did tested it only on Android 13 and it is expected to not work on older Android versions. I am planning to implement fully-fledged implementation a bit later and test it on Android 8+ devices.

twaik avatar Nov 17 '24 16:11 twaik

Oh I'm sorry I did not see the message about no bug reports if it's not working. I will delete everything except for the section about the device where it is already working.

robertkirkman avatar Nov 17 '24 17:11 robertkirkman

Ok, I updated the source, now it works with android 28-35.

twaik avatar Nov 19 '24 08:11 twaik