Statically allocate one EGL display.

This reduces support to EGL_DEFAULT_DISPLAY or assumes the
native display handle corresponds with the default display.

Bug 24600445

Change-Id: Ieb5d08beceff1cc46557483e1bed159dd9ab1bee
Reviewed-on: https://swiftshader-review.googlesource.com/4520
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index 88dcb82..e311662 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -26,7 +26,7 @@
 #include <sys/ioctl.h>
 #include <linux/fb.h>
 #include <fcntl.h>
-#elif defined(__unix__)
+#elif defined(__linux__)
 #include "Main/libX11.hpp"
 #elif defined(__APPLE__)
 #include "OSXUtils.hpp"
@@ -39,66 +39,29 @@
 namespace egl
 {
 
-egl::Display *Display::getPlatformDisplay(EGLenum platform, void *nativeDisplay)
+Display *Display::get(EGLDisplay dpy)
 {
-    #ifndef __ANDROID__
-        if(platform == EGL_UNKNOWN)   // Default platform
-        {
-            #if defined(__unix__)
-				if(libX11)
-				{
-					platform = EGL_PLATFORM_X11_EXT;
-				}
-				else
-				{
-					platform = EGL_PLATFORM_GBM_KHR;
-				}
-            #endif
-        }
-
-        if(!nativeDisplay)   // Default display
-        {
-            if(platform == EGL_PLATFORM_X11_EXT)
-            {
-                #if defined(__unix__)
-					if(libX11->XOpenDisplay)
-					{
-						nativeDisplay = libX11->XOpenDisplay(NULL);
-					}
-					else
-					{
-						return error(EGL_BAD_PARAMETER, (egl::Display*)EGL_NO_DISPLAY);
-					}
-                #else
-                    return error(EGL_BAD_PARAMETER, (egl::Display*)EGL_NO_DISPLAY);
-                #endif
-            }
-        }
-        else
-        {
-            // FIXME: Check if nativeDisplay is a valid display device context for <platform>
-        }
-    #endif
-
-	static std::map<void*, Display*> displays;
-	static sw::BackoffLock displaysMutex;
-
-	displaysMutex.lock();
-
-    egl::Display *display = displays[nativeDisplay];
-
-    if(!display)
+	if(dpy != (EGLDisplay)1)   // We only support the default display
 	{
-        display = new egl::Display(platform, nativeDisplay);
-        displays[nativeDisplay] = display;
-    }
+		return nullptr;
+	}
 
-    displaysMutex.unlock();
+	static void *nativeDisplay = nullptr;
 
-    return display;
+	#if defined(__linux__) && !defined(__ANDROID__)
+		// Even if the application provides a native display handle, we open (and close) our own connection
+		if(!nativeDisplay && libX11->XOpenDisplay)
+		{
+			nativeDisplay = libX11->XOpenDisplay(NULL);
+		}
+	#endif
+
+	static Display display(nativeDisplay);
+
+	return &display;
 }
 
-Display::Display(EGLenum platform, void *nativeDisplay) : platform(platform), nativeDisplay(nativeDisplay)
+Display::Display(void *nativeDisplay) : nativeDisplay(nativeDisplay)
 {
     mMinSwapInterval = 1;
     mMaxSwapInterval = 1;
@@ -107,6 +70,13 @@
 Display::~Display()
 {
     terminate();
+
+	#if defined(__linux__) && !defined(__ANDROID__)
+		if(nativeDisplay && libX11->XCloseDisplay)
+		{
+			libX11->XCloseDisplay((::Display*)nativeDisplay);
+		}
+	#endif
 }
 
 static void cpuid(int registers[4], int info)
@@ -545,7 +515,7 @@
 		}
 		return true;
     #elif defined(__linux__)
-        if(platform == EGL_PLATFORM_X11_EXT)
+        if(nativeDisplay)
         {
             XWindowAttributes windowAttributes;
             Status status = libX11->XGetWindowAttributes((::Display*)nativeDisplay, window, &windowAttributes);
@@ -669,7 +639,7 @@
 		// No framebuffer device found, or we're in user space
 		return sw::FORMAT_X8B8G8R8;
     #elif defined(__linux__)
-        if(platform == EGL_PLATFORM_X11_EXT)
+        if(nativeDisplay)
         {
             Screen *screen = libX11->XDefaultScreenOfDisplay((::Display*)nativeDisplay);
             unsigned int bpp = libX11->XPlanesOfScreen(screen);
@@ -682,11 +652,10 @@
             default: UNREACHABLE(bpp);   // Unexpected display mode color depth
             }
         }
-        else if(platform == EGL_PLATFORM_GBM_MESA)
+        else
         {
             return sw::FORMAT_X8R8G8B8;
         }
-        else UNREACHABLE(platform);
     #elif defined(__APPLE__)
         return sw::FORMAT_A8B8G8R8;
     #else
diff --git a/src/OpenGL/libEGL/Display.h b/src/OpenGL/libEGL/Display.h
index da1b442..84dcce1 100644
--- a/src/OpenGL/libEGL/Display.h
+++ b/src/OpenGL/libEGL/Display.h
@@ -28,7 +28,7 @@
 	class Display

 	{

 	public:

-		static egl::Display *getPlatformDisplay(EGLenum platform, void *nativeDisplay);

+		static Display *get(EGLDisplay dpy);

 

 		bool initialize();

 		void terminate();

@@ -57,12 +57,11 @@
 		const char *getExtensionString() const;

 

 	private:

-		Display(EGLenum platform, void *nativeDisplay);

+		explicit Display(void *nativeDisplay);

 		~Display();

 

 		sw::Format getDisplayFormat() const;

 

-        const EGLenum platform;

 		void *const nativeDisplay;

 

 		EGLint mMaxSwapInterval;

diff --git a/src/OpenGL/libEGL/Surface.cpp b/src/OpenGL/libEGL/Surface.cpp
index db189b2..f8d0ac8 100644
--- a/src/OpenGL/libEGL/Surface.cpp
+++ b/src/OpenGL/libEGL/Surface.cpp
@@ -23,7 +23,7 @@
 #include "common/debug.h"

 #include "Main/FrameBuffer.hpp"

 

-#if defined(__unix__) && !defined(__ANDROID__)

+#if defined(__linux__) && !defined(__ANDROID__)

 #include "Main/libX11.hpp"

 #elif defined(_WIN32)

 #include <tchar.h>

diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index 8e951c6..0f44287 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -22,6 +22,8 @@
 

 #if defined(__ANDROID__)

 #include <system/window.h>

+#elif defined(__linux__)

+#include "Main/libX11.hpp"

 #endif

 

 #include <string.h>

@@ -108,14 +110,12 @@
 {

 	TRACE("(EGLNativeDisplayType display_id = %p)", display_id);

 

-	if(display_id == EGL_DEFAULT_DISPLAY)

+	if(display_id != EGL_DEFAULT_DISPLAY)

 	{

-		return egl::Display::getPlatformDisplay(EGL_UNKNOWN, nullptr);

+		// FIXME: Check if display_id is the default display

 	}

-	else

-	{

-		return egl::Display::getPlatformDisplay(EGL_UNKNOWN, reinterpret_cast<void*>((uintptr_t)display_id));

-	}

+

+	return success((EGLDisplay)1);   // We only support the default display

 }

 

 EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)

@@ -128,7 +128,7 @@
 		return error(EGL_BAD_DISPLAY, EGL_FALSE);

 	}

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!display->initialize())

 	{

@@ -150,7 +150,7 @@
 		return error(EGL_BAD_DISPLAY, EGL_FALSE);

 	}

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	display->terminate();

 

@@ -161,15 +161,17 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLint name = %d)", dpy, name);

 

-	if(dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)

-	{

-		return success("EGL_KHR_platform_gbm "

-		               "EGL_KHR_platform_x11 "

-		               "EGL_EXT_client_extensions "

-		               "EGL_EXT_platform_base");

-	}

+	#if defined(__linux__) && !defined(__ANDROID__)

+		if(dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)

+		{

+			return success("EGL_KHR_platform_gbm "

+			               "EGL_KHR_platform_x11 "

+			               "EGL_EXT_client_extensions "

+			               "EGL_EXT_platform_base");

+		}

+	#endif

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!validateDisplay(display))

 	{

@@ -203,7 +205,7 @@
 		  "EGLint config_size = %d, EGLint *num_config = %p)",

 		  dpy, configs, config_size, num_config);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!validateDisplay(display))

 	{

@@ -231,7 +233,7 @@
 		  "EGLConfig *configs = %p, EGLint config_size = %d, EGLint *num_config = %p)",

 		  dpy, attrib_list, configs, config_size, num_config);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!validateDisplay(display))

 	{

@@ -263,7 +265,7 @@
 	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLint attribute = %d, EGLint *value = %p)",

 		  dpy, config, attribute, value);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!validateConfig(display, config))

 	{

@@ -283,7 +285,7 @@
 	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativeWindowType win = %p, "

 		  "const EGLint *attrib_list = %p)", dpy, config, window, attrib_list);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!validateConfig(display, config))

 	{

@@ -303,7 +305,7 @@
 	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, const EGLint *attrib_list = %p)",

 		  dpy, config, attrib_list);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!validateConfig(display, config))

 	{

@@ -318,7 +320,7 @@
 	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativePixmapType pixmap = %p, "

 		  "const EGLint *attrib_list = %p)", dpy, config, pixmap, attrib_list);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!validateConfig(display, config))

 	{

@@ -334,7 +336,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);

 

 	if(!validateSurface(display, eglSurface))

@@ -357,7 +359,7 @@
 	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint *value = %p)",

 		  dpy, surface, attribute, value);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Surface *eglSurface = (egl::Surface*)surface;

 

 	if(!validateSurface(display, eglSurface))

@@ -493,7 +495,7 @@
 	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint value = %d)",

 		  dpy, surface, attribute, value);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);

 

 	if(!validateSurface(display, eglSurface))

@@ -528,7 +530,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);

 

 	if(!validateSurface(display, eglSurface))

@@ -570,7 +572,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);

 

 	if(!validateSurface(display, eglSurface))

@@ -607,7 +609,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLint interval = %d)", dpy, interval);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!validateDisplay(display))

 	{

@@ -647,7 +649,7 @@
 		}

 	}

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Context *shareContext = static_cast<egl::Context*>(share_context);

 

 	if(!validateConfig(display, config))

@@ -667,7 +669,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p)", dpy, ctx);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Context *context = static_cast<egl::Context*>(ctx);

 

 	if(!validateContext(display, context))

@@ -690,7 +692,7 @@
 	TRACE("(EGLDisplay dpy = %p, EGLSurface draw = %p, EGLSurface read = %p, EGLContext ctx = %p)",

 		  dpy, draw, read, ctx);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Context *context = static_cast<egl::Context*>(ctx);

 	egl::Surface *drawSurface = static_cast<egl::Surface*>(draw);

 	egl::Surface *readSurface = static_cast<egl::Surface*>(read);

@@ -785,7 +787,7 @@
 	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLint attribute = %d, EGLint *value = %p)",

 		  dpy, ctx, attribute, value);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Context *context = static_cast<egl::Context*>(ctx);

 

 	if(!validateContext(display, context))

@@ -820,7 +822,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Surface *eglSurface = (egl::Surface*)surface;

 

 	if(!validateSurface(display, eglSurface))

@@ -842,7 +844,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLNativePixmapType target = %p)", dpy, surface, target);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);

 

 	if(!validateSurface(display, eglSurface))

@@ -859,7 +861,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLenum target = 0x%X, buffer = %p, const EGLint attrib_list = %p)", dpy, ctx, target, buffer, attrib_list);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	egl::Context *context = static_cast<egl::Context*>(ctx);

 

 	if(!validateDisplay(display))

@@ -941,7 +943,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLImageKHR image = %p)", dpy, image);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!validateDisplay(display))

 	{

@@ -963,7 +965,39 @@
 {

 	TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLint *attrib_list = %p)", platform, native_display, attrib_list);

 

-	return egl::Display::getPlatformDisplay(platform, native_display);

+	switch(platform)

+	{

+	#if defined(__linux__) && !defined(__ANDROID__)

+	case EGL_PLATFORM_X11_EXT: break;

+	case EGL_PLATFORM_GBM_KHR: break;

+	#endif

+	default:

+		return error(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);

+	}

+

+	#if defined(__linux__) && !defined(__ANDROID__)

+		if(platform == EGL_PLATFORM_X11_EXT)

+		{

+			if(!libX11)

+			{

+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);

+			}

+

+			if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)

+			{

+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);   // Unimplemented

+			}

+		}

+		else if(platform == EGL_PLATFORM_GBM_KHR)

+		{

+			if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)

+			{

+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);   // Unimplemented

+			}

+		}

+	#endif

+

+	return success((EGLDisplay)1);   // We only support the default display

 }

 

 EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)

@@ -1004,7 +1038,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLunum type = %x, EGLint *attrib_list=%p)", dpy, type, attrib_list);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!validateDisplay(display))

 	{

@@ -1035,7 +1069,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p)", dpy, sync);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	FenceSync *eglSync = static_cast<FenceSync*>(sync);

 

 	if(!validateDisplay(display))

@@ -1052,7 +1086,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint flags = %x, EGLTimeKHR value = %llx)", dpy, sync, flags, timeout);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 	FenceSync *eglSync = static_cast<FenceSync*>(sync);

 

 	if(!validateDisplay(display))

@@ -1075,7 +1109,7 @@
 {

 	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLint *value = %p)", dpy, sync, attribute, value);

 

-	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Display *display = egl::Display::get(dpy);

 

 	if(!validateDisplay(display))

 	{