util/vbuf: fix multidraw unrolling
[platform/upstream/mesa.git] / docs / android.rst
1 Android
2 =======
3
4 Mesa hardware drivers can be built for Android one of two ways: built
5 into the Android OS using the ndk-build build system on older versions
6 of Android, or out-of-tree using the Meson build system and the
7 Android NDK.
8
9 The ndk-build build system has proven to be hard to maintain, as one
10 needs a built Android tree to build against, and it has never been
11 tested in CI.  The Meson build system flow is frequently used by
12 Chrome OS developers for building and testing Android drivers.
13
14 Building using the Android NDK
15 ------------------------------
16
17 Download and install the NDK using whatever method you normally would.
18 Then, create your Meson cross file to use it, something like this
19 ``~/.local/share/meson/cross/android-aarch64`` file::
20
21     [binaries]
22     ar = 'NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar'
23     c = ['ccache', 'NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android29-clang']
24     cpp = ['ccache', 'NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android29-clang++', '-fno-exceptions', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-static-libstdc++']
25     c_ld = 'lld'
26     cpp_ld = 'lld'
27     strip = 'NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-strip'
28     # Android doesn't come with a pkg-config, but we need one for Meson to be happy not
29     # finding all the optional deps it looks for.  Use system pkg-config pointing at a
30     # directory we get to populate with any .pc files we want to add for Android
31     pkgconfig = ['env', 'PKG_CONFIG_LIBDIR=NDKDIR/pkgconfig', '/usr/bin/pkg-config']
32
33     [host_machine]
34     system = 'linux'
35     cpu_family = 'arm'
36     cpu = 'armv8'
37     endian = 'little'
38
39 Now, use that cross file for your Android build directory (as in this
40 one cross-compiling the turnip driver for a stock Pixel phone)
41
42 .. code-block:: console
43
44     meson build-android-aarch64 \
45         --cross-file android-aarch64 \
46         -Dplatforms=android \
47         -Dplatform-sdk-version=26 \
48         -Dandroid-stub=true \
49         -Dgallium-drivers= \
50         -Dvulkan-drivers=freedreno \
51         -Dfreedreno-kgsl=true
52     ninja -C build-android-aarch64
53
54 Replacing Android drivers on stock Android
55 ------------------------------------------
56
57 The vendor partition with the drivers is normally mounted from a
58 read-only disk image on ``/vendor``.  To be able to replace them for
59 driver development, we need to unlock the device and remount
60 ``/vendor`` read/write.
61
62 .. code-block:: console
63
64     adb disable-verity
65     adb reboot
66     adb remount -R
67
68 Now you can replace drivers as in:
69
70 .. code-block:: console
71
72     adb push build-android-aarch64/src/freedreno/vulkan/libvulkan_freedreno.so /vendor/lib64/hw/vulkan.sdm710.so
73
74 Note this command doesn't quite work because libvulkan wants the
75 SONAME to match.  For now, in turnip we have been using a hack to the
76 meson.build to change the SONAME.
77
78 Replacing Android drivers on Chrome OS
79 --------------------------------------
80
81 Chrome OS's ARC++ is an Android container with hardware drivers inside
82 of it.  The vendor partition with the drivers is normally mounted from
83 a read-only squashfs image on disk.  For doing rapid driver
84 development, you don't want to regenerate that image.  So, we'll take
85 the existing squashfs image, copy it out on the host, and then use a
86 bind mount instead of a loopback mount so we can update our drivers
87 using scp from outside the container.
88
89 On your device, you'll want to make ``/`` read-write.  ssh in as root
90 and run:
91
92 .. code-block:: console
93
94     crossystem dev_boot_signed_only=0
95     /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification --partitions 4
96     reboot
97
98 Then, we'll switch Android from using an image for ``/vendor`` to using a
99 bind-mount from a directory we control.
100
101 .. code-block:: console
102
103     cd /opt/google/containers/android/
104     mkdir vendor-ro
105     mount -o loop vendor.raw.img vendor-ro
106     cp -a vendor-ro vendor-rw
107     emacs config.json
108
109 In the ``config.json``, you want to find the block for ``/vendor`` and
110 change it to::
111
112             {
113                 "destination": "/vendor",
114                 "type": "bind",
115                 "source": "/opt/google/containers/android/vendor-rw",
116                 "options": [
117                     "bind",
118                     "rw"
119                 ]
120             },
121
122 Now, restart the UI to do a full reload:
123
124 .. code-block:: console
125
126     restart ui
127
128 At this point, your android container is restarted with your new
129 bind-mount ``/vendor``, and if you use ``android-sh`` to shell into it
130 then the ``mount`` command should show::
131
132     /dev/root on /vendor type ext2 (rw,seclabel,relatime)
133
134 Now, replacing your DRI driver with a new one built for Android should
135 be a matter of:
136
137 .. code-block:: console
138
139     scp msm_dri.so $HOST:/opt/google/containers/android/vendor-rw/lib64/dri/
140
141 You can do your build of your DRI driver using ``emerge-$BOARD
142 arc-mesa-freedreno`` (for example) if you have a source tree with
143 ARC++, but it should also be possible to build using the NDK as
144 described above.  There are currently rough edges with this, for
145 example the build will require that you have your arc-libdrm build
146 available to the NDK, assuming you're building anything but the
147 Freedreno Vulkan driver for KGSL.  You can mostly put things in place
148 with:
149
150 .. code-block:: console
151
152     scp $HOST:/opt/google/containers/android/vendor-rw/lib64/libdrm.so \
153         NDKDIR/sysroot/usr/lib/aarch64-linux-android/lib/
154
155     ln -s \
156         /usr/include/xf86drm.h \
157         /usr/include/libsync.h \
158         /usr/include/libdrm \
159         NDKDIR/sysroot/usr/include/
160
161 It seems that new invocations of an application will often reload the
162 DRI driver, but depending on the component you're working on you may
163 find you need to reload the whole Android container.  To do so without
164 having to log in to Chrome again every time, you can just kill the
165 container and let it restart:
166
167 .. code-block:: console
168
169     kill $(cat /run/containers/android-run_oci/container.pid )