Support for using external Wayland EGL Displays.

Change-Id: Ib9bdf79f853376f089fcec1fde9e62c790dc8dfa
diff --git a/src/third_party/starboard/rdk/shared/system/system_egl.cc b/src/third_party/starboard/rdk/shared/system/system_egl.cc
index 7eeb8ce..f73b2e1 100644
--- a/src/third_party/starboard/rdk/shared/system/system_egl.cc
+++ b/src/third_party/starboard/rdk/shared/system/system_egl.cc
@@ -34,8 +34,10 @@
 #include "starboard/egl.h"
 
 #include "third_party/starboard/rdk/shared/application_rdk.h"
+#include "third_party/starboard/rdk/shared/log_override.h"
 
 #include <essos-app.h>
+#include <essos-system.h>
 
 #if !defined(EGL_VERSION_1_0) || !defined(EGL_VERSION_1_1) || \
     !defined(EGL_VERSION_1_2) || !defined(EGL_VERSION_1_3) || \
@@ -45,6 +47,12 @@
 
 namespace {
 
+#ifdef EGL_PLATFORM_WAYLAND_EXT
+static PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC gEglCreatePlatformPixmapSurfaceEXT;
+static PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC gEglCreatePlatformWindowSurfaceEXT;
+static PFNEGLGETPLATFORMDISPLAYEXTPROC gEglGetPlatformDisplayEXT;
+#endif
+
 // Convenience functions that redirect to the intended function but "cast" the
 // type of the SbEglNative*Type parameter into the desired type. Depending on
 // the platform, the type of cast to use is different so either C-style casts or
@@ -61,6 +69,11 @@
                                       SbEglConfig config,
                                       SbEglNativePixmapType pixmap,
                                       const SbEglInt32* attrib_list) {
+#ifdef EGL_PLATFORM_WAYLAND_EXT
+  if (gEglCreatePlatformPixmapSurfaceEXT)
+    return gEglCreatePlatformPixmapSurfaceEXT(dpy, config, (EGLNativePixmapType)pixmap,
+                                              attrib_list);
+#endif
   return eglCreatePixmapSurface(dpy, config, (EGLNativePixmapType)pixmap,
                                 attrib_list);
 }
@@ -69,16 +82,44 @@
                                       SbEglConfig config,
                                       SbEglNativeWindowType win,
                                       const SbEglInt32* attrib_list) {
+#ifdef EGL_PLATFORM_WAYLAND_EXT
+  if (gEglCreatePlatformWindowSurfaceEXT)
+    return gEglCreatePlatformWindowSurfaceEXT(dpy, config, (EGLNativeWindowType)win,
+                                              attrib_list);
+#endif
   return eglCreateWindowSurface(dpy, config, (EGLNativeWindowType)win,
                                 attrib_list);
 }
 
 SbEglDisplay SbEglGetDisplay(SbEglNativeDisplayType display_id) {
+  SbEglDisplay result = SB_EGL_NO_DISPLAY;
   NativeDisplayType display_type;
   EssCtx *ctx = third_party::starboard::rdk::shared::Application::Get()->GetEssCtx();
-  if (EssContextGetEGLDisplayType(ctx, &display_type))
-    return eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(display_type));
-  return eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(display_id));
+
+  if (EssContextGetEGLDisplayType(ctx, &display_type) == false)
+      display_type = reinterpret_cast<NativeDisplayType>(display_id);
+
+#ifdef EGL_PLATFORM_WAYLAND_EXT
+  if (gEglGetPlatformDisplayEXT) {
+    if (EssContextGetUseWayland(ctx)) {
+      result = gEglGetPlatformDisplayEXT(EGL_PLATFORM_WAYLAND_EXT, reinterpret_cast<EGLNativeDisplayType>(display_type), nullptr);
+    }
+    if (result == SB_EGL_NO_DISPLAY) {
+      SB_LOG(ERROR) << "eglGetPlatformDisplayEXT failed, fallback to eglGetDisplay.";
+      gEglGetPlatformDisplayEXT = nullptr;
+      gEglCreatePlatformPixmapSurfaceEXT = nullptr;
+      gEglCreatePlatformWindowSurfaceEXT = nullptr;
+    }
+    else {
+      SB_LOG(INFO) << "eglGetPlatformDisplayEXT succeded, result = " << result;
+    }
+  }
+#endif
+
+  if (result == SB_EGL_NO_DISPLAY)
+    result = eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(display_type));
+
+  return result;
 }
 
 const SbEglInterface g_sb_egl_interface = {
@@ -132,5 +173,24 @@
 }  // namespace
 
 const SbEglInterface* SbGetEglInterface() {
+#ifdef EGL_PLATFORM_WAYLAND_EXT
+  gEglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
+  gEglCreatePlatformPixmapSurfaceEXT = (PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC)eglGetProcAddress("eglCreatePlatformPixmapSurfaceEXT");
+  gEglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
+  if (!gEglGetPlatformDisplayEXT || !gEglCreatePlatformPixmapSurfaceEXT || !gEglCreatePlatformWindowSurfaceEXT) {
+    if (!gEglGetPlatformDisplayEXT)
+      SB_LOG(INFO) << "eglGetPlatformDisplayEXT is not available";
+    if (!gEglCreatePlatformPixmapSurfaceEXT)
+      SB_LOG(INFO) << "eglCreatePlatformPixmapSurfaceEXT is not available";
+    if (!gEglCreatePlatformWindowSurfaceEXT)
+      SB_LOG(INFO) << "eglCreatePlatformWindowSurfaceEXT is not available";
+    gEglGetPlatformDisplayEXT = nullptr;
+    gEglCreatePlatformPixmapSurfaceEXT = nullptr;
+    gEglCreatePlatformWindowSurfaceEXT = nullptr;
+  }
+  else {
+    SB_LOG(INFO) << "Found EGL platform display extensions.";
+  }
+#endif
   return &g_sb_egl_interface;
 }