Reland "Properly report xcb_connect failures in DisplayVkXcb"

This is a reland of 81bee2e7f6deeda15691dd0b7fca90626b66bfb8

Changes for the reland:
Do not attempt to use Xcb if DISPLAY is not defined - for headless ozone.

Original change's description:
> Properly report xcb_connect failures in DisplayVkXcb
>
> Bug: chromium:1223431
> Change-Id: Iaefddbda3fef283eed365fe010ee003a3b3beca8
> Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3083383
> Reviewed-by: Jamie Madill <jmadill@chromium.org>
> Commit-Queue: Yuly Novikov <ynovikov@chromium.org>

Bug: chromium:1223431
Change-Id: I19be7d10cbd3692e1de6458bc0e2db5996a755af
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3099674
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Yuly Novikov <ynovikov@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.cpp b/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.cpp
index 2b3ec8f..7107895 100644
--- a/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.cpp
+++ b/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.cpp
@@ -43,29 +43,42 @@
 }  // namespace
 
 DisplayVkXcb::DisplayVkXcb(const egl::DisplayState &state)
-    : DisplayVk(state), mXcbConnection(nullptr)
+    : DisplayVk(state), mXcbConnection(nullptr), mHasXDisplay(false)
 {}
 
 egl::Error DisplayVkXcb::initialize(egl::Display *display)
 {
-    mXcbConnection = xcb_connect(nullptr, nullptr);
-    if (mXcbConnection == nullptr)
+    mHasXDisplay = !angle::GetEnvironmentVar("DISPLAY").empty();
+    if (mHasXDisplay)
     {
-        return egl::EglNotInitialized();
+        mXcbConnection = xcb_connect(nullptr, nullptr);
+        ASSERT(mXcbConnection != nullptr);
+        int xcb_connection_error = xcb_connection_has_error(mXcbConnection);
+        if (xcb_connection_error)
+        {
+            ERR() << "xcb_connect() failed, error " << xcb_connection_error;
+            xcb_disconnect(mXcbConnection);
+            mXcbConnection = nullptr;
+            return egl::EglNotInitialized();
+        }
     }
     return DisplayVk::initialize(display);
 }
 
 void DisplayVkXcb::terminate()
 {
-    ASSERT(mXcbConnection != nullptr);
-    xcb_disconnect(mXcbConnection);
-    mXcbConnection = nullptr;
+    if (mHasXDisplay)
+    {
+        ASSERT(mXcbConnection != nullptr);
+        xcb_disconnect(mXcbConnection);
+        mXcbConnection = nullptr;
+    }
     DisplayVk::terminate();
 }
 
 bool DisplayVkXcb::isValidNativeWindow(EGLNativeWindowType window) const
 {
+    ASSERT(mHasXDisplay);
     // There doesn't appear to be an xcb function explicitly for checking the validity of a
     // window ID, but xcb_query_tree_reply will return nullptr if the window doesn't exist.
     xcb_query_tree_cookie_t cookie =
@@ -82,6 +95,7 @@
 SurfaceImpl *DisplayVkXcb::createWindowSurfaceVk(const egl::SurfaceState &state,
                                                  EGLNativeWindowType window)
 {
+    ASSERT(mHasXDisplay);
     return new WindowSurfaceVkXcb(state, window, mXcbConnection);
 }
 
@@ -104,8 +118,7 @@
 void DisplayVkXcb::checkConfigSupport(egl::Config *config)
 {
     // If no window system, cannot support windows.
-    static bool sNoX11Display = angle::GetEnvironmentVar("DISPLAY").empty();
-    if (sNoX11Display)
+    if (!mHasXDisplay)
     {
         // No window support if no X11.
         config->surfaceType &= ~EGL_WINDOW_BIT;
diff --git a/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h b/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h
index 01559b9..54eea5c 100644
--- a/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h
+++ b/src/libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h
@@ -38,6 +38,10 @@
 
   private:
     xcb_connection_t *mXcbConnection;
+    // If there is no X Display, obviously it's impossible to connect to it with Xcb,
+    // so rendering to windows is not supported, but rendering to pbuffers is still supported.
+    // This mode is used in headless ozone testing.
+    bool mHasXDisplay;
 };
 
 }  // namespace rx