Present() function in anbox platform sdk is not being called

Hi there, I am building and testing custom platform plugin based on the Anbox Platform SDK 1.17.0.

In the description of the “anbox::GraphicsProcessor::present(AnboxGraphicsBuffer2* buffer, AnboxCallback* callback)” function provided in the graphics_processor.h of the SDK, it is mentioned, “Used when graphics implementation is ANBOX_GRAPHICS_IMPLEMENTATION_TYPE_DIRECT_RENDERING or ANBOX_GRAPHICS_IMPLEMENTATION_TYPE_HOST_RENDERING.”
https://github.com/anbox-cloud/anbox-platform-sdk/blob/master/include/anbox-platform-sdk/graphics_processor.h

However, even after setting the GRAPHICS_IMPLEMENTATION_TYPE to ANBOX_GRAPHICS_IMPLEMENTATION_TYPE_HOST_RENDERING, I expected the present() function of the GraphicsProcessor to be called, but it is not being invoked.
And begin_frame() and finish_frame() are being called.

How can I ensure that present() function provided by the Anbox Platform SDK is called on a device with an NVIDIA GPU?

Any advice or guidance on this issue would be greatly appreciated. Thanks.

Best regards,

environment

Install Anbox cloud appliance
Ubuntu 22.04 pro
GPU : Nvidia Geforce RTX 3060 Ti, Driver Version: 535.129.03, CUDA Version: 12.2

test command

amc launch --raw --devmode --cpus 4 --gpu-slots 1 --memory 3221225472 --disk-size 3221225472
triplet=$(dpkg-architecture -qDEB_BUILD_MULTIARCH)
amc exec “${id}” mkdir “/usr/lib/${triplet}/anbox/platforms/myplatform”
lxc file push “platform_myplatform.so” “ams-${id}/usr/lib/${triplet}/anbox/platforms/myplatform/”
cat << EOF | amc exec “${id}” tee /var/lib/anbox/session.yaml
log-level: debug
platform: myplatform

platform code

inherit anbox::Platform
– get_config_item() override
— configure ANBOX_GRAPHICS_IMPLEMENTATION_TYPE_HOST_RENDERING to GRAPHICS_IMPLEMENTATION_TYPE
— configure DISPLAY_SPEC2 (AnboxDisplaySpec2 display_spec_ = {1280, 720, 160, 60}; )

inherit anbox::GraphicsProcessor
– initialize() override + include below code
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored “-Wold-style-cast”
configuration->native_display = EGL_DEFAULT_DISPLAY;
#pragma GCC diagnostic pop
configuration->native_window = 0;
configuration->output_flip_mode = FLIP_MODE_VERTICAL;
// The NVIDIA GL driver supports pbuffers so lets use them
configuration->avoid_pbuffers = false;
configuration->texture_format = AnboxGraphicsTextureFormat::TEXTURE_FORMAT_RGBA;

Hey @adlecddqq1,

The documentation is right in saying that GraphicsProcessor::present is called with ANBOX_GRAPHICS_IMPLEMENTATION_TYPE_HOST_RENDERING but also not precise enough as there is one more condition which need to be full filled for this.

Anbox Cloud traditionally uses EmuGL derived from the Android emulator (see https://android.googlesource.com/platform/external/qemu/+/master/distrib/android-emugl/DESIGN) to support OpenGL ES on NVIDIA GPUs. Recent versions of Anbox Cloud started to migrate to a VirGL/Venus based architecture (see https://chromeos.dev/en/posts/improving-vulkan-availability-with-venus) which bases graphics support on top of the NVIDIA Vulkan driver to provide full Vulkan API support in Android.

Both EmuGL and VirGL are considered to be ANBOX_GRAPHICS_IMPLEMENTATION_TYPE_HOST_RENDERING. The current default for ANBOX_GRAPHICS_IMPLEMENTATION_TYPE_HOST_RENDERING is EmuGL and we will migrate to VirGL with Anbox Cloud 1.22. In the upcoming Anbox Cloud 1.21 VirGL is kept behind a feature flag and instructions will be available at release time on how to enable it.

With the above I can now explain when GraphicsProcessor::present is called: It is only called for ANBOX_GRAPHICS_IMPLEMENTATION_TYPE_HOST_RENDERING when VirGL is being used. When EmuGL (current default in 1.20) is used you have to use GraphicsProcessor::begin_frame/GraphicsProcessor::finish_frame instead.

If you’re looking on how to receive the current frame buffer with GraphicsProcessor::begin_frame/GraphicsProcessor::finish_frame, you can simply beind an FBO with glBindFramebuffer(GL_FRAMEBUFFER, fbo) in begin_frame to redirect all rendering to a texture (which could be backed by a dma-buf). In finish_frame you can then either read the backing texture memory to CPU memory with glReadPixels or pass a potentially used dma-buf to whatever video encoder you want to use. The default WebRTC implementation in Anbox Cloud does this similar but with quite a few optimizations for efficiency and low latency.

I hope that helps. If not or you have any other questions, please let us know.

1 Like

Dear morphis

Thanks to your detailed explanation, I now understand that the present() function is not available in the current version, and I was able to inspect the frame buffer data through begin_frame() and finish_frame(). I greatly appreciate your assistance.

Best Regards.

That only applies for ANBOX_GRAPHICS_IMPLEMENTATION_TYPE_HOST_RENDERING. For AMD and Intel GPUs we use ANBOX_GRAPHICS_IMPLEMENTATION_TYPE_DIRECT_RENDERING and for that code path GraphicsProcessor::present is called and not begin_frame/finish_frame. So if you’re going to support multiple GPU types you will need to implement both paths.

I Understood. Thank you for the additional explanation.