Merge "Avoid running graphics detector N times for --num_instances=N" into main
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index e749638..078a8b6 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -1350,6 +1350,9 @@
     mutable_env_config.set_start_wmediumd(false);
   }
 
+  const auto graphics_availability =
+      GetGraphicsAvailabilityWithSubprocessCheck();
+
   // Instance specific configs
   bool is_first_instance = true;
   int instance_index = 0;
@@ -1599,7 +1602,8 @@
 
     // gpu related settings
     const std::string gpu_mode = CF_EXPECT(ConfigureGpuSettings(
-        gpu_mode_vec[instance_index], gpu_vhost_user_mode_vec[instance_index],
+        graphics_availability, gpu_mode_vec[instance_index],
+        gpu_vhost_user_mode_vec[instance_index],
         gpu_renderer_features_vec[instance_index],
         gpu_context_types_vec[instance_index], vmm_mode,
         guest_configs[instance_index], instance));
diff --git a/host/commands/assemble_cvd/graphics_flags.cc b/host/commands/assemble_cvd/graphics_flags.cc
index d843f51..c4275aa 100644
--- a/host/commands/assemble_cvd/graphics_flags.cc
+++ b/host/commands/assemble_cvd/graphics_flags.cc
@@ -352,25 +352,6 @@
   return CF_ERR("Graphics detector unavailable for host arch.");
 }
 
-CF_UNUSED_ON_MACOS
-Result<const gfxstream::proto::GraphicsAvailability>
-GetGraphicsAvailabilityWithSubprocessCheck() {
-  Command graphics_detector_cmd(CF_EXPECT(GraphicsDetectorBinaryPath()));
-  std::string graphics_detector_stdout;
-  auto ret = RunWithManagedStdio(std::move(graphics_detector_cmd), nullptr,
-                                 &graphics_detector_stdout, nullptr);
-  CF_EXPECT_EQ(ret, 0, "Failed to run graphics detector, bad return value");
-
-  gfxstream::proto::GraphicsAvailability availability;
-  google::protobuf::TextFormat::Parser parser;
-  if (!parser.ParseFromString(graphics_detector_stdout, &availability)) {
-    return CF_ERR("Failed to parse graphics detector stdout: "
-                  << graphics_detector_stdout);
-  }
-
-  return availability;
-}
-
 bool IsAmdGpu(const gfxstream::proto::GraphicsAvailability& availability) {
   return (availability.has_egl() &&
           ((availability.egl().has_gles2_availability() &&
@@ -481,18 +462,57 @@
   return {};
 }
 
-}  // namespace
-
 static std::unordered_set<std::string> kSupportedGpuContexts{
     "gfxstream-vulkan", "gfxstream-composer", "cross-domain", "magma"};
 
+}  // namespace
+
+gfxstream::proto::GraphicsAvailability
+GetGraphicsAvailabilityWithSubprocessCheck() {
+#ifdef __APPLE__
+  return {};
+#else
+  auto graphics_detector_binary_result = GraphicsDetectorBinaryPath();
+  if (!graphics_detector_binary_result.ok()) {
+    LOG(ERROR) << "Failed to run graphics detector, graphics detector path "
+               << " not available: "
+               << graphics_detector_binary_result.error().FormatForEnv()
+               << ". Assuming no availability.";
+    return {};
+  }
+
+  Command graphics_detector_cmd(graphics_detector_binary_result.value());
+  std::string graphics_detector_stdout;
+  auto ret = RunWithManagedStdio(std::move(graphics_detector_cmd), nullptr,
+                                 &graphics_detector_stdout, nullptr);
+  if (ret != 0) {
+    LOG(ERROR) << "Failed to run graphics detector, bad return value: " << ret
+               << ". Assuming no availability.";
+    return {};
+  }
+
+  gfxstream::proto::GraphicsAvailability availability;
+  google::protobuf::TextFormat::Parser parser;
+  if (!parser.ParseFromString(graphics_detector_stdout, &availability)) {
+    LOG(ERROR) << "Failed to parse graphics detector stdout: "
+               << graphics_detector_stdout << ". Assuming no availability.";
+    return {};
+  }
+
+  LOG(DEBUG) << "Host Graphics Availability:" << availability.DebugString();
+  return availability;
+#endif
+}
+
 Result<std::string> ConfigureGpuSettings(
+    const gfxstream::proto::GraphicsAvailability& graphics_availability,
     const std::string& gpu_mode_arg, const std::string& gpu_vhost_user_mode_arg,
     const std::string& gpu_renderer_features_arg,
     std::string& gpu_context_types_arg, VmmMode vmm,
     const GuestConfig& guest_config,
     CuttlefishConfig::MutableInstanceSpecific& instance) {
 #ifdef __APPLE__
+  (void)graphics_availability;
   (void)gpu_vhost_user_mode_arg;
   (void)vmm;
   (void)guest_config;
@@ -506,20 +526,6 @@
   instance.set_gpu_mode(gpu_mode);
   instance.set_enable_gpu_vhost_user(false);
 #else
-  gfxstream::proto::GraphicsAvailability graphics_availability;
-
-  auto graphics_availability_result =
-      GetGraphicsAvailabilityWithSubprocessCheck();
-  if (!graphics_availability_result.ok()) {
-    LOG(ERROR) << "Failed to get graphics availability: "
-               << graphics_availability_result.error().Message()
-               << ". Assuming none.";
-  } else {
-    graphics_availability = graphics_availability_result.value();
-    LOG(DEBUG) << "Host Graphics Availability:"
-               << graphics_availability.DebugString();
-  }
-
   const std::string gpu_mode = CF_EXPECT(
       SelectGpuMode(gpu_mode_arg, vmm, guest_config, graphics_availability));
   const bool enable_gpu_vhost_user =
diff --git a/host/commands/assemble_cvd/graphics_flags.h b/host/commands/assemble_cvd/graphics_flags.h
index 8329724..f5d1ce8 100644
--- a/host/commands/assemble_cvd/graphics_flags.h
+++ b/host/commands/assemble_cvd/graphics_flags.h
@@ -17,6 +17,8 @@
 
 #include <string>
 
+#include <GraphicsDetector.pb.h>
+
 #include "common/libs/utils/result.h"
 #include "host/commands/assemble_cvd/flags.h"
 #include "host/libs/config/config_utils.h"
@@ -24,7 +26,11 @@
 
 namespace cuttlefish {
 
+gfxstream::proto::GraphicsAvailability
+GetGraphicsAvailabilityWithSubprocessCheck();
+
 Result<std::string> ConfigureGpuSettings(
+    const gfxstream::proto::GraphicsAvailability& graphics_availability,
     const std::string& gpu_mode_arg, const std::string& gpu_vhost_user_mode_arg,
     const std::string& gpu_renderer_features_arg,
     std::string& gpu_context_types_arg, VmmMode vmm,