[vbox-dev] Running MeeGo UX correctly inside VirtualBox with OpenGL acceleration
haitao.feng at intel.com
Sun Aug 29 23:14:52 PDT 2010
Recently I am working on GL acceleration for MeeGo UX (http://meego.com/) in
VirtualBox. I have some findings on the VirtualBox GL acceleration
implementation and want to discuss them with VirtualBox developers.
1. How GL acceleration works in VirtualBox
VirtualBox uses Chromium (http://chromium.sourceforge.net/) to accelerate GL
performance. Chromium is a software framework to distribute OpenGL functions
calls across network. When VirtualBox addons are installed in the guest OS, and
when we start up an OpenGL application, it will dynamically modify the GL
dispatch table in LibGL.so. (It provides a X dri driver and will tell LibGL to
link its dri driver, when this driver is loaded, it modified the LibGL dispatch
table, this modification mechanism is provided by Chromium). The dynamic
modified libGL.so will dispatch the OpenGL function from guest to VirtualBox
through HGCM (Host Guest Communication Management). The VirtualBox will perform
those OpenGL functions at host side.
At host side, VirtualBox will create a peer window according with the guest
window, and perform the GL functions against this window. For the interaction
between guest normal X window and the OpenGL window, VirtualBox will check the
status of the guest OpenGL window, such as mapping, clipping, and will change
the host peer window states accordingly. For example, it gets the clipping
regions of the guest OpenGL window and uses those to clip the peer window. Those
checks are done when glClear and other most used glFunctions are invoked.
2. Problem Statement
However the above approach could not run MeeGo Netbook UX correctly. Actually
MeeGo NetBook UX is a mutter plugin. Mutter, as a compositor, draws textures
from application pixmaps into its GL window. When mutter wants to draw a texture
on its GL window, VirtualBox draws a window on top of mutter GL window at host
side. The drawing order of the host peer window is controlled by host WM, while
the drawing order of the texture is controlled by guest mutter. Actually the
MeeGo Netbook UX draw things into two layers, the bottom is the texture from
managed window application pixmap, the top is the MeeGo panel. So if an OpenGL
application is invoked, it will hide the top layer partially or wholly and make
the MeeGo panel unaccessible from users. (In real device, the OpenGL window
will be converted into texture and draw below MeeGo panel, while in VirtualBox,
the OpenGL window on host side will be on top of MeeGo panel)
If there are only one layer, the above approach works. For example, there is no
big problem with twm and compiz. I have not read compiz source codes, but I
guess it draws everything into one layer.
There are two ways to solve the problem.
1). Rendering GL off-screen and reading window contents back into guest.
We could use an off-screen buffer to do the rendering on host side, and when
guest needs the window contents, we read them back from host to guest. The
performance gain relies on OpenGL costs more time than reading pixels.
With minimal change to the current implementation, In Linux, off-screen buffer
could be achieved by using XCompositeRedirectWindow, In Windows and Mac, it
could be achieved by making the host peer window invisible.
With more changes, the off-screen buffer could be achieved by pixmap/fbo in
Linux and pbuffer/fbo in Windows and Mac.
When glXSwapbuffer happens, we copy the peer off-screen content from host to
guest by using glReadPixels.
I have disabled GLX_texture_from_pixmap and made this approach work in
VirtualBox on Linux, Windows and Mac OS X. The performance is usable in real
development. I could submit the code patch if you are interested in this
implementation. I will try this approach when enabling GLX_texture_from_pixmap
as currently this extension is on.
2). Rendering GL at host-side and forwarding guest normal X window
contents into host
Essentially this approach is to implement the guest mutter logic at host side.
Instead of drawing window, we will draw texture at host side. We still need an
off-screen buffer for OpenGL application, and when we want to draw texture in
guest, we convert the off-screen buffer to texture and draw it at host side. In
Linux, we could use GLX_texture_from_pixmap to accelerate on host, in
Windows/Mac, at host side we will copy the content, and translate the pixmap
into texture by glTexImage2D, which is the same with guest mutter fallback
implementation. For normal X window, we need to forward their contents out and
draw it if there are damages for them.
To implement this, for guest GL window, we need to find a chance to bind the
host peer window's pixmap into texture, and then draw it at a proper time. For
guest normal X window, when there are damages, we need to turn them into texture
and draw them outside. I have not implemented this yet.
I want to know what do you think from VirtualBox developer's perspective and
your future plan on VirtualBox GL acceleration. I'd like to see MeeGo UX could
run with GL acceleration in official VirtualBox distribution in the future.
More information about the vbox-dev