Implemented EGL_EXT_platform_base and EGL_KHR_platform_gbm.

BUG=18314459

Change-Id: I361dba91a2fec3d9c923c660e64b5cc25beeb72b
Reviewed-on: https://swiftshader-review.googlesource.com/1421
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index e6c8743..69baa9c 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -29,29 +29,43 @@
 typedef std::map<EGLNativeDisplayType, Display*> DisplayMap; 
 DisplayMap displays;
 
-egl::Display *Display::getDisplay(EGLNativeDisplayType displayId)
+egl::Display *Display::getPlatformDisplay(EGLenum platform, EGLNativeDisplayType displayId)
 {
-    if(displayId == EGL_DEFAULT_DISPLAY)
+    if(platform == EGL_UNKNOWN)   // Default
     {
         #if defined(__unix__)
-            displayId = XOpenDisplay(NULL);
+            platform = EGL_PLATFORM_X11_EXT;
         #endif
     }
 
+    if(displayId == EGL_DEFAULT_DISPLAY)
+    {
+        if(platform == EGL_PLATFORM_X11_EXT)
+        {
+            #if defined(__unix__)
+                displayId = XOpenDisplay(NULL);
+            #else
+                return error(EGL_BAD_PARAMETER, (egl::Display*)EGL_NO_DISPLAY);
+            #endif
+        }
+    }
+    else
+    {
+        // FIXME: Check if displayId is a valid display device context for <platform>
+    }
+
     if(displays.find(displayId) != displays.end())
     {
         return displays[displayId];
     }
 
-    // FIXME: Check if displayId is a valid display device context
-
-    egl::Display *display = new egl::Display(displayId);
+    egl::Display *display = new egl::Display(platform, displayId);
 
     displays[displayId] = display;
     return display;
 }
 
-Display::Display(EGLNativeDisplayType displayId) : displayId(displayId)
+Display::Display(EGLenum platform, EGLNativeDisplayType displayId) : platform(platform), displayId(displayId)
 {
     mMinSwapInterval = 1;
     mMaxSwapInterval = 1;
@@ -449,14 +463,19 @@
 
 bool Display::isValidWindow(EGLNativeWindowType window)
 {
-	#if defined(_WIN32)
-		return IsWindow(window) == TRUE;
-	#else
-		XWindowAttributes windowAttributes;
-		Status status = XGetWindowAttributes(displayId, window, &windowAttributes);
-			
-		return status == True;
+    #if defined(_WIN32)
+        return IsWindow(window) == TRUE;
+    #else
+        if(platform == EGL_PLATFORM_X11_EXT)
+        {
+            XWindowAttributes windowAttributes;
+            Status status = XGetWindowAttributes(displayId, window, &windowAttributes);
+
+            return status == True;
+        }
 	#endif
+
+    return false;
 }
 
 bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
@@ -509,19 +528,29 @@
 	
 		ReleaseDC(0, deviceContext);
 	#else
-		Screen *screen = XDefaultScreenOfDisplay(displayId);
-		displayMode.width = XWidthOfScreen(screen);
-		displayMode.height = XHeightOfScreen(screen);
-		unsigned int bpp = XPlanesOfScreen(screen);
+        if(platform == EGL_PLATFORM_X11_EXT)
+        {
+            Screen *screen = XDefaultScreenOfDisplay(displayId);
+            displayMode.width = XWidthOfScreen(screen);
+            displayMode.height = XHeightOfScreen(screen);
+            unsigned int bpp = XPlanesOfScreen(screen);
 
-		switch(bpp)
-		{
-		case 32: displayMode.format = sw::FORMAT_X8R8G8B8; break;
-		case 24: displayMode.format = sw::FORMAT_R8G8B8;   break;
-		case 16: displayMode.format = sw::FORMAT_R5G6B5;   break;
-		default:
-			ASSERT(false);   // Unexpected display mode color depth
-		}
+            switch(bpp)
+            {
+            case 32: displayMode.format = sw::FORMAT_X8R8G8B8; break;
+            case 24: displayMode.format = sw::FORMAT_R8G8B8;   break;
+            case 16: displayMode.format = sw::FORMAT_R5G6B5;   break;
+            default:
+                ASSERT(false);   // Unexpected display mode color depth
+            }
+        }
+        else if(platform == EGL_PLATFORM_GBM_MESA)
+        {
+            displayMode.width = 0;
+            displayMode.height = 0;
+            displayMode.format = sw::FORMAT_X8R8G8B8;
+        }
+        else UNREACHABLE();
 	#endif
 
 	return displayMode;
diff --git a/src/OpenGL/libEGL/Display.h b/src/OpenGL/libEGL/Display.h
index ff1d7c8..3c47853 100644
--- a/src/OpenGL/libEGL/Display.h
+++ b/src/OpenGL/libEGL/Display.h
@@ -30,7 +30,7 @@
 	public:

 		~Display();

 

-		static egl::Display *getDisplay(EGLNativeDisplayType displayId);

+		static egl::Display *getPlatformDisplay(EGLenum platform, EGLNativeDisplayType displayId);

 

 		bool initialize();

 		void terminate();

@@ -59,10 +59,11 @@
 		const char *getExtensionString() const;

 

 	private:

-		Display(EGLNativeDisplayType displayId);

+		Display(EGLenum platform, EGLNativeDisplayType displayId);

 

 		DisplayMode getDisplayMode() const;

 

+        const EGLenum platform;

 		const EGLNativeDisplayType displayId;

 

 		EGLint mMaxSwapInterval;

diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index 6f4a4c8..006005d 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -105,7 +105,7 @@
 

     try

     {

-        return egl::Display::getDisplay(display_id);

+        return egl::Display::getPlatformDisplay(EGL_UNKNOWN, display_id);

     }

     catch(std::bad_alloc&)

     {

@@ -180,7 +180,10 @@
     {

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

         {

-            return success("EGL_EXT_client_extensions");

+            return success("EGL_KHR_platform_gbm "

+                           "EGL_KHR_platform_x11 "

+                           "EGL_EXT_client_extensions "

+                           "EGL_EXT_platform_base");

         }

 

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

@@ -1191,6 +1194,32 @@
     return EGL_FALSE;

 }

 

+EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)

+{

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

+

+    try

+    {

+        return egl::Display::getPlatformDisplay(platform, (EGLNativeDisplayType)native_display);

+    }

+    catch(std::bad_alloc&)

+    {

+        return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);

+    }

+

+    return EGL_NO_DISPLAY;

+}

+

+EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)

+{

+    return eglCreateWindowSurface(dpy, config, (EGLNativeWindowType)native_window, attrib_list);

+}

+

+EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)

+{

+    return eglCreatePixmapSurface(dpy, config, (EGLNativePixmapType)native_pixmap, attrib_list);

+}

+

 __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)

 {

     TRACE("(const char *procname = \"%s\")", procname);

@@ -1209,6 +1238,9 @@
 

 			EXTENSION(eglCreateImageKHR),

 			EXTENSION(eglDestroyImageKHR),

+            EXTENSION(eglGetPlatformDisplayEXT),

+            EXTENSION(eglCreatePlatformWindowSurfaceEXT),

+            EXTENSION(eglCreatePlatformPixmapSurfaceEXT),

 

 			#undef EXTENSION

 		};

diff --git a/src/OpenGL/libEGL/libEGL.def b/src/OpenGL/libEGL/libEGL.def
index 4555d71..e9293a9 100644
--- a/src/OpenGL/libEGL/libEGL.def
+++ b/src/OpenGL/libEGL/libEGL.def
@@ -1,44 +1,47 @@
-LIBRARY	libEGL
-EXPORTS
-	eglBindAPI                      @14
-	eglBindTexImage                 @20
-	eglChooseConfig                 @7
-	eglCopyBuffers                  @33
-	eglCreateContext                @23
-	eglCreatePbufferFromClientBuffer        @18
-	eglCreatePbufferSurface         @10
-	eglCreatePixmapSurface          @11
-	eglCreateWindowSurface          @9
-	eglDestroyContext               @24
-	eglDestroySurface               @12
-	eglGetConfigAttrib              @8
-	eglGetConfigs                   @6
-	eglGetCurrentContext            @26
-	eglGetCurrentDisplay            @28
-	eglGetCurrentSurface            @27
-	eglGetDisplay                   @2
-	eglGetError                     @1
-	eglGetProcAddress               @34
-	eglInitialize                   @3
-	eglMakeCurrent                  @25
-	eglQueryAPI                     @15
-	eglQueryContext                 @29
-	eglQueryString                  @5
-	eglQuerySurface                 @13
-	eglReleaseTexImage              @21
-	eglReleaseThread                @17
-	eglSurfaceAttrib                @19
-	eglSwapBuffers                  @32
-	eglSwapInterval                 @22
-	eglTerminate                    @4
-	eglWaitClient                   @16
-	eglWaitGL                       @30
-	eglWaitNative                   @31
-
-	; Extensions
-	eglCreateImageKHR
-	eglDestroyImageKHR
-
-	; Functions that don't change the error code, for use by client APIs
-	clientGetCurrentContext
+LIBRARY	libEGL

+EXPORTS

+	eglBindAPI                      @14

+	eglBindTexImage                 @20

+	eglChooseConfig                 @7

+	eglCopyBuffers                  @33

+	eglCreateContext                @23

+	eglCreatePbufferFromClientBuffer        @18

+	eglCreatePbufferSurface         @10

+	eglCreatePixmapSurface          @11

+	eglCreateWindowSurface          @9

+	eglDestroyContext               @24

+	eglDestroySurface               @12

+	eglGetConfigAttrib              @8

+	eglGetConfigs                   @6

+	eglGetCurrentContext            @26

+	eglGetCurrentDisplay            @28

+	eglGetCurrentSurface            @27

+	eglGetDisplay                   @2

+	eglGetError                     @1

+	eglGetProcAddress               @34

+	eglInitialize                   @3

+	eglMakeCurrent                  @25

+	eglQueryAPI                     @15

+	eglQueryContext                 @29

+	eglQueryString                  @5

+	eglQuerySurface                 @13

+	eglReleaseTexImage              @21

+	eglReleaseThread                @17

+	eglSurfaceAttrib                @19

+	eglSwapBuffers                  @32

+	eglSwapInterval                 @22

+	eglTerminate                    @4

+	eglWaitClient                   @16

+	eglWaitGL                       @30

+	eglWaitNative                   @31

+

+	; Extensions

+	eglCreateImageKHR

+	eglDestroyImageKHR

+	eglGetPlatformDisplayEXT

+    eglCreatePlatformWindowSurfaceEXT

+    eglCreatePlatformPixmapSurfaceEXT

+

+	; Functions that don't change the error code, for use by client APIs

+	clientGetCurrentContext

 	clientGetCurrentDisplay
\ No newline at end of file