Title: [207615] trunk/Source/WebCore
Revision
207615
Author
carlo...@webkit.org
Date
2016-10-20 05:37:53 -0700 (Thu, 20 Oct 2016)

Log Message

[GTK] Avoid including egl.h headers in internal headers
https://bugs.webkit.org/show_bug.cgi?id=163722

Reviewed by Žan Doberšek.

egl.h includes eglplatform.h that decides the native types for the platform at compile time. However, we support
to build with X11 and Wayland at the same time and decide what to use at runtime. Currently GLContext.h includes
eglplatform.h after wayland-egl.h if Wayland is enabled. That means that the wayland native types are used by
default from all cpp files including GLContext.h. It currently works in X11 because we cast the value anyway and
for example EGLNativeWindowType is a pointer in Wayland that can be casted to unsigned long in X11 to represent
the X Window. This is very fragile in any case, we should avoid adding egl headers in our headers and only
include it in cpp files. But we also need to ensure we don't use X11 and Wayland in the same cpp file.

* PlatformGTK.cmake:
* platform/graphics/GLContext.cpp:
(WebCore::GLContext::createContextForWindow):
* platform/graphics/GLContext.h:
* platform/graphics/egl/GLContextEGL.cpp:
(WebCore::GLContextEGL::createWindowContext):
(WebCore::GLContextEGL::createContext):
(WebCore::GLContextEGL::~GLContextEGL):
* platform/graphics/egl/GLContextEGL.h:
* platform/graphics/egl/GLContextEGLWayland.cpp: Added.
(WebCore::GLContextEGL::GLContextEGL):
(WebCore::GLContextEGL::createWindowSurfaceWayland):
(WebCore::GLContextEGL::createWaylandContext):
(WebCore::GLContextEGL::destroyWaylandWindow):
* platform/graphics/egl/GLContextEGLX11.cpp: Added.
(WebCore::GLContextEGL::GLContextEGL):
(WebCore::GLContextEGL::createWindowSurfaceX11):
(WebCore::GLContextEGL::createPixmapContext):
* platform/graphics/glx/GLContextGLX.cpp:
(WebCore::GLContextGLX::createWindowContext):
(WebCore::GLContextGLX::createContext):
(WebCore::GLContextGLX::GLContextGLX):
* platform/graphics/glx/GLContextGLX.h:
* platform/graphics/wayland/PlatformDisplayWayland.cpp:
* platform/graphics/x11/PlatformDisplayX11.cpp:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (207614 => 207615)


--- trunk/Source/WebCore/ChangeLog	2016-10-20 12:36:06 UTC (rev 207614)
+++ trunk/Source/WebCore/ChangeLog	2016-10-20 12:37:53 UTC (rev 207615)
@@ -1,5 +1,46 @@
 2016-10-20  Carlos Garcia Campos  <cgar...@igalia.com>
 
+        [GTK] Avoid including egl.h headers in internal headers
+        https://bugs.webkit.org/show_bug.cgi?id=163722
+
+        Reviewed by Žan Doberšek.
+
+        egl.h includes eglplatform.h that decides the native types for the platform at compile time. However, we support
+        to build with X11 and Wayland at the same time and decide what to use at runtime. Currently GLContext.h includes
+        eglplatform.h after wayland-egl.h if Wayland is enabled. That means that the wayland native types are used by
+        default from all cpp files including GLContext.h. It currently works in X11 because we cast the value anyway and
+        for example EGLNativeWindowType is a pointer in Wayland that can be casted to unsigned long in X11 to represent
+        the X Window. This is very fragile in any case, we should avoid adding egl headers in our headers and only
+        include it in cpp files. But we also need to ensure we don't use X11 and Wayland in the same cpp file.
+
+        * PlatformGTK.cmake:
+        * platform/graphics/GLContext.cpp:
+        (WebCore::GLContext::createContextForWindow):
+        * platform/graphics/GLContext.h:
+        * platform/graphics/egl/GLContextEGL.cpp:
+        (WebCore::GLContextEGL::createWindowContext):
+        (WebCore::GLContextEGL::createContext):
+        (WebCore::GLContextEGL::~GLContextEGL):
+        * platform/graphics/egl/GLContextEGL.h:
+        * platform/graphics/egl/GLContextEGLWayland.cpp: Added.
+        (WebCore::GLContextEGL::GLContextEGL):
+        (WebCore::GLContextEGL::createWindowSurfaceWayland):
+        (WebCore::GLContextEGL::createWaylandContext):
+        (WebCore::GLContextEGL::destroyWaylandWindow):
+        * platform/graphics/egl/GLContextEGLX11.cpp: Added.
+        (WebCore::GLContextEGL::GLContextEGL):
+        (WebCore::GLContextEGL::createWindowSurfaceX11):
+        (WebCore::GLContextEGL::createPixmapContext):
+        * platform/graphics/glx/GLContextGLX.cpp:
+        (WebCore::GLContextGLX::createWindowContext):
+        (WebCore::GLContextGLX::createContext):
+        (WebCore::GLContextGLX::GLContextGLX):
+        * platform/graphics/glx/GLContextGLX.h:
+        * platform/graphics/wayland/PlatformDisplayWayland.cpp:
+        * platform/graphics/x11/PlatformDisplayX11.cpp:
+
+2016-10-20  Carlos Garcia Campos  <cgar...@igalia.com>
+
         [GTK] Avoid strstr() when checking (E)GL extensions
         https://bugs.webkit.org/show_bug.cgi?id=161958
 

Modified: trunk/Source/WebCore/PlatformGTK.cmake (207614 => 207615)


--- trunk/Source/WebCore/PlatformGTK.cmake	2016-10-20 12:36:06 UTC (rev 207614)
+++ trunk/Source/WebCore/PlatformGTK.cmake	2016-10-20 12:37:53 UTC (rev 207615)
@@ -126,6 +126,8 @@
     platform/graphics/cairo/TransformationMatrixCairo.cpp
 
     platform/graphics/egl/GLContextEGL.cpp
+    platform/graphics/egl/GLContextEGLWayland.cpp
+    platform/graphics/egl/GLContextEGLX11.cpp
 
     platform/graphics/freetype/FontCacheFreeType.cpp
     platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp

Modified: trunk/Source/WebCore/platform/graphics/GLContext.cpp (207614 => 207615)


--- trunk/Source/WebCore/platform/graphics/GLContext.cpp	2016-10-20 12:36:06 UTC (rev 207614)
+++ trunk/Source/WebCore/platform/graphics/GLContext.cpp	2016-10-20 12:37:53 UTC (rev 207615)
@@ -84,12 +84,7 @@
 #endif
 
 #if USE(GLX)
-#if PLATFORM(WAYLAND) // Building both X11 and Wayland targets
-    XID GLXWindowHandle = reinterpret_cast<XID>(windowHandle);
-#else
-    XID GLXWindowHandle = static_cast<XID>(windowHandle);
-#endif
-    if (auto glxContext = GLContextGLX::createContext(GLXWindowHandle, display))
+    if (auto glxContext = GLContextGLX::createContext(windowHandle, display))
         return WTFMove(glxContext);
 #endif
 #if USE(EGL)

Modified: trunk/Source/WebCore/platform/graphics/GLContext.h (207614 => 207615)


--- trunk/Source/WebCore/platform/graphics/GLContext.h	2016-10-20 12:36:06 UTC (rev 207614)
+++ trunk/Source/WebCore/platform/graphics/GLContext.h	2016-10-20 12:37:53 UTC (rev 207615)
@@ -27,10 +27,6 @@
 #if USE(EGL) && !PLATFORM(GTK)
 #include "eglplatform.h"
 typedef EGLNativeWindowType GLNativeWindowType;
-#elif PLATFORM(GTK) && PLATFORM(WAYLAND) && !defined(GTK_API_VERSION_2)
-#include <wayland-egl.h>
-#include <EGL/eglplatform.h>
-typedef EGLNativeWindowType GLNativeWindowType;
 #else
 typedef uint64_t GLNativeWindowType;
 #endif

Modified: trunk/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp (207614 => 207615)


--- trunk/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp	2016-10-20 12:36:06 UTC (rev 207614)
+++ trunk/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp	2016-10-20 12:37:53 UTC (rev 207615)
@@ -22,6 +22,8 @@
 #if USE(EGL)
 
 #include "GraphicsContext3D.h"
+#include "PlatformDisplay.h"
+#include <EGL/egl.h>
 
 #if USE(CAIRO)
 #include <cairo.h>
@@ -34,18 +36,6 @@
 #include "OpenGLShims.h"
 #endif
 
-#if PLATFORM(X11)
-#include "PlatformDisplayX11.h"
-#include "XErrorTrapper.h"
-#include "XUniquePtr.h"
-#include <X11/Xlib.h>
-#endif
-
-#if PLATFORM(WAYLAND)
-#include "PlatformDisplayWayland.h"
-#include <wayland-egl.h>
-#endif
-
 #if ENABLE(ACCELERATED_2D_CANVAS)
 // cairo-gl.h includes some definitions from GLX that conflict with
 // the ones provided by us. Since GLContextEGL doesn't use any GLX
@@ -103,7 +93,7 @@
     return eglChooseConfig(display, attributeList, config, 1, &numberConfigsReturned) && numberConfigsReturned;
 }
 
-std::unique_ptr<GLContextEGL> GLContextEGL::createWindowContext(EGLNativeWindowType window, PlatformDisplay& platformDisplay, EGLContext sharingContext)
+std::unique_ptr<GLContextEGL> GLContextEGL::createWindowContext(GLNativeWindowType window, PlatformDisplay& platformDisplay, EGLContext sharingContext)
 {
     EGLDisplay display = platformDisplay.eglDisplay();
     EGLConfig config;
@@ -114,7 +104,19 @@
     if (context == EGL_NO_CONTEXT)
         return nullptr;
 
-    EGLSurface surface = eglCreateWindowSurface(display, config, window, 0);
+    EGLSurface surface = EGL_NO_SURFACE;
+#if PLATFORM(GTK)
+#if PLATFORM(X11)
+    if (platformDisplay.type() == PlatformDisplay::Type::X11)
+        surface = createWindowSurfaceX11(display, config, window);
+#endif
+#if PLATFORM(WAYLAND)
+    if (platformDisplay.type() == PlatformDisplay::Type::Wayland)
+        surface = createWindowSurfaceWayland(display, config, window);
+#endif
+#else
+    surface = eglCreateWindowSurface(display, config, static_cast<EGLNativeWindowType>(window), nullptr);
+#endif
     if (surface == EGL_NO_SURFACE) {
         eglDestroyContext(display, context);
         return nullptr;
@@ -165,91 +167,8 @@
     return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, EGL_NO_SURFACE, Surfaceless));
 }
 
-#if PLATFORM(X11)
-std::unique_ptr<GLContextEGL> GLContextEGL::createPixmapContext(PlatformDisplay& platformDisplay, EGLContext sharingContext)
+std::unique_ptr<GLContextEGL> GLContextEGL::createContext(GLNativeWindowType window, PlatformDisplay& platformDisplay)
 {
-    EGLDisplay display = platformDisplay.eglDisplay();
-    EGLConfig config;
-    if (!getEGLConfig(display, &config, PixmapSurface))
-        return nullptr;
-
-    EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes);
-    if (context == EGL_NO_CONTEXT)
-        return nullptr;
-
-    EGLint visualId;
-    if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &visualId)) {
-        eglDestroyContext(display, context);
-        return nullptr;
-    }
-
-    Display* x11Display = downcast<PlatformDisplayX11>(platformDisplay).native();
-
-    XVisualInfo visualInfo;
-    visualInfo.visualid = visualId;
-    int numVisuals = 0;
-    XUniquePtr<XVisualInfo> visualInfoList(XGetVisualInfo(x11Display, VisualIDMask, &visualInfo, &numVisuals));
-    if (!visualInfoList || !numVisuals) {
-        eglDestroyContext(display, context);
-        return nullptr;
-    }
-
-    // We are using VisualIDMask so there must be only one.
-    ASSERT(numVisuals == 1);
-    XUniquePixmap pixmap = XCreatePixmap(x11Display, DefaultRootWindow(x11Display), 1, 1, visualInfoList.get()[0].depth);
-    if (!pixmap) {
-        eglDestroyContext(display, context);
-        return nullptr;
-    }
-
-    // Some drivers fail to create the surface producing BadDrawable X error and the default XError handler normally aborts.
-    // However, if the X error is ignored, eglCreatePixmapSurface() ends up returning a surface and we can continue creating
-    // the context. Since this is an offscreen context, it doesn't matter if the pixmap used is not valid because we never do
-    // swap buffers. So, we use a custom XError handler here that ignores BadDrawable errors and only warns about any other
-    // errors without aborting in any case.
-    XErrorTrapper trapper(x11Display, XErrorTrapper::Policy::Warn, { BadDrawable });
-    EGLSurface surface = eglCreatePixmapSurface(display, config, reinterpret_cast<EGLNativePixmapType>(pixmap.get()), 0);
-    if (surface == EGL_NO_SURFACE) {
-        eglDestroyContext(display, context);
-        return nullptr;
-    }
-
-    return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, surface, WTFMove(pixmap)));
-}
-#endif // PLATFORM(X11)
-
-#if PLATFORM(WAYLAND)
-std::unique_ptr<GLContextEGL> GLContextEGL::createWaylandContext(PlatformDisplay& platformDisplay, EGLContext sharingContext)
-{
-    EGLDisplay display = platformDisplay.eglDisplay();
-    EGLConfig config;
-    if (!getEGLConfig(display, &config, WindowSurface))
-        return nullptr;
-
-    EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes);
-    if (context == EGL_NO_CONTEXT)
-        return nullptr;
-
-    WlUniquePtr<struct wl_surface> wlSurface(downcast<PlatformDisplayWayland>(platformDisplay).createSurface());
-    if (!wlSurface) {
-        eglDestroyContext(display, context);
-        return nullptr;
-    }
-
-    EGLNativeWindowType window = wl_egl_window_create(wlSurface.get(), 1, 1);
-    EGLSurface surface = eglCreateWindowSurface(display, config, window, 0);
-    if (surface == EGL_NO_SURFACE) {
-        eglDestroyContext(display, context);
-        wl_egl_window_destroy(window);
-        return nullptr;
-    }
-
-    return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, surface, WTFMove(wlSurface), window));
-}
-#endif
-
-std::unique_ptr<GLContextEGL> GLContextEGL::createContext(EGLNativeWindowType window, PlatformDisplay& platformDisplay)
-{
     if (platformDisplay.eglDisplay() == EGL_NO_DISPLAY)
         return nullptr;
 
@@ -311,29 +230,6 @@
     ASSERT(type == Surfaceless || surface != EGL_NO_SURFACE);
 }
 
-#if PLATFORM(X11)
-GLContextEGL::GLContextEGL(PlatformDisplay& display, EGLContext context, EGLSurface surface, XUniquePixmap&& pixmap)
-    : GLContext(display)
-    , m_context(context)
-    , m_surface(surface)
-    , m_type(PixmapSurface)
-    , m_pixmap(WTFMove(pixmap))
-{
-}
-#endif
-
-#if PLATFORM(WAYLAND)
-GLContextEGL::GLContextEGL(PlatformDisplay& display, EGLContext context, EGLSurface surface, WlUniquePtr<struct wl_surface>&& wlSurface, EGLNativeWindowType wlWindow)
-    : GLContext(display)
-    , m_context(context)
-    , m_surface(surface)
-    , m_type(WindowSurface)
-    , m_wlSurface(WTFMove(wlSurface))
-    , m_wlWindow(wlWindow)
-{
-}
-#endif
-
 GLContextEGL::~GLContextEGL()
 {
 #if USE(CAIRO)
@@ -352,8 +248,7 @@
         eglDestroySurface(display, m_surface);
 
 #if PLATFORM(WAYLAND)
-    if (m_wlWindow)
-        wl_egl_window_destroy(m_wlWindow);
+    destroyWaylandWindow();
 #endif
 }
 

Modified: trunk/Source/WebCore/platform/graphics/egl/GLContextEGL.h (207614 => 207615)


--- trunk/Source/WebCore/platform/graphics/egl/GLContextEGL.h	2016-10-20 12:36:06 UTC (rev 207614)
+++ trunk/Source/WebCore/platform/graphics/egl/GLContextEGL.h	2016-10-20 12:37:53 UTC (rev 207615)
@@ -17,13 +17,11 @@
  *  Boston, MA 02110-1301 USA
  */
 
-#ifndef GLContextEGL_h
-#define GLContextEGL_h
+#pragma once
 
 #if USE(EGL)
 
 #include "GLContext.h"
-#include <EGL/egl.h>
 
 #if PLATFORM(X11)
 #include "XUniqueResource.h"
@@ -31,18 +29,25 @@
 
 #if PLATFORM(WAYLAND)
 #include "WlUniquePtr.h"
+struct wl_egl_window;
 #endif
 
+typedef void *EGLConfig;
+typedef void *EGLContext;
+typedef void *EGLDisplay;
+typedef void *EGLSurface;
+
 namespace WebCore {
 
 class GLContextEGL final : public GLContext {
     WTF_MAKE_NONCOPYABLE(GLContextEGL);
 public:
-    static std::unique_ptr<GLContextEGL> createContext(EGLNativeWindowType, PlatformDisplay&);
+    static std::unique_ptr<GLContextEGL> createContext(GLNativeWindowType, PlatformDisplay&);
     static std::unique_ptr<GLContextEGL> createSharingContext(PlatformDisplay&);
 
     virtual ~GLContextEGL();
 
+private:
     bool makeContextCurrent() override;
     void swapBuffers() override;
     void waitNative() override;
@@ -58,7 +63,6 @@
     PlatformGraphicsContext3D platformContext() override;
 #endif
 
-private:
     enum EGLSurfaceType { PbufferSurface, WindowSurface, PixmapSurface, Surfaceless };
 
     GLContextEGL(PlatformDisplay&, EGLContext, EGLSurface, EGLSurfaceType);
@@ -66,23 +70,26 @@
     GLContextEGL(PlatformDisplay&, EGLContext, EGLSurface, XUniquePixmap&&);
 #endif
 #if PLATFORM(WAYLAND)
-    GLContextEGL(PlatformDisplay&, EGLContext, EGLSurface, WlUniquePtr<struct wl_surface>&&, EGLNativeWindowType);
+    GLContextEGL(PlatformDisplay&, EGLContext, EGLSurface, WlUniquePtr<struct wl_surface>&&, struct wl_egl_window*);
+    void destroyWaylandWindow();
 #endif
 
-    static std::unique_ptr<GLContextEGL> createWindowContext(EGLNativeWindowType, PlatformDisplay&, EGLContext sharingContext = EGL_NO_CONTEXT);
-    static std::unique_ptr<GLContextEGL> createPbufferContext(PlatformDisplay&, EGLContext sharingContext = EGL_NO_CONTEXT);
-    static std::unique_ptr<GLContextEGL> createSurfacelessContext(PlatformDisplay&, EGLContext sharingContext = EGL_NO_CONTEXT);
+    static std::unique_ptr<GLContextEGL> createWindowContext(GLNativeWindowType, PlatformDisplay&, EGLContext sharingContext = nullptr);
+    static std::unique_ptr<GLContextEGL> createPbufferContext(PlatformDisplay&, EGLContext sharingContext = nullptr);
+    static std::unique_ptr<GLContextEGL> createSurfacelessContext(PlatformDisplay&, EGLContext sharingContext = nullptr);
 #if PLATFORM(X11)
-    static std::unique_ptr<GLContextEGL> createPixmapContext(PlatformDisplay&, EGLContext sharingContext = EGL_NO_CONTEXT);
+    static std::unique_ptr<GLContextEGL> createPixmapContext(PlatformDisplay&, EGLContext sharingContext = nullptr);
+    static EGLSurface createWindowSurfaceX11(EGLDisplay, EGLConfig, GLNativeWindowType);
 #endif
 #if PLATFORM(WAYLAND)
-    static std::unique_ptr<GLContextEGL> createWaylandContext(PlatformDisplay&, EGLContext sharingContext = EGL_NO_CONTEXT);
+    static std::unique_ptr<GLContextEGL> createWaylandContext(PlatformDisplay&, EGLContext sharingContext = nullptr);
+    static EGLSurface createWindowSurfaceWayland(EGLDisplay, EGLConfig, GLNativeWindowType);
 #endif
 
     static bool getEGLConfig(EGLDisplay, EGLConfig*, EGLSurfaceType);
 
-    EGLContext m_context { EGL_NO_CONTEXT };
-    EGLSurface m_surface { EGL_NO_SURFACE };
+    EGLContext m_context { nullptr };
+    EGLSurface m_surface { nullptr };
     EGLSurfaceType m_type;
 #if PLATFORM(X11)
     XUniquePixmap m_pixmap;
@@ -99,5 +106,3 @@
 } // namespace WebCore
 
 #endif // USE(EGL)
-
-#endif // GLContextEGL_h

Added: trunk/Source/WebCore/platform/graphics/egl/GLContextEGLWayland.cpp (0 => 207615)


--- trunk/Source/WebCore/platform/graphics/egl/GLContextEGLWayland.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/egl/GLContextEGLWayland.cpp	2016-10-20 12:37:53 UTC (rev 207615)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 Igalia, S.L.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "GLContextEGL.h"
+
+#if USE(EGL) && PLATFORM(WAYLAND)
+
+#include "PlatformDisplayWayland.h"
+// These includes need to be in this order because wayland-egl.h defines WL_EGL_PLATFORM
+// and egl.h checks that to decide whether it's Wayland platform.
+#include <wayland-egl.h>
+#include <EGL/egl.h>
+
+namespace WebCore {
+
+GLContextEGL::GLContextEGL(PlatformDisplay& display, EGLContext context, EGLSurface surface, WlUniquePtr<struct wl_surface>&& wlSurface, struct wl_egl_window* wlWindow)
+    : GLContext(display)
+    , m_context(context)
+    , m_surface(surface)
+    , m_type(WindowSurface)
+    , m_wlSurface(WTFMove(wlSurface))
+    , m_wlWindow(wlWindow)
+{
+}
+
+EGLSurface GLContextEGL::createWindowSurfaceWayland(EGLDisplay display, EGLConfig config, GLNativeWindowType window)
+{
+    return eglCreateWindowSurface(display, config, reinterpret_cast<EGLNativeWindowType>(window), nullptr);
+}
+
+std::unique_ptr<GLContextEGL> GLContextEGL::createWaylandContext(PlatformDisplay& platformDisplay, EGLContext sharingContext)
+{
+    EGLDisplay display = platformDisplay.eglDisplay();
+    EGLConfig config;
+    if (!getEGLConfig(display, &config, WindowSurface))
+        return nullptr;
+
+    static const EGLint contextAttributes[] = {
+#if USE(OPENGL_ES_2)
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+#endif
+        EGL_NONE
+    };
+
+    EGLContext context = eglCreateContext(display, config, sharingContext, contextAttributes);
+    if (context == EGL_NO_CONTEXT)
+        return nullptr;
+
+    WlUniquePtr<struct wl_surface> wlSurface(downcast<PlatformDisplayWayland>(platformDisplay).createSurface());
+    if (!wlSurface) {
+        eglDestroyContext(display, context);
+        return nullptr;
+    }
+
+    EGLNativeWindowType window = wl_egl_window_create(wlSurface.get(), 1, 1);
+    EGLSurface surface = eglCreateWindowSurface(display, config, window, 0);
+    if (surface == EGL_NO_SURFACE) {
+        eglDestroyContext(display, context);
+        wl_egl_window_destroy(window);
+        return nullptr;
+    }
+
+    return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, surface, WTFMove(wlSurface), window));
+}
+
+void GLContextEGL::destroyWaylandWindow()
+{
+    if (m_wlWindow)
+        wl_egl_window_destroy(m_wlWindow);
+}
+
+} // namespace WebCore
+
+#endif //  USE(EGL) && PLATFORM(WAYLAND)

Added: trunk/Source/WebCore/platform/graphics/egl/GLContextEGLX11.cpp (0 => 207615)


--- trunk/Source/WebCore/platform/graphics/egl/GLContextEGLX11.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/egl/GLContextEGLX11.cpp	2016-10-20 12:37:53 UTC (rev 207615)
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2016 Igalia, S.L.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "GLContextEGL.h"
+
+#if USE(EGL) && PLATFORM(X11)
+#include "PlatformDisplayX11.h"
+#include "XErrorTrapper.h"
+#include "XUniquePtr.h"
+#include <EGL/egl.h>
+#include <X11/Xlib.h>
+
+namespace WebCore {
+
+GLContextEGL::GLContextEGL(PlatformDisplay& display, EGLContext context, EGLSurface surface, XUniquePixmap&& pixmap)
+    : GLContext(display)
+    , m_context(context)
+    , m_surface(surface)
+    , m_type(PixmapSurface)
+    , m_pixmap(WTFMove(pixmap))
+{
+}
+
+EGLSurface GLContextEGL::createWindowSurfaceX11(EGLDisplay display, EGLConfig config, GLNativeWindowType window)
+{
+    return eglCreateWindowSurface(display, config, static_cast<EGLNativeWindowType>(window), nullptr);
+}
+
+std::unique_ptr<GLContextEGL> GLContextEGL::createPixmapContext(PlatformDisplay& platformDisplay, EGLContext sharingContext)
+{
+    EGLDisplay display = platformDisplay.eglDisplay();
+    EGLConfig config;
+    if (!getEGLConfig(display, &config, PixmapSurface))
+        return nullptr;
+
+    static const EGLint contextAttributes[] = {
+#if USE(OPENGL_ES_2)
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+#endif
+        EGL_NONE
+    };
+    EGLContext context = eglCreateContext(display, config, sharingContext, contextAttributes);
+    if (context == EGL_NO_CONTEXT)
+        return nullptr;
+
+    EGLint visualId;
+    if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &visualId)) {
+        eglDestroyContext(display, context);
+        return nullptr;
+    }
+
+    Display* x11Display = downcast<PlatformDisplayX11>(platformDisplay).native();
+
+    XVisualInfo visualInfo;
+    visualInfo.visualid = visualId;
+    int numVisuals = 0;
+    XUniquePtr<XVisualInfo> visualInfoList(XGetVisualInfo(x11Display, VisualIDMask, &visualInfo, &numVisuals));
+    if (!visualInfoList || !numVisuals) {
+        eglDestroyContext(display, context);
+        return nullptr;
+    }
+
+    // We are using VisualIDMask so there must be only one.
+    ASSERT(numVisuals == 1);
+    XUniquePixmap pixmap = XCreatePixmap(x11Display, DefaultRootWindow(x11Display), 1, 1, visualInfoList.get()[0].depth);
+    if (!pixmap) {
+        eglDestroyContext(display, context);
+        return nullptr;
+    }
+
+    // Some drivers fail to create the surface producing BadDrawable X error and the default XError handler normally aborts.
+    // However, if the X error is ignored, eglCreatePixmapSurface() ends up returning a surface and we can continue creating
+    // the context. Since this is an offscreen context, it doesn't matter if the pixmap used is not valid because we never do
+    // swap buffers. So, we use a custom XError handler here that ignores BadDrawable errors and only warns about any other
+    // errors without aborting in any case.
+    XErrorTrapper trapper(x11Display, XErrorTrapper::Policy::Warn, { BadDrawable });
+    EGLSurface surface = eglCreatePixmapSurface(display, config, reinterpret_cast<EGLNativePixmapType>(pixmap.get()), 0);
+    if (surface == EGL_NO_SURFACE) {
+        eglDestroyContext(display, context);
+        return nullptr;
+    }
+
+    return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, surface, WTFMove(pixmap)));
+}
+
+} // namespace WebCore
+
+#endif // USE(EGL) && PLATFORM(X11)

Modified: trunk/Source/WebCore/platform/graphics/glx/GLContextGLX.cpp (207614 => 207615)


--- trunk/Source/WebCore/platform/graphics/glx/GLContextGLX.cpp	2016-10-20 12:36:06 UTC (rev 207614)
+++ trunk/Source/WebCore/platform/graphics/glx/GLContextGLX.cpp	2016-10-20 12:37:53 UTC (rev 207615)
@@ -52,11 +52,11 @@
     return !!glXSwapIntervalSGI;
 }
 
-std::unique_ptr<GLContextGLX> GLContextGLX::createWindowContext(XID window, PlatformDisplay& platformDisplay, GLXContext sharingContext)
+std::unique_ptr<GLContextGLX> GLContextGLX::createWindowContext(GLNativeWindowType window, PlatformDisplay& platformDisplay, GLXContext sharingContext)
 {
     Display* display = downcast<PlatformDisplayX11>(platformDisplay).native();
     XWindowAttributes attributes;
-    if (!XGetWindowAttributes(display, window, &attributes))
+    if (!XGetWindowAttributes(display, static_cast<Window>(window), &attributes))
         return nullptr;
 
     XVisualInfo visualInfo;
@@ -135,7 +135,7 @@
     return std::unique_ptr<GLContextGLX>(new GLContextGLX(platformDisplay, WTFMove(context), WTFMove(pixmap), WTFMove(glxPixmap)));
 }
 
-std::unique_ptr<GLContextGLX> GLContextGLX::createContext(XID window, PlatformDisplay& platformDisplay)
+std::unique_ptr<GLContextGLX> GLContextGLX::createContext(GLNativeWindowType window, PlatformDisplay& platformDisplay)
 {
     GLXContext glxSharingContext = platformDisplay.sharingGLContext() ? static_cast<GLContextGLX*>(platformDisplay.sharingGLContext())->m_context.get() : nullptr;
     auto context = window ? createWindowContext(window, platformDisplay, glxSharingContext) : nullptr;
@@ -155,11 +155,11 @@
     return context;
 }
 
-GLContextGLX::GLContextGLX(PlatformDisplay& display, XUniqueGLXContext&& context, XID window)
+GLContextGLX::GLContextGLX(PlatformDisplay& display, XUniqueGLXContext&& context, GLNativeWindowType window)
     : GLContext(display)
     , m_x11Display(downcast<PlatformDisplayX11>(m_display).native())
     , m_context(WTFMove(context))
-    , m_window(window)
+    , m_window(static_cast<Window>(window))
 {
 }
 

Modified: trunk/Source/WebCore/platform/graphics/glx/GLContextGLX.h (207614 => 207615)


--- trunk/Source/WebCore/platform/graphics/glx/GLContextGLX.h	2016-10-20 12:36:06 UTC (rev 207614)
+++ trunk/Source/WebCore/platform/graphics/glx/GLContextGLX.h	2016-10-20 12:37:53 UTC (rev 207615)
@@ -17,8 +17,7 @@
  *  Boston, MA 02110-1301 USA
  */
 
-#ifndef GLContextGLX_h
-#define GLContextGLX_h
+#pragma once
 
 #if USE(GLX)
 
@@ -27,7 +26,7 @@
 #include "XUniqueResource.h"
 
 typedef unsigned char GLubyte;
-typedef unsigned long XID;
+typedef unsigned long Window;
 typedef void* ContextKeyType;
 typedef struct _XDisplay Display;
 
@@ -36,11 +35,12 @@
 class GLContextGLX final : public GLContext {
     WTF_MAKE_NONCOPYABLE(GLContextGLX);
 public:
-    static std::unique_ptr<GLContextGLX> createContext(XID window, PlatformDisplay&);
+    static std::unique_ptr<GLContextGLX> createContext(GLNativeWindowType, PlatformDisplay&);
     static std::unique_ptr<GLContextGLX> createSharingContext(PlatformDisplay&);
 
     virtual ~GLContextGLX();
 
+private:
     bool makeContextCurrent() override;
     void swapBuffers() override;
     void waitNative() override;
@@ -54,18 +54,17 @@
     PlatformGraphicsContext3D platformContext() override;
 #endif
 
-private:
-    GLContextGLX(PlatformDisplay&, XUniqueGLXContext&&, XID);
+    GLContextGLX(PlatformDisplay&, XUniqueGLXContext&&, GLNativeWindowType);
     GLContextGLX(PlatformDisplay&, XUniqueGLXContext&&, XUniqueGLXPbuffer&&);
     GLContextGLX(PlatformDisplay&, XUniqueGLXContext&&, XUniquePixmap&&, XUniqueGLXPixmap&&);
 
-    static std::unique_ptr<GLContextGLX> createWindowContext(XID window, PlatformDisplay&, GLXContext sharingContext = nullptr);
+    static std::unique_ptr<GLContextGLX> createWindowContext(GLNativeWindowType, PlatformDisplay&, GLXContext sharingContext = nullptr);
     static std::unique_ptr<GLContextGLX> createPbufferContext(PlatformDisplay&, GLXContext sharingContext = nullptr);
     static std::unique_ptr<GLContextGLX> createPixmapContext(PlatformDisplay&, GLXContext sharingContext = nullptr);
 
     Display* m_x11Display { nullptr };
     XUniqueGLXContext m_context;
-    XID m_window { 0 };
+    Window m_window { 0 };
     XUniqueGLXPbuffer m_pbuffer;
     XUniquePixmap m_pixmap;
     XUniqueGLXPixmap m_glxPixmap;
@@ -76,4 +75,3 @@
 
 #endif // USE(GLX)
 
-#endif // GLContextGLX_h

Modified: trunk/Source/WebCore/platform/graphics/wayland/PlatformDisplayWayland.cpp (207614 => 207615)


--- trunk/Source/WebCore/platform/graphics/wayland/PlatformDisplayWayland.cpp	2016-10-20 12:36:06 UTC (rev 207614)
+++ trunk/Source/WebCore/platform/graphics/wayland/PlatformDisplayWayland.cpp	2016-10-20 12:37:53 UTC (rev 207615)
@@ -30,7 +30,10 @@
 
 #include "GLContextEGL.h"
 #include <cstring>
+// These includes need to be in this order because wayland-egl.h defines WL_EGL_PLATFORM
+// and egl.h checks that to decide whether it's Wayland platform.
 #include <wayland-egl.h>
+#include <EGL/egl.h>
 #include <wtf/Assertions.h>
 
 namespace WebCore {

Modified: trunk/Source/WebCore/platform/graphics/x11/PlatformDisplayX11.cpp (207614 => 207615)


--- trunk/Source/WebCore/platform/graphics/x11/PlatformDisplayX11.cpp	2016-10-20 12:36:06 UTC (rev 207614)
+++ trunk/Source/WebCore/platform/graphics/x11/PlatformDisplayX11.cpp	2016-10-20 12:37:53 UTC (rev 207615)
@@ -26,6 +26,8 @@
 #include "config.h"
 #include "PlatformDisplayX11.h"
 
+#include "GLContext.h"
+
 #if PLATFORM(X11)
 #include <X11/Xlib.h>
 #include <X11/extensions/Xcomposite.h>
@@ -35,14 +37,8 @@
 
 #if USE(EGL)
 #include <EGL/egl.h>
-#include <EGL/eglplatform.h>
 #endif
 
-// FIXME: this needs to be here, after eglplatform.h, to avoid EGLNativeDisplayType to be defined as wl_display.
-// Since we support Wayland and X11 to be built at the same time, but eglplatform.h defines are decided at compile time
-// we need to ensure we only include eglplatform.h from X11 or Wayland specific files.
-#include "GLContext.h"
-
 namespace WebCore {
 
 PlatformDisplayX11::PlatformDisplayX11()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to