[WPE] Add some error reporting during EGL display/context creation
authoraperez@igalia.com <aperez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Nov 2017 18:55:57 +0000 (18:55 +0000)
committeraperez@igalia.com <aperez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Nov 2017 18:55:57 +0000 (18:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=178937

Reviewed by Carlos Alberto Lopez Perez.

Unconditionally log errors using WTFLogAlways during EGL context creation. This
provides a small degree of help for troubleshooting, and while eglGetError() only
returns numeric error codes, it's better than nothing.

No new tests needed.

* platform/graphics/PlatformDisplay.cpp:
(WebCore::PlatformDisplay::initializeEGLDisplay):
* platform/graphics/egl/GLContextEGL.cpp:
(WebCore::GLContextEGL::errorString):
(WebCore::GLContextEGL::lastErrorString):
(WebCore::GLContextEGL::createWindowContext):
(WebCore::GLContextEGL::createPbufferContext):
(WebCore::GLContextEGL::createSurfacelessContext):
(WebCore::GLContextEGL::createContext):
(WebCore::GLContextEGL::createSharingContext):
(WebCore::GLContextEGL::GLContextEGL):
* platform/graphics/egl/GLContextEGL.h:
* platform/graphics/egl/GLContextEGLWPE.cpp:
(WebCore::GLContextEGL::createWPEContext):
* platform/graphics/wpe/PlatformDisplayWPE.cpp:
(WebCore::PlatformDisplayWPE::initialize):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224347 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/PlatformDisplay.cpp
Source/WebCore/platform/graphics/egl/GLContextEGL.cpp
Source/WebCore/platform/graphics/egl/GLContextEGL.h
Source/WebCore/platform/graphics/egl/GLContextEGLWPE.cpp
Source/WebCore/platform/graphics/wpe/PlatformDisplayWPE.cpp

index 684a022..49c8d80 100644 (file)
@@ -1,3 +1,33 @@
+2017-11-02  Adrian Perez de Castro  <aperez@igalia.com>
+
+        [WPE] Add some error reporting during EGL display/context creation
+        https://bugs.webkit.org/show_bug.cgi?id=178937
+
+        Reviewed by Carlos Alberto Lopez Perez.
+
+        Unconditionally log errors using WTFLogAlways during EGL context creation. This
+        provides a small degree of help for troubleshooting, and while eglGetError() only
+        returns numeric error codes, it's better than nothing.
+
+        No new tests needed.
+
+        * platform/graphics/PlatformDisplay.cpp:
+        (WebCore::PlatformDisplay::initializeEGLDisplay):
+        * platform/graphics/egl/GLContextEGL.cpp:
+        (WebCore::GLContextEGL::errorString):
+        (WebCore::GLContextEGL::lastErrorString):
+        (WebCore::GLContextEGL::createWindowContext):
+        (WebCore::GLContextEGL::createPbufferContext):
+        (WebCore::GLContextEGL::createSurfacelessContext):
+        (WebCore::GLContextEGL::createContext):
+        (WebCore::GLContextEGL::createSharingContext):
+        (WebCore::GLContextEGL::GLContextEGL):
+        * platform/graphics/egl/GLContextEGL.h:
+        * platform/graphics/egl/GLContextEGLWPE.cpp:
+        (WebCore::GLContextEGL::createWPEContext):
+        * platform/graphics/wpe/PlatformDisplayWPE.cpp:
+        (WebCore::PlatformDisplayWPE::initialize):
+
 2017-11-02  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Move InspectorAgents into a folder
index 59898d6..6314c42 100644 (file)
@@ -64,6 +64,7 @@
 #else
 #include <EGL/egl.h>
 #endif
+#include "GLContextEGL.h"
 #include <wtf/HashSet.h>
 #include <wtf/NeverDestroyed.h>
 #endif
@@ -197,13 +198,15 @@ void PlatformDisplay::initializeEGLDisplay()
 
     if (m_eglDisplay == EGL_NO_DISPLAY) {
         m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-        if (m_eglDisplay == EGL_NO_DISPLAY)
+        if (m_eglDisplay == EGL_NO_DISPLAY) {
+            WTFLogAlways("Cannot get default EGL display: %s\n", GLContextEGL::lastErrorString());
             return;
+        }
     }
 
     EGLint majorVersion, minorVersion;
     if (eglInitialize(m_eglDisplay, &majorVersion, &minorVersion) == EGL_FALSE) {
-        LOG_ERROR("EGLDisplay Initialization failed.");
+        WTFLogAlways("EGLDisplay Initialization failed: %s\n", GLContextEGL::lastErrorString());
         terminateEGLDisplay();
         return;
     }
index 1ba179b..9c36085 100644 (file)
@@ -67,6 +67,37 @@ static const EGLenum gEGLAPIVersion = EGL_OPENGL_ES_API;
 static const EGLenum gEGLAPIVersion = EGL_OPENGL_API;
 #endif
 
+const char* GLContextEGL::errorString(int statusCode)
+{
+    static_assert(sizeof(int) >= sizeof(EGLint), "EGLint must not be wider than int");
+    switch (statusCode) {
+#define CASE_RETURN_STRING(name) case name: return #name
+        // https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglGetError.xhtml
+        CASE_RETURN_STRING(EGL_SUCCESS);
+        CASE_RETURN_STRING(EGL_NOT_INITIALIZED);
+        CASE_RETURN_STRING(EGL_BAD_ACCESS);
+        CASE_RETURN_STRING(EGL_BAD_ALLOC);
+        CASE_RETURN_STRING(EGL_BAD_ATTRIBUTE);
+        CASE_RETURN_STRING(EGL_BAD_CONTEXT);
+        CASE_RETURN_STRING(EGL_BAD_CONFIG);
+        CASE_RETURN_STRING(EGL_BAD_CURRENT_SURFACE);
+        CASE_RETURN_STRING(EGL_BAD_DISPLAY);
+        CASE_RETURN_STRING(EGL_BAD_SURFACE);
+        CASE_RETURN_STRING(EGL_BAD_MATCH);
+        CASE_RETURN_STRING(EGL_BAD_PARAMETER);
+        CASE_RETURN_STRING(EGL_BAD_NATIVE_PIXMAP);
+        CASE_RETURN_STRING(EGL_BAD_NATIVE_WINDOW);
+        CASE_RETURN_STRING(EGL_CONTEXT_LOST);
+#undef CASE_RETURN_STRING
+    default: return "Unknown EGL error";
+    }
+}
+
+const char* GLContextEGL::lastErrorString()
+{
+    return errorString(eglGetError());
+}
+
 bool GLContextEGL::getEGLConfig(EGLDisplay display, EGLConfig* config, EGLSurfaceType surfaceType)
 {
     EGLint attributeList[] = {
@@ -105,12 +136,16 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createWindowContext(GLNativeWindowTy
 {
     EGLDisplay display = platformDisplay.eglDisplay();
     EGLConfig config;
-    if (!getEGLConfig(display, &config, WindowSurface))
+    if (!getEGLConfig(display, &config, WindowSurface)) {
+        WTFLogAlways("Cannot obtain EGL window context configuration: %s\n", lastErrorString());
         return nullptr;
+    }
 
     EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes);
-    if (context == EGL_NO_CONTEXT)
+    if (context == EGL_NO_CONTEXT) {
+        WTFLogAlways("Cannot create EGL window context: %s\n", lastErrorString());
         return nullptr;
+    }
 
     EGLSurface surface = EGL_NO_SURFACE;
 #if PLATFORM(GTK)
@@ -129,6 +164,7 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createWindowContext(GLNativeWindowTy
     surface = eglCreateWindowSurface(display, config, static_cast<EGLNativeWindowType>(window), nullptr);
 #endif
     if (surface == EGL_NO_SURFACE) {
+        WTFLogAlways("Cannot create EGL window surface: %s\n", lastErrorString());
         eglDestroyContext(display, context);
         return nullptr;
     }
@@ -140,16 +176,21 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createPbufferContext(PlatformDisplay
 {
     EGLDisplay display = platformDisplay.eglDisplay();
     EGLConfig config;
-    if (!getEGLConfig(display, &config, PbufferSurface))
+    if (!getEGLConfig(display, &config, PbufferSurface)) {
+        WTFLogAlways("Cannot obtain EGL Pbuffer configuration: %s\n", lastErrorString());
         return nullptr;
+    }
 
     EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes);
-    if (context == EGL_NO_CONTEXT)
+    if (context == EGL_NO_CONTEXT) {
+        WTFLogAlways("Cannot create EGL Pbuffer context: %s\n", lastErrorString());
         return nullptr;
+    }
 
     static const int pbufferAttributes[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
     EGLSurface surface = eglCreatePbufferSurface(display, config, pbufferAttributes);
     if (surface == EGL_NO_SURFACE) {
+        WTFLogAlways("Cannot create EGL Pbuffer surface: %s\n", lastErrorString());
         eglDestroyContext(display, context);
         return nullptr;
     }
@@ -160,31 +201,47 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createPbufferContext(PlatformDisplay
 std::unique_ptr<GLContextEGL> GLContextEGL::createSurfacelessContext(PlatformDisplay& platformDisplay, EGLContext sharingContext)
 {
     EGLDisplay display = platformDisplay.eglDisplay();
-    if (display == EGL_NO_DISPLAY)
+    if (display == EGL_NO_DISPLAY) {
+        WTFLogAlways("Cannot create surfaceless EGL context: invalid display (last error: %s)\n", lastErrorString());
         return nullptr;
+    }
 
     const char* extensions = eglQueryString(display, EGL_EXTENSIONS);
-    if (!GLContext::isExtensionSupported(extensions, "EGL_KHR_surfaceless_context") && !GLContext::isExtensionSupported(extensions, "EGL_KHR_surfaceless_opengl"))
+    if (!GLContext::isExtensionSupported(extensions, "EGL_KHR_surfaceless_context") && !GLContext::isExtensionSupported(extensions, "EGL_KHR_surfaceless_opengl")) {
+        WTFLogAlways("Cannot create EGL surfaceless context: missing EGL_KHR_surfaceless_{context,opengl} extension.\n");
         return nullptr;
+    }
 
     EGLConfig config;
-    if (!getEGLConfig(display, &config, Surfaceless))
+    if (!getEGLConfig(display, &config, Surfaceless)) {
+        WTFLogAlways("Cannot obtain EGL surfaceless configuration: %s\n", lastErrorString());
         return nullptr;
+    }
 
     EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes);
-    if (context == EGL_NO_CONTEXT)
+    if (context == EGL_NO_CONTEXT) {
+        WTFLogAlways("Cannot create EGL surfaceless context: %s\n", lastErrorString());
         return nullptr;
+    }
 
     return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, EGL_NO_SURFACE, Surfaceless));
 }
 
 std::unique_ptr<GLContextEGL> GLContextEGL::createContext(GLNativeWindowType window, PlatformDisplay& platformDisplay)
 {
-    if (platformDisplay.eglDisplay() == EGL_NO_DISPLAY)
+    if (platformDisplay.eglDisplay() == EGL_NO_DISPLAY) {
+        WTFLogAlways("Cannot create EGL context: invalid display (last error: %s)\n", lastErrorString());
         return nullptr;
+    }
 
-    if (eglBindAPI(gEGLAPIVersion) == EGL_FALSE)
+    if (eglBindAPI(gEGLAPIVersion) == EGL_FALSE) {
+#if USE(OPENGL_ES_2)
+        WTFLogAlways("Cannot create EGL context: error binding OpenGL ES API (%s)\n", lastErrorString());
+#else
+        WTFLogAlways("Cannot create EGL context: error binding OpenGL API (%s)\n", lastErrorString());
+#endif
         return nullptr;
+    }
 
     EGLContext eglSharingContext = platformDisplay.sharingGLContext() ? static_cast<GLContextEGL*>(platformDisplay.sharingGLContext())->m_context : EGL_NO_CONTEXT;
     auto context = window ? createWindowContext(window, platformDisplay, eglSharingContext) : nullptr;
@@ -212,11 +269,19 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createContext(GLNativeWindowType win
 
 std::unique_ptr<GLContextEGL> GLContextEGL::createSharingContext(PlatformDisplay& platformDisplay)
 {
-    if (platformDisplay.eglDisplay() == EGL_NO_DISPLAY)
+    if (platformDisplay.eglDisplay() == EGL_NO_DISPLAY) {
+        WTFLogAlways("Cannot create EGL sharing context: invalid display (last error: %s)", lastErrorString());
         return nullptr;
+    }
 
-    if (eglBindAPI(gEGLAPIVersion) == EGL_FALSE)
+    if (eglBindAPI(gEGLAPIVersion) == EGL_FALSE) {
+#if USE(OPENGL_ES_2)
+        WTFLogAlways("Cannot create EGL sharing context: error binding OpenGL ES API (%s)\n", lastErrorString());
+#else
+        WTFLogAlways("Cannot create EGL sharing context: error binding OpenGL API (%s)\n", lastErrorString());
+#endif
         return nullptr;
+    }
 
     auto context = createSurfacelessContext(platformDisplay);
     if (!context) {
@@ -247,6 +312,8 @@ GLContextEGL::GLContextEGL(PlatformDisplay& display, EGLContext context, EGLSurf
 {
     ASSERT(type != PixmapSurface);
     ASSERT(type == Surfaceless || surface != EGL_NO_SURFACE);
+    RELEASE_ASSERT(m_display.eglDisplay() != EGL_NO_DISPLAY);
+    RELEASE_ASSERT(context != EGL_NO_CONTEXT);
 }
 
 GLContextEGL::~GLContextEGL()
index b3ce7f5..e810ac7 100644 (file)
@@ -49,6 +49,9 @@ public:
     static std::unique_ptr<GLContextEGL> createContext(GLNativeWindowType, PlatformDisplay&);
     static std::unique_ptr<GLContextEGL> createSharingContext(PlatformDisplay&);
 
+    static const char* errorString(int statusCode);
+    static const char* lastErrorString();
+
     virtual ~GLContextEGL();
 
 private:
index 184c3e3..57a18ce 100644 (file)
@@ -52,8 +52,10 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createWPEContext(PlatformDisplay& pl
 {
     EGLDisplay display = platformDisplay.eglDisplay();
     EGLConfig config;
-    if (!getEGLConfig(display, &config, WindowSurface))
+    if (!getEGLConfig(display, &config, WindowSurface)) {
+        WTFLogAlways("Cannot obtain EGL WPE context configuration: %s\n", lastErrorString());
         return nullptr;
+    }
 
     static const EGLint contextAttributes[] = {
 #if USE(OPENGL_ES_2)
@@ -63,19 +65,23 @@ std::unique_ptr<GLContextEGL> GLContextEGL::createWPEContext(PlatformDisplay& pl
     };
 
     EGLContext context = eglCreateContext(display, config, sharingContext, contextAttributes);
-    if (context == EGL_NO_CONTEXT)
+    if (context == EGL_NO_CONTEXT) {
+        WTFLogAlways("Cannot create EGL WPE context: %s\n", lastErrorString());
         return nullptr;
+    }
 
     auto* target = wpe_renderer_backend_egl_offscreen_target_create();
     wpe_renderer_backend_egl_offscreen_target_initialize(target, downcast<PlatformDisplayWPE>(platformDisplay).backend());
     EGLNativeWindowType window = wpe_renderer_backend_egl_offscreen_target_get_native_window(target);
     if (!window) {
+        WTFLogAlways("Cannot create EGL WPE context: %s\n", lastErrorString());
         wpe_renderer_backend_egl_offscreen_target_destroy(target);
         return nullptr;
     }
 
     EGLSurface surface = eglCreateWindowSurface(display, config, static_cast<EGLNativeWindowType>(window), nullptr);
     if (surface == EGL_NO_SURFACE) {
+        WTFLogAlways("Cannot create EGL WPE window surface: %s\n", lastErrorString());
         eglDestroyContext(display, context);
         wpe_renderer_backend_egl_offscreen_target_destroy(target);
         return nullptr;
index 8c349c1..2b5fe32 100644 (file)
@@ -54,7 +54,7 @@ void PlatformDisplayWPE::initialize(int hostFd)
 
     m_eglDisplay = eglGetDisplay(wpe_renderer_backend_egl_get_native_display(m_backend));
     if (m_eglDisplay == EGL_NO_DISPLAY) {
-        WTFLogAlways("PlatformDisplayWPE: could not create the EGL display.");
+        WTFLogAlways("PlatformDisplayWPE: could not create the EGL display: %s.", GLContextEGL::lastErrorString());
         return;
     }