Statically allocate function pointer tables for libXCB

This avoids the use of dynamically allocated memory, managed by a
shared_ptr<>, which required exit-time deallocation.

Bug: b/203541908
Change-Id: I660d2f6cdf0d2194863bc12e5322d94700885ace
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/60090
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Sean Risser <srisser@google.com>
diff --git a/src/WSI/libXCB.cpp b/src/WSI/libXCB.cpp
index c540cb8..0eeed19 100644
--- a/src/WSI/libXCB.cpp
+++ b/src/WSI/libXCB.cpp
@@ -36,21 +36,21 @@
 
 LibXcbExports *LibXCB::loadExports()
 {
-	static auto exports = [] {
-		if(getProcAddress(RTLD_DEFAULT, "xcb_create_gc"))
+	static LibXcbExports exports = [] {
+		if(getProcAddress(RTLD_DEFAULT, "xcb_create_gc"))  // Search the global scope for pre-loaded XCB library.
 		{
-			return std::make_unique<LibXcbExports>(RTLD_DEFAULT);
+			return LibXcbExports(RTLD_DEFAULT);
 		}
 
 		if(void *lib = loadLibrary("libxcb.so.1"))
 		{
-			return std::make_unique<LibXcbExports>(lib);
+			return LibXcbExports(lib);
 		}
 
-		return std::unique_ptr<LibXcbExports>();
+		return LibXcbExports();
 	}();
 
-	return exports.get();
+	return exports.xcb_create_gc ? &exports : nullptr;
 }
 
 LibXCB libXCB;
diff --git a/src/WSI/libXCB.hpp b/src/WSI/libXCB.hpp
index 1e535cb..db9433c 100644
--- a/src/WSI/libXCB.hpp
+++ b/src/WSI/libXCB.hpp
@@ -19,15 +19,16 @@
 
 struct LibXcbExports
 {
+	LibXcbExports() {}
 	LibXcbExports(void *lib);
 
-	xcb_void_cookie_t (*xcb_create_gc)(xcb_connection_t *c, xcb_gcontext_t cid, xcb_drawable_t drawable, uint32_t value_mask, const void *value_list);
-	int (*xcb_flush)(xcb_connection_t *c);
-	xcb_void_cookie_t (*xcb_free_gc)(xcb_connection_t *c, xcb_gcontext_t gc);
-	uint32_t (*xcb_generate_id)(xcb_connection_t *c);
-	xcb_get_geometry_cookie_t (*xcb_get_geometry)(xcb_connection_t *c, xcb_drawable_t drawable);
-	xcb_get_geometry_reply_t *(*xcb_get_geometry_reply)(xcb_connection_t *c, xcb_get_geometry_cookie_t cookie, xcb_generic_error_t **e);
-	xcb_void_cookie_t (*xcb_put_image)(xcb_connection_t *c, uint8_t format, xcb_drawable_t drawable, xcb_gcontext_t gc, uint16_t width, uint16_t height, int16_t dst_x, int16_t dst_y, uint8_t left_pad, uint8_t depth, uint32_t data_len, const uint8_t *data);
+	xcb_void_cookie_t (*xcb_create_gc)(xcb_connection_t *c, xcb_gcontext_t cid, xcb_drawable_t drawable, uint32_t value_mask, const void *value_list) = nullptr;
+	int (*xcb_flush)(xcb_connection_t *c) = nullptr;
+	xcb_void_cookie_t (*xcb_free_gc)(xcb_connection_t *c, xcb_gcontext_t gc) = nullptr;
+	uint32_t (*xcb_generate_id)(xcb_connection_t *c) = nullptr;
+	xcb_get_geometry_cookie_t (*xcb_get_geometry)(xcb_connection_t *c, xcb_drawable_t drawable) = nullptr;
+	xcb_get_geometry_reply_t *(*xcb_get_geometry_reply)(xcb_connection_t *c, xcb_get_geometry_cookie_t cookie, xcb_generic_error_t **e) = nullptr;
+	xcb_void_cookie_t (*xcb_put_image)(xcb_connection_t *c, uint8_t format, xcb_drawable_t drawable, xcb_gcontext_t gc, uint16_t width, uint16_t height, int16_t dst_x, int16_t dst_y, uint8_t left_pad, uint8_t depth, uint32_t data_len, const uint8_t *data) = nullptr;
 };
 
 class LibXCB