🇺🇸 English version
virglrenderer是給QEMU虛擬機用的顯示技術,可給虛擬機提供3D硬體加速。舉例來說:Linux電腦用QEMU跑Android-x86虛擬機,能透過virglrenderer改善虛擬機的3D圖形性能。
透過Termux執行virglrenderer的伺服器,就能在Android手機達到類似效果,雖然目前的圖形效率沒有很高就是了。
至少這樣就可以在Termux的Proot Linux環境看4K60p影片、玩3D遊戲了。
SuperTuxKart, Glxgears
此方案的好處是Proot和Chroot都能用,並且過程比之前編譯Zink的要簡單許多。
用講的太抽象,不如先看看影片所呈現的效果:
- 測試手機:Sony Xperia 5 II,系統版本Android 12,處理器Snapdragon 865,GPU為Adreno 650,RAM 8GB。
安裝Termux,並安裝Termux X11套件與其APK。
理論上XSDL或VNC也可以,我個人偏好用Termux X11來顯示圖形環境。
安裝一個Proot發行版並設定桌面環境。
個人推薦安裝Debian。
註:Termux現有virglrenderer_android
套件可以裝,你可以用這個取代手動編譯的virglrenderer。
方案1:安裝virglrenderer Android
virglrenderer-adroid使用的是Android的GLES,適用於大多數Android手機。
- 安裝virglrenderer-android
1
| pkg install virglrenderer-android
|
- 執行Virgl伺服器:
1
| virgl_test_server_android &
|
方案2:編譯支援Zink的Virglrenderer
Zink是模擬Vulkan的驅動程式,只支援使用Qualcomm Aderno GPU的Android裝置。
註:以下是在Termux編譯,而非proot內部。
- 安裝編譯用的套件
1
2
3
4
5
6
7
8
9
| pkg install -y x11-repo
pkg install -y clang lld binutils cmake autoconf automake libtool ndk-sysroot ndk-multilib make python git libandroid-shmem-static ninja llvm bison flex libx11 xorgproto libdrm libpixman libxfixes libjpeg-turbo xtrans libxxf86vm xorg-xrandr xorg-font-util xorg-util-macros libxfont2 libxkbfile libpciaccess xcb-util-renderutil xcb-util-image xcb-util-keysyms xcb-util-wm xorg-xkbcomp xkeyboard-config libxdamage libxinerama
pkg install clvk glfw mesa-vulkan-icd-swrast swiftshader vulkan-extension-layer vulkan-extension-layer-static vulkan-headers vulkan-loader vulkan-loader-generic vulkan-tools
pkg install vulkan-loader-android
pip install meson mako
|
- 複製libxshmfence、mesa、libepoxy、virglrenderer的原始碼
1
2
3
4
5
6
| mkdir ~/tmp
cd ~/tmp
LD_PRELOAD='' git clone --depth 1 -b libxshmfence-1.3 https://gitlab.freedesktop.org/xorg/lib/libxshmfence.git
LD_PRELOAD='' git clone --depth 1 -b mesa-22.0.5 https://gitlab.freedesktop.org/mesa/mesa.git
LD_PRELOAD='' git clone --depth 1 -b 1.5.10 https://github.com/anholt/libepoxy.git
LD_PRELOAD='' git clone --shallow-since 2022-06-27 https://gitlab.freedesktop.org/virgl/virglrenderer.git
|
- 編譯libxshmfence
1
2
3
4
| cd ~/tmp/libxshmfence
./autogen.sh --prefix=$PREFIX --with-shared-memory-dir=$TMPDIR
sed -i s/values.h/limits.h/ ./src/xshmfence_futex.h
make -j8 install CPPFLAGS=-DMAXINT=INT_MAX
|
- 編譯mesa
1
2
3
4
5
6
7
8
9
10
11
| cd ~/tmp/mesa
sed -i '40s+^$+#include "X11/Xlib.h"+' src/egl/main/egldisplay.h
sed -i 's/^import os$/import os, shutil\ndef link(src, dest):\n shutil.copyfile(src, dest)\ndef unlink(src):\n os.remove(src)\nos.link = link\nos.unlink = unlink/' bin/install_megadrivers.py
mkdir b && cd b
LDFLAGS='-l:libandroid-shmem.a -llog' meson .. -Dprefix=$PREFIX -Dplatforms=x11 -Dgbm=enabled -Ddri-drivers='' -Dgallium-drivers=zink,swrast -Dllvm=disabled -Dvulkan-drivers='' -Dcpp_rtti=false -Dc_args=-Wno-error=incompatible-function-pointer-types -Dbuildtype=release
rm $PREFIX/lib/libglapi.so*
rm $PREFIX/lib/libGL.so*
rm $PREFIX/lib/libGLES*
rm $PREFIX/lib/libEGL*
rm $PREFIX/lib/libgbm*
ninja install
|
- 編譯libepoxy
1
2
3
4
5
| cd ~/tmp/libepoxy
mkdir b && cd b
meson -Dprefix=$PREFIX -Dbuildtype=release -Dglx=yes -Degl=yes -Dtests=false -Dc_args=-U__ANDROID__ ..
rm $PREFIX/lib/libepoxy.so*
ninja install
|
- 編譯virglrenderer
1
2
3
4
5
6
| cd ~/tmp/virglrenderer
git checkout -f dd301caf7e05ec9c09634fb7872067542aad89b7~2
sed -i 's+"/tmp+"/data/data/com.termux/files/usr/tmp+' vtest/vtest_protocol.h
mkdir b && cd b
meson -Dbuildtype=release -Dprefix=$PREFIX -Dplatforms=egl ..
ninja install
|
- 欲啟動Virgl伺服器,執行以下指令,這裡會輸出圖形相關的除錯資訊。接著再從螢幕左邊滑進來開第二個終端機執行其他指令。
1
| MESA_NO_ERROR=1 MESA_GL_VERSION_OVERRIDE=4.0 GALLIUM_DRIVER=zink virgl_test_server --use-egl-surfaceless &
|
Termux本身用於執行virglrenderer的伺服器,但是Termux的應用程式無法直接使用virglrenderer,必須使用proot或chroot才行。
virgl server可能會在Termux更新套件後失效(啟動應用程式看到libEGL warning: DRI2: failed to create dri screen
之類的訊息)。如果發生了,就得重新編譯第3節提到的所有套件。
啟動virgl的伺服器。
啟動Termux X11 APP。回到Termux,執行Termux X11
1
2
| export DISPLAY=:0
termux-x11 :0 &
|
- 從螢幕左邊滑進來,按New Session開啟第二個終端機。以一般帳戶
user
登入proot-distro,掛載Termux的tmp目錄至Proot-distro,
1
| proot-distro login debian --user user --shared-tmp
|
- 啟動XFCE4桌面環境。
1
2
| export DISPLAY=:0
dbus-launch --exit-with-session startxfce4 &
|
在Termux X11的界面開啟終端機。在執行程式前加入GALLIUM_DRIVER
啟用virgl硬體加速,如果不加系統會回復使用CPU算繪的llvmpipe。有些程式加MESA_GL_VERSION_OVERRIDE=4.0
會開不起來,需要自行測試。
例如要執行方塊遊戲Minetest:
1
| GALLIUM_DRIVER=virpipe MESA_GL_VERSION_OVERRIDE=4.0 minetest
|
virpipe下glxgears的FPS相比llvimpipe高出一些。

llvmpipe與virpipe比較,Minetest的FPS從10FPS增長到最多20FPS。

VLC啟用virpipe後4K60p影片也播得動了,但基本上是拼盡全力在算繪,一有程式(例如錄影)跟影片播放器搶資源就會畫面撕裂。

賽車遊戲SueprTuxKart成長最明顯:llvmpipe模式下是幻燈片,有了virpipe後就能正常遊玩了。

Firefox在about:config
強制啟用WebGL後,WebGL Aquarium的FPS翻倍。

設定帶有XFCE4桌面的chroot Ubuntu with XFCE4
將SELinux設定為Permissive
- 啟動Termux X11 APP,返回Termxu,執行:
1
| XDG_RUNTIME_DIR=${TMPDIR} termux-x11 :0 -ac &
|
- 將Termux的tmp掛載至chroot的tmp
1
2
| export CHROOT_DIR=/data/local/tmp/chrootubuntu
sudo busybox mount --bind $PREFIX/tmp $CHROOT_DIR/tmp
|
- 登入chroot,啟動XFCE4
1
2
3
| chmod -R 777 /tmp
export DISPLAY=:0 PULSE_SERVER=tcp:127.0.0.1:4713
dbus-launch --exit-with-session startxfce4 &
|
- 以virgl 啟動應用程式
1
| GALLIUM_DRIVER=virpipe MESA_GL_VERSION_OVERRIDE=4.0 minetest
|
請先安裝Box86 + Wine。
在Termux啟動virgl伺服器。
並在執行exe前同樣加上GALLIUM_DRIVER
參數,例如:
1
| GALLIUM_DRIVER=virpipe MESA_GL_VERSION_OVERRIDE=4.0 box86 wine AIR.exe
|
virgl能讓部份需要硬體加速的Windows遊戲正常執行,例如Tobyfox製作的《Undertale》

以及Key製作的視覺小說《Air》,需另外安裝日文字體。
