gpu_renderer: add syncfd flag for gfxstream

Add a gpu argument to control the syncfd of gfxstream implemented in
these CL: https://android-review.googlesource.com/q/topic:%22gfxstream-sync-fd%22+(status:open%20OR%20status:merged).
Default to enabled.

BUG=None
TEST=launch_cvd

Change-Id: Id4933b8654fc1b1bb73784bd8e1a85e73d0266d6
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2286237
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Kaiyi Li <kaiyili@google.com>
Reviewed-by: Lingfeng Yang <lfy@google.com>
Reviewed-by: Zach Reizner <zachr@chromium.org>
diff --git a/devices/Cargo.toml b/devices/Cargo.toml
index cb2efd9..07453de 100644
--- a/devices/Cargo.toml
+++ b/devices/Cargo.toml
@@ -11,7 +11,7 @@
 video-encoder = ["libvda"]
 wl-dmabuf = []
 x = ["gpu_display/x"]
-gfxstream = ["gpu"]
+gfxstream = ["gpu", "gpu_renderer/gfxstream"]
 
 [dependencies]
 acpi_tables = {path = "../acpi_tables" }
diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs
index bad69c4..4bffba3 100644
--- a/devices/src/virtio/gpu/mod.rs
+++ b/devices/src/virtio/gpu/mod.rs
@@ -67,6 +67,8 @@
     pub renderer_use_gles: bool,
     pub renderer_use_glx: bool,
     pub renderer_use_surfaceless: bool,
+    #[cfg(feature = "gfxstream")]
+    pub gfxstream_use_syncfd: bool,
     pub mode: GpuMode,
 }
 
@@ -88,6 +90,8 @@
             renderer_use_gles: true,
             renderer_use_glx: false,
             renderer_use_surfaceless: true,
+            #[cfg(feature = "gfxstream")]
+            gfxstream_use_syncfd: true,
             mode: GpuMode::Mode3D,
         }
     }
@@ -1030,6 +1034,8 @@
             .use_gles(gpu_parameters.renderer_use_gles)
             .use_glx(gpu_parameters.renderer_use_glx)
             .use_surfaceless(gpu_parameters.renderer_use_surfaceless);
+        #[cfg(feature = "gfxstream")]
+        let renderer_flags = renderer_flags.use_syncfd(gpu_parameters.gfxstream_use_syncfd);
 
         let backend_kind = match gpu_parameters.mode {
             GpuMode::Mode2D => BackendKind::Virtio2D,
diff --git a/devices/src/virtio/gpu/virtio_gfxstream_backend.rs b/devices/src/virtio/gpu/virtio_gfxstream_backend.rs
index b2a9fb7..e7d4654 100644
--- a/devices/src/virtio/gpu/virtio_gfxstream_backend.rs
+++ b/devices/src/virtio/gpu/virtio_gfxstream_backend.rs
@@ -216,6 +216,7 @@
         display: GpuDisplay,
         display_width: u32,
         display_height: u32,
+        renderer_flags: RendererFlags,
         _gpu_device_socket: VmMemoryControlRequestSocket,
         _pci_bar: Alloc,
     ) -> VirtioGfxStreamBackend {
@@ -224,8 +225,6 @@
             fence_state: Rc::clone(&fence_state),
         }));
 
-        let renderer_flags: RendererFlags = RendererFlags::new().use_surfaceless(true);
-
         let display_rc_refcell = Rc::new(RefCell::new(display));
 
         let scanout_surface = match (display_rc_refcell.borrow_mut()).create_surface(
@@ -284,7 +283,7 @@
         display: GpuDisplay,
         display_width: u32,
         display_height: u32,
-        _renderer_flags: RendererFlags,
+        renderer_flags: RendererFlags,
         _event_devices: Vec<EventDevice>,
         gpu_device_socket: VmMemoryControlRequestSocket,
         pci_bar: Alloc,
@@ -293,6 +292,7 @@
             display,
             display_width,
             display_height,
+            renderer_flags,
             gpu_device_socket,
             pci_bar,
         )))
diff --git a/gpu_renderer/Cargo.toml b/gpu_renderer/Cargo.toml
index c15e6df..b331f49 100644
--- a/gpu_renderer/Cargo.toml
+++ b/gpu_renderer/Cargo.toml
@@ -6,6 +6,7 @@
 
 [features]
 virtio-gpu-next = []
+gfxstream = []
 
 [dependencies]
 data_model = { path = "../data_model" }
diff --git a/gpu_renderer/src/lib.rs b/gpu_renderer/src/lib.rs
index 9cdb5a3..ef22b34 100644
--- a/gpu_renderer/src/lib.rs
+++ b/gpu_renderer/src/lib.rs
@@ -211,6 +211,12 @@
     pub fn use_gles(self, v: bool) -> RendererFlags {
         self.set_flag(VIRGL_RENDERER_USE_GLES, v)
     }
+
+    #[cfg(feature = "gfxstream")]
+    pub fn use_syncfd(self, v: bool) -> RendererFlags {
+        const GFXSTREAM_RENDERER_FLAGS_NO_SYNCFD_BIT: u32 = 1 << 20;
+        self.set_flag(GFXSTREAM_RENDERER_FLAGS_NO_SYNCFD_BIT, !v)
+    }
 }
 
 impl From<RendererFlags> for i32 {
diff --git a/src/main.rs b/src/main.rs
index 935e714..285fb90 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -217,6 +217,21 @@
                         });
                     }
                 },
+                #[cfg(feature = "gfxstream")]
+                "syncfd" => match v {
+                    "true" | "" => {
+                        gpu_params.gfxstream_use_syncfd = true;
+                    }
+                    "false" => {
+                        gpu_params.gfxstream_use_syncfd = false;
+                    }
+                    _ => {
+                        return Err(argument::Error::InvalidValue {
+                            value: v.to_string(),
+                            expected: String::from("gpu parameter 'syncfd' should be a boolean"),
+                        });
+                    }
+                },
                 "width" => {
                     gpu_params.display_width =
                         v.parse::<u32>()
@@ -1417,6 +1432,7 @@
                                   egl[=true|=false] - If the virtio-gpu backend should use a EGL context for rendering.
                                   glx[=true|=false] - If the virtio-gpu backend should use a GLX context for rendering.
                                   surfaceless[=true|=false] - If the virtio-gpu backend should use a surfaceless context for rendering.
+                                  syncfd[=true|=false] - If the gfxstream backend should support EGL_ANDROID_native_fence_sync
                                   "),
           #[cfg(feature = "tpm")]
           Argument::flag("software-tpm", "enable a software emulated trusted platform module device"),