devcontainer: use VirtualGL on mac hosts
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 0e5e97316d53db..a24c524047c345 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,8 +1,13 @@
 FROM ghcr.io/commaai/openpilot-base:latest
 
-RUN apt update && apt install -y vim net-tools usbutils htop ripgrep tmux
+RUN apt update && apt install -y vim net-tools usbutils htop ripgrep tmux wget mesa-utils xvfb libxtst6 libxv1 libglu1-mesa libegl1-mesa
 RUN pip install ipython jupyter jupyterlab
 
+RUN cd /tmp && \
+    ARCH=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) && \
+    curl -L -o virtualgl.deb "https://downloads.sourceforge.net/project/virtualgl/3.1/virtualgl_3.1_$ARCH.deb" && \
+    dpkg -i virtualgl.deb
+
 USER batman
 
 RUN cd $HOME && \
diff --git a/.devcontainer/container_post_create.sh b/.devcontainer/container_post_create.sh
index b6202b3cbdef11..dee1c611018bad 100755
--- a/.devcontainer/container_post_create.sh
+++ b/.devcontainer/container_post_create.sh
@@ -3,17 +3,34 @@
 TARGET_USER=batman
 source .devcontainer/.host/.env
 
-# override display flag for mac
+# override display flag for mac hosts
 if [[ $HOST_OS == darwin ]]; then
   echo "Setting up DISPLAY override for macOS..."
   cat <<EOF >> /home/$TARGET_USER/.bashrc
-if [ -n "\$DISPLAY" ]; then
-  DISPLAY_NUM=\$(echo "\$DISPLAY" | awk -F: '{print \$NF}')
+source .devcontainer/.host/.env
+if [ -n "\$HOST_DISPLAY" ]; then
+  DISPLAY_NUM=\$(echo "\$HOST_DISPLAY" | awk -F: '{print \$NF}')
   export DISPLAY=host.docker.internal:\$DISPLAY_NUM
 fi
 EOF
 fi
 
+# setup virtualgl for mac hosts
+if [[ $HOST_OS == darwin ]]; then
+  echo "Setting up virtualgl for macOS..."
+  cat <<EOF >> /home/$TARGET_USER/.bashrc
+if [ -n "\$HOST_DISPLAY" ]; then
+  export VGL_PORT=10000
+  export VGL_CLIENT=host.docker.internal
+  export VGL_COMPRESS=rgb
+  export VGL_DISPLAY=:99
+  export VGL_FPS=60
+  # prevent vglrun from running exec
+  alias exec=:; source vglrun :; unalias exec
+fi
+EOF
+fi
+
 # These lines are temporary, to remain backwards compatible with old devcontainers
 # that were running as root and therefore had their caches written as root
 sudo chown -R $TARGET_USER: /tmp/scons_cache
diff --git a/.devcontainer/container_post_start.sh b/.devcontainer/container_post_start.sh
index 4404f6a9a99973..1521b9c3fb4c30 100755
--- a/.devcontainer/container_post_start.sh
+++ b/.devcontainer/container_post_start.sh
@@ -1,7 +1,15 @@
 #!/usr/bin/env bash
 
+source .devcontainer/.host/.env
+
 # setup safe directories for submodules
 SUBMODULE_DIRS=$(git config --file .gitmodules --get-regexp path | awk '{ print $2 }')
 for DIR in $SUBMODULE_DIRS; do 
   git config --global --add safe.directory "$PWD/$DIR"
 done
+
+# virtual display for virtualgl
+if [[ "$HOST_OS" == "darwin" ]] && [[ -n "$HOST_DISPLAY" ]]; then
+  echo "Starting virtual display at :99 ..."
+  tmux new-session -d -s fakedisplay Xvfb :99 -screen 0 1920x1080x24
+fi
diff --git a/.devcontainer/host_setup.sh b/.devcontainer/host_setup.sh
index b3119185a464c0..8ff81ebe421b6b 100755
--- a/.devcontainer/host_setup.sh
+++ b/.devcontainer/host_setup.sh
@@ -2,6 +2,7 @@
 
 # pull base image
 if [[ -z $USE_LOCAL_IMAGE ]]; then
+  echo "Updating openpilot_base image if needed..."
   docker pull ghcr.io/commaai/openpilot-base:latest
 fi
 
@@ -27,3 +28,20 @@ fi
 HOST_INFO_FILE=".devcontainer/.host/.env"
 SYSTEM=$(uname -s | tr '[:upper:]' '[:lower:]')
 echo "HOST_OS=\"$SYSTEM\"" > $HOST_INFO_FILE
+echo "HOST_DISPLAY=\"$DISPLAY\"" >> $HOST_INFO_FILE
+
+# run virtualgl if macos
+if [[ $SYSTEM == "darwin" ]]; then
+  echo
+  if [[ -f /opt/VirtualGL/bin/vglclient ]]; then
+    echo "Starting VirtualGL client at port 10000..."
+    VGL_LOG_FILE=".devcontainer/.host/.vgl/vglclient.log"
+    mkdir -p "$(dirname $VGL_LOG_FILE)"
+    /opt/VirtualGL/bin/vglclient -l "$VGL_LOG_FILE" -display "$DISPLAY" -port 10000 -detach
+  else
+    echo "VirtualGL not found. GUI tools may not work properly. Some GUI tools require OpenGL to work properly. To use them with XQuartz on mac, VirtualGL needs to be installed. To install it run:"
+    echo
+    echo "  brew install --cask virtualgl"
+    echo
+  fi
+fi

Use VirtualGL to force direct rendering of OpenGL (as opposed to indirect rendering which happens by default while forwarding X with XQuartz). This should cameraview in selfdrive/ui/ui and tools like plotjuggler/cabana. 