meson,gfxstream: add Android support via meson2hermetic

Previously, there were no meson.build rules for the Android
portion of gfxstream_vk, since nobody builds gfxstream_vk + Android
via the Android NDK.

Using Soong (and not the Android NDK) is an absolute requirement,
since Android Virtual Devices (AVDs) were amongst to fully
transition to Soong over Android makefiles, leading to
breath-taking and exhilarating build speeds.

The meson build rules that do exist works are designed for
gfxstream_vk + Linux.  That leads to higher maintainence
costs: maintaining hand-written Android.bp files for Android,
and meson.build for Linux.

Enter meson2hermetic.  With this tool, meson.build becomes the
source of truth, and Android.bp are generating automatically,
reducing maintainence costs.

But for this to work, the portion of gfxstream_vk that didn't
have meson build rules needs them.  This patch does this
and there are two things to note:

1) gfxstream_vk + Android needs dependencies that don't have
any pkg-config files, and exist only with the AOSP tree.
These include things like:

   - libqemupipe.ranchu
   - libOpenglCodecCommon
   - libgralloc_cb.ranchu
   - renderControlEncoder

Most of these dependencies support the Goldfish AVD, and will
be deleted over time as the that emulator transitions to
virtio-gpu.  There are more generic Android deps too, like
"android_base".

Generic Android dependencies are given the prefix "android-",
while Goldfish (a.k.a Android Emulator) is given the prefix
"android-aemu-".

The ability to use dependencies that don't have a direct
Linux-distro style analogue is the one of motivators
meson2hermetic.

2) There's a special "gfxstream_emulated_android" case.  This
is for the GfxstreamEnd2EndTests target, which uses the code
defined here:

- src/gfxstream/guest/android/ANativeWindowEmulated.cpp
- src/gfxstream/guest/android/GrallocEmulated.cpp

This is used by Gfxstream Github for CI/CD.

Acked-by: Eric Engestrom <eric@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39279>
This commit is contained in:
Gurchetan Singh 2025-11-24 14:01:04 -08:00 committed by Marge Bot
parent 6e9b1ed53a
commit adec216eb0
8 changed files with 192 additions and 86 deletions

View file

@ -451,6 +451,27 @@ with_platform_haiku = _platforms.contains('haiku')
with_platform_windows = _platforms.contains('windows')
with_platform_macos = _platforms.contains('macos')
with_gfxstream_emulated_android = with_gfxstream_vk and with_platform_android and host_machine.system() == 'linux'
if with_gfxstream_emulated_android
# When building the android_stub with a non-Bionic sysroot/target, we to have
# define macros that are typically in <sys/cdefs.h> when using a Bionic
# sysroot
pre_args += '-D__INTRODUCED_IN(api_level)='
# We don't want to build Vulkan common code when running the emulated
# gfxstream Android platform. This causes issues when building in
# tandem with host Lavapipe.
#
# TODO(gfxstream-devs@): Modifying the user-provided platform can be removed
# when Cuttlefish moves it's host library builds off Soong, and on to Github.
# For now, add basic sanity checks before modifying user arguments.
if _platforms.contains('android') and _platforms.length() != 1
error('You cannot enable platform "android" at the same time as another platform')
endif
_platforms = []
with_platform_android = false
endif
with_glx = get_option('glx')
if with_glx == 'auto'
if not with_opengl
@ -925,8 +946,9 @@ endif
pre_args += '-DGLAPI_EXPORT_PROTO_ENTRY_POINTS=@0@'.format(with_glapi_export_proto_entry_points.to_int())
with_android_stub = get_option('android-stub')
if with_android_stub and not with_platform_android
error('`-D android-stub=true` makes no sense without `-D platforms=android`')
need_android_stub = with_platform_android or with_gfxstream_emulated_android
if with_android_stub and not need_android_stub
error('`-D android-stub=true` makes no sense without `-D platforms=android` or emulated Android')
endif
with_libbacktrace = get_option('android-libbacktrace') \

View file

@ -0,0 +1,44 @@
# Copyright 2026 Google
# SPDX-License-Identifier: MIT
inc_gfxstream_android = include_directories('include')
deps_gfxstream_android = [dependency('android-utils')]
if host_machine.system() == 'android'
dep_android_minigbm_headers = dependency('android-minigbm-headers')
dep_android_nativebase_headers = dependency('android-nativebase-headers')
dep_android_aemu_gralloc_headers = dependency('android-aemu-gralloc-headers')
files_gfxstream_android = files(
'ANativeWindowAndroid.cpp',
'GfxStreamGralloc.cpp',
'GrallocGoldfish.cpp',
'GrallocMinigbm.cpp',
)
deps_gfxstream_android += [
dep_android_minigbm_headers,
dep_android_nativebase_headers,
dep_android_aemu_gralloc_headers,
]
else
files_gfxstream_android = files(
'ANativeWindowEmulated.cpp',
'GrallocEmulated.cpp',
)
endif
libgfxstream_guest_android = static_library(
'gfxstream_android',
files_gfxstream_android,
cpp_args: gfxstream_guest_args,
include_directories: [inc_gfxstream_android, inc_platform_virtgpu, inc_src, inc_include],
link_with: [libplatform_virtgpu],
dependencies: deps_gfxstream_android + dep_android,
)
idep_gfxstream_guest_android = declare_dependency(
link_with: libgfxstream_guest_android,
include_directories: inc_gfxstream_android,
)
gfxstream_deps += idep_gfxstream_guest_android

View file

@ -24,5 +24,5 @@ libconnection_manager = static_library(
inc_aemu,
],
link_with: [lib_goldfish_address_space, libplatform_virtgpu],
dependencies: dep_libdrm,
dependencies: [dep_libdrm, dep_android_aemu_qemupipe, idep_mesautil],
)

View file

@ -21,6 +21,7 @@ if host_machine.system() == 'windows'
else
gfxstream_guest_args += '-DLINUX_GUEST_BUILD'
endif
# Include the gfxstream private VkStructureType definitions
gfxstream_guest_args += '-DVK_GFXSTREAM_STRUCTURE_TYPE_EXT'
@ -44,6 +45,61 @@ gfxstream_guest_args += '-DVK_BASE_VERSION_1_4'
gfxstream_guest_args += '-DVK_GRAPHICS_VERSION_1_4'
gfxstream_guest_args += '-DVK_COMPUTE_VERSION_1_4'
if with_gfxstream_emulated_android
gfxstream_guest_args += '-DEND2END_TESTS'
endif
#====================================#
# Standard deps #
#====================================#
gfxstream_deps = [
dep_libdrm,
idep_mesautil,
idep_vulkan_wsi_headers,
idep_vulkan_lite_runtime,
idep_vulkan_util_headers,
idep_vulkan_wsi,
dep_valgrind,
]
if with_perfetto
gfxstream_deps += dep_perfetto
endif
#====================================#
# Android deps (mostly Goldfish) #
# Only works with meson2hermetic #
#====================================#
dep_android_base = null_dep
dep_android_arect = null_dep
dep_android_aemu_base = null_dep
dep_android_aemu_gl_codec = null_dep
dep_android_aemu_qemupipe = null_dep
dep_android_aemu_ringbuffer = null_dep
dep_android_aemu_rc_encoder = null_dep
if with_platform_android or with_gfxstream_emulated_android
gfxstream_guest_args += '-DVK_USE_PLATFORM_ANDROID_KHR'
dep_android_base = dependency('android-base')
dep_android_arect = dependency('android-arect')
dep_android_aemu_base = dependency('android-aemu-base')
dep_android_aemu_gl_codec = dependency('android-aemu-gl-codec')
dep_android_aemu_qemupipe = dependency('android-aemu-qemupipe')
dep_android_aemu_ringbuffer = dependency('android-aemu-ringbuffer')
dep_android_aemu_rc_encoder = dependency('android-aemu-rc-encoder')
gfxstream_deps += dep_android
gfxstream_deps += [
dep_android_base,
dep_android_arect,
dep_android_aemu_base,
dep_android_aemu_gl_codec,
dep_android_aemu_ringbuffer,
dep_android_aemu_rc_encoder,
dep_android_aemu_qemupipe,
]
endif
#===============#
# Includes #
#===============#
@ -58,5 +114,10 @@ subdir('iostream')
subdir('platform')
subdir('GoldfishAddressSpace')
subdir('connection-manager')
if with_platform_android or with_gfxstream_emulated_android
subdir('android')
endif
subdir('vulkan_enc')
subdir('vulkan')

View file

@ -13,5 +13,5 @@ libplatform_virtgpu_drm = static_library(
files_libplatform_virtgpu_drm,
cpp_args: gfxstream_guest_args,
include_directories: [inc_platform_virtgpu, inc_src, inc_include],
dependencies: dep_libdrm,
dependencies: [dep_libdrm, idep_mesautil],
)

View file

@ -26,6 +26,7 @@ libplatform_virtgpu_kumquat = static_library(
],
dependencies: [
idep_vulkan_util_headers,
idep_mesautil,
dep_virtgpu_kumquat_ffi,
dep_gfxstream_vulkan_mapper,
],

View file

@ -18,22 +18,18 @@ if with_platform_wayland
gfxstream_vk_wsi_args += '-DGFXSTREAM_VK_WAYLAND'
endif
gfxstream_deps = [
dep_libdrm,
idep_vulkan_wsi_headers,
idep_vulkan_lite_runtime,
idep_vulkan_util_headers,
idep_vulkan_wsi,
dep_valgrind,
]
files_vulkan_gfxstream = files_lib_vulkan_gfxstream + files_lib_vulkan_enc
files_vulkan_gfxstream += gfxstream_vk_entrypoints
files_vulkan_gfxstream += gfxstream_guest_vk_autogen
files_vulkan_gfxstream += vulkan_gfxstream_h
if with_perfetto
gfxstream_deps += dep_perfetto
if with_platform_android or with_gfxstream_emulated_android
files_vulkan_gfxstream += files_lib_vulkan_enc_android
endif
lib_vulkan_gfxstream = shared_library(
'vulkan_gfxstream',
files_lib_vulkan_gfxstream + files_lib_vulkan_enc + gfxstream_vk_entrypoints + gfxstream_guest_vk_autogen + vulkan_gfxstream_h,
files_vulkan_gfxstream,
cpp_args: gfxstream_guest_args + gfxstream_vk_wsi_args,
include_directories: [
inc_vulkan_headers,
@ -66,7 +62,7 @@ icd_file_name = libname_prefix + 'vulkan_gfxstream.' + libname_suffix
gfxstream_icd = custom_target(
'gfxstream_vk_icd',
input: [vk_icd_gen, vk_api_xml],
output : 'gfxstream_vk_icd.' + vulkan_manifest_suffix,
output: 'gfxstream_vk_icd.' + vulkan_manifest_suffix,
command: [
prog_python,
'@INPUT0@',

View file

@ -4,83 +4,61 @@
output_host_path = meson.current_build_dir() + '/host/vulkan/cereal'
guest_enc_path = meson.current_build_dir()
if build_machine.system() != 'android'
gfxstream_guest_vk_autogen = custom_target(
'gfxstream_guest_vk_autogen',
output: [
'VkEncoder.h',
'goldfish_vk_counting_guest.h',
'goldfish_vk_deepcopy_guest.h',
'goldfish_vk_marshaling_guest.h',
'goldfish_vk_extension_structs_guest.h',
'goldfish_vk_reserved_marshaling_guest.h',
'goldfish_vk_transform_guest.h',
'goldfish_vk_counting_guest.cpp',
'goldfish_vk_deepcopy_guest.cpp',
'goldfish_vk_extension_structs_guest.cpp',
'goldfish_vk_marshaling_guest.cpp',
'goldfish_vk_reserved_marshaling_guest.cpp',
'goldfish_vk_transform_guest.cpp',
'VkEncoder.cpp',
'func_table.cpp',
],
depend_files: genvk_depends,
env: {
'GFXSTREAM_NO_CLANG_FMT': '1',
'CEREAL_VARIANT' : 'guest',
'GFXSTREAM_GUEST_ENCODER_DIR': guest_enc_path,
},
input: [genvk, vk_api_xml, vk_gfxstream_xml],
command: [
prog_python,
'@INPUT0@',
'-registry',
'@INPUT1@',
'-registryGfxstream',
'@INPUT2@',
'cereal',
'-o',
output_host_path,
],
)
vulkan_gfxstream_h = custom_target(
'vulkan_gfxstream_header',
output: ['vulkan_gfxstream.h'],
env: {'GFXSTREAM_NO_CLANG_FMT': '1', 'CEREAL_VARIANT' : 'guest'},
input: [genvk, vk_gfxstream_xml],
depend_files: genvk_depends,
command: [
prog_python,
'@INPUT0@',
'-registry',
'@INPUT1@',
'vulkan_gfxstream.h',
'-o',
guest_enc_path,
],
)
else
gfxstream_guest_vk_autogen = files(
'VkEncoder.cpp',
gfxstream_guest_vk_autogen = custom_target(
'gfxstream_guest_vk_autogen',
output: [
'VkEncoder.h',
'func_table.cpp',
'goldfish_vk_counting_guest.cpp',
'goldfish_vk_counting_guest.h',
'goldfish_vk_deepcopy_guest.cpp',
'goldfish_vk_deepcopy_guest.h',
'goldfish_vk_extension_structs_guest.cpp',
'goldfish_vk_extension_structs_guest.h',
'goldfish_vk_marshaling_guest.cpp',
'goldfish_vk_marshaling_guest.h',
'goldfish_vk_reserved_marshaling_guest.cpp',
'goldfish_vk_extension_structs_guest.h',
'goldfish_vk_reserved_marshaling_guest.h',
'goldfish_vk_transform_guest.cpp',
'goldfish_vk_transform_guest.h',
)
'goldfish_vk_counting_guest.cpp',
'goldfish_vk_deepcopy_guest.cpp',
'goldfish_vk_extension_structs_guest.cpp',
'goldfish_vk_marshaling_guest.cpp',
'goldfish_vk_reserved_marshaling_guest.cpp',
'goldfish_vk_transform_guest.cpp',
'VkEncoder.cpp',
'func_table.cpp',
],
depend_files: genvk_depends,
env: {
'GFXSTREAM_NO_CLANG_FMT': '1',
'CEREAL_VARIANT' : 'guest',
'GFXSTREAM_GUEST_ENCODER_DIR': guest_enc_path,
},
input: [genvk, vk_api_xml, vk_gfxstream_xml],
command: [
prog_python,
'@INPUT0@',
'-registry',
'@INPUT1@',
'-registryGfxstream',
'@INPUT2@',
'cereal',
'-o',
output_host_path,
],
)
vulkan_gfxstream_h = files('vulkan_gfxstream.h')
endif
vulkan_gfxstream_h = custom_target(
'vulkan_gfxstream_header',
output: ['vulkan_gfxstream.h'],
depend_files: genvk_depends,
env: {'GFXSTREAM_NO_CLANG_FMT': '1', 'CEREAL_VARIANT' : 'guest'},
input: [genvk, vk_gfxstream_xml],
command: [
prog_python,
'@INPUT0@',
'-registry',
'@INPUT1@',
'vulkan_gfxstream.h',
'-o',
guest_enc_path,
],
)
gfxstream_vk_entrypoints = custom_target(
'gfxstream_vk_entrypoints',
@ -116,3 +94,7 @@ files_lib_vulkan_enc = files(
'VulkanStreamGuest.cpp',
'gfxstream_vk_private.cpp',
) + sha1_h
files_lib_vulkan_enc_android = files(
'AndroidHardwareBuffer.cpp',
)