Replies: 3 comments 95 replies
-
@licy183 can you please ping someone who can help us? |
Beta Was this translation helpful? Give feedback.
-
I'm starting to adapt my EGL wrapper to libglvnd now and I'm looking into libxcb to make the X11 platform available. I'll report my progress here. |
Beta Was this translation helpful? Give feedback.
-
@licy183 Hi. I have an idea how to make virglrenderer-android work much faster than it does now, but it will require patching virglrenderer, mesa and maybe X server. Maybe it would be tough thing. virgl + mesa (virpipe driver) + X server. I think it should work only after checking only if X server supports DRI3 and Android supports AHardwareBuffer. AHardwareBuffer can be transfered through Unix sockets (preferably socketpair), so it would be much better to set some AHardwareBuffer as back/front buffer and transfered to X server with How do you think, can you implement that? |
Beta Was this translation helpful? Give feedback.
-
Hi. It is purely theoretical material, you can ignore it if you want or add something I miss.
I am not enough skilled to implement this but I found some things that can be useful for someone who is enough skilled.
Using full GL with Android's GLES library.
Everybody knows that we can emulate GL with virglrenderer+GLES and mesa's libGL.so+virpipe. But this virtio solution gives significant overhead. Related issue.
I think it is possible to get rid of virtio and dispatch GL (or Gallium, I am not so sure) directly to GLES. zzyiwei said it is possible to do something like
GL->virgl->vrend->GLES
to achieve this.Using Android's GLES with X11 without exposing private API.
Forcing mesa to output to shared texture.
Currently Android's EGL library does not support X11, and there is no GLX support. We can use mesa but it can not use Android's drivers. There are only swrast and virpipe backends available. Both of them use shared memory fragment created with shmat/shmctl/shmdt/etc so mesa renders image to some internal buffer,
memcpy
's it to shared memory fragment and than displays it on X server (swrast) ormemcpy
's image from memfd/ashmem fragment to the same shared fragment and than displays it on X server (virpipe). This solution is universal but not much effective. Android 8+ lets us useAHardwareBuffer
. We can allocate it an bind to GLES texture. We can not build ANativeWindow from such buffer without exposing private Android APIs, but it is possible to modify mesa/vrend source to force output to this texture instead of rendering to EGLSurface.Binding shared texture (AHardwareBuffer) to X server.
As I said before Android's EGL is not compatible with X11 windows. But we can bind Android's
AHardwareBuffer
to new pixmap of X server and display it (and of cource we should force GL library to output everything to this AHardwareBuffer based texture). That is how I see this.AHardwareBuffer_sendHandleToUnixSocket
. So you can create socket withsocketpair
and pass AHardwareBuffer there. After that you will be able torecvmsg
file descriptors related to this AHardwareBuffer from second file descriptor of this socket pair. As far as I know first file descriptor of AHardwareBuffer we get this way is always DMABUF file descriptor. This file descriptor can bemmap
ed as any ordinary file descriptor.xcb_shm_attach_fd
function (man) that lets us bind any file descriptor to X server as memory fragment (just like XShmCreateImage, but not yet binding to XImage). And there is second functionxcb_shm_create_pixmap
(man) to create pixmap from this memory fragment. As you can see these functions are not properly documented, but they work.xcb_present_pixmap
on X11 window at coordinate (0,0) (here). That is pretty elegant and enough optimized I think.PRESENT
extension'sconfigure
(window resize) events (here) and read them without interfering with the rest of application code (here).Presenting pixmap should be done at every
glXSwapBuffers
call, and we should have at least two or three buffers to avoid flickering.Using full GL with Android's Vulkan library with Zink.
Modern Zink requires
vkCreateXcbSurfaceKHR
for its Kopper WSI. Android's Vulkan library does not provide it. But I believe we can make Zink output to some offscreen surface withvkCreateDisplayPlaneSurfaceKHR
and then output to shared memory fragment just like swrast do, or output to AHardwareBuffer bound to Vulkan as a texture and bind it to X11 pixmap (in the way I described for GLES output).UPD: As far as I understand this we can not inject vkImages created with AHardwareBuffers to Vulkan swapchain, but we can replace the whone zink_kopper.c code with something more termux-specific, implementing output to a few AHardwareBuffers, with presenting these buffers to X11 window with
Present
X11 extension...Sorry for my bad English.
Beta Was this translation helpful? Give feedback.
All reactions