Title: [173651] trunk/Source/WebCore
Revision
173651
Author
[email protected]
Date
2014-09-15 23:53:30 -0700 (Mon, 15 Sep 2014)

Log Message

[GTK] Add WaylandDisplay
https://bugs.webkit.org/show_bug.cgi?id=136216

Reviewed by Martin Robinson.

Add the WaylandDisplay class. This class is used in the LayerTreeHostGtk,
in the WebProcess, and controls the connection to the nested Wayland
compositor in the UIProcess. Only one instance of the class is used in the
WebProcess, accessible via the static WaylandDisplay::instance() method.

The WaylandDisplay constructor performs the EGL initialization while also
querying the Wayland register, resulting in initializing client-side objects
that can interact with the wl_compositor and wl_webkitgtk interfaces
implemented in the nested Wayland compositor. The single class instance is
only deemed properly initialized if it picked up the Wayland interface objects
and has properly acquired the EGL display and config.

WaylandDisplay::createSurface() is called by the LayerTreeHostGtk during
its own initialization. The method creates a new wl_surface object via the
wl_compositor interface and a new wl_egl_window object that's based on that
surface. For the wl_egl_window object, we fall back to a width or height of 1
in case the passed-in value for either is 0. This avoids problems in Mesa
where widths or heights of 0 are not supported.

We associate the created surface with the passed-in widget ID, as provided
by LayerTreeHostGtk, via the wl_webkitgtk interface. This enables proper
mapping of Wayland surfaces and the GtkWidgets in the UIProcess and makes
it possible for the nested Wayland compositor to correctly determine which
GtkWidget has to be redrawn after some surface has been committed.

WaylandDisplay::createSharingGLContext() creates a new GLContextEGL object
that's to be used as a sharing context. The method creates a new surface
via the wl_compositor interface and uses it to create a dummy native EGL
window that's 1x1px in size. The GLContextEGL object is then created
through the static GLContextEGL::createWindowContext() method.

* PlatformGTK.cmake:
* platform/graphics/wayland/WaylandDisplay.cpp: Added.
(WebCore::WaylandDisplay::globalCallback):
(WebCore::WaylandDisplay::globalRemoveCallback):
(WebCore::WaylandDisplay::instance):
(WebCore::WaylandDisplay::WaylandDisplay):
(WebCore::WaylandDisplay::createSurface):
(WebCore::WaylandDisplay::createSharingGLContext):
* platform/graphics/wayland/WaylandDisplay.h: Added.
(WebCore::WaylandDisplay::nativeDisplay):
(WebCore::WaylandDisplay::eglDisplay):
* platform/graphics/wayland/WaylandSurface.cpp:
(WebCore::WaylandSurface::~WaylandSurface): Assert that the WaylandDisplay
instance is present before going on to destroy the surface resources.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (173650 => 173651)


--- trunk/Source/WebCore/ChangeLog	2014-09-16 06:26:57 UTC (rev 173650)
+++ trunk/Source/WebCore/ChangeLog	2014-09-16 06:53:30 UTC (rev 173651)
@@ -1,3 +1,56 @@
+2014-09-15  Iago Toral  <[email protected]> and Zan Dobersek  <[email protected]>
+
+        [GTK] Add WaylandDisplay
+        https://bugs.webkit.org/show_bug.cgi?id=136216
+
+        Reviewed by Martin Robinson.
+
+        Add the WaylandDisplay class. This class is used in the LayerTreeHostGtk,
+        in the WebProcess, and controls the connection to the nested Wayland
+        compositor in the UIProcess. Only one instance of the class is used in the
+        WebProcess, accessible via the static WaylandDisplay::instance() method.
+
+        The WaylandDisplay constructor performs the EGL initialization while also
+        querying the Wayland register, resulting in initializing client-side objects
+        that can interact with the wl_compositor and wl_webkitgtk interfaces
+        implemented in the nested Wayland compositor. The single class instance is
+        only deemed properly initialized if it picked up the Wayland interface objects
+        and has properly acquired the EGL display and config.
+
+        WaylandDisplay::createSurface() is called by the LayerTreeHostGtk during
+        its own initialization. The method creates a new wl_surface object via the
+        wl_compositor interface and a new wl_egl_window object that's based on that
+        surface. For the wl_egl_window object, we fall back to a width or height of 1
+        in case the passed-in value for either is 0. This avoids problems in Mesa
+        where widths or heights of 0 are not supported.
+
+        We associate the created surface with the passed-in widget ID, as provided
+        by LayerTreeHostGtk, via the wl_webkitgtk interface. This enables proper
+        mapping of Wayland surfaces and the GtkWidgets in the UIProcess and makes
+        it possible for the nested Wayland compositor to correctly determine which
+        GtkWidget has to be redrawn after some surface has been committed.
+
+        WaylandDisplay::createSharingGLContext() creates a new GLContextEGL object
+        that's to be used as a sharing context. The method creates a new surface
+        via the wl_compositor interface and uses it to create a dummy native EGL
+        window that's 1x1px in size. The GLContextEGL object is then created
+        through the static GLContextEGL::createWindowContext() method.
+
+        * PlatformGTK.cmake:
+        * platform/graphics/wayland/WaylandDisplay.cpp: Added.
+        (WebCore::WaylandDisplay::globalCallback):
+        (WebCore::WaylandDisplay::globalRemoveCallback):
+        (WebCore::WaylandDisplay::instance):
+        (WebCore::WaylandDisplay::WaylandDisplay):
+        (WebCore::WaylandDisplay::createSurface):
+        (WebCore::WaylandDisplay::createSharingGLContext):
+        * platform/graphics/wayland/WaylandDisplay.h: Added.
+        (WebCore::WaylandDisplay::nativeDisplay):
+        (WebCore::WaylandDisplay::eglDisplay):
+        * platform/graphics/wayland/WaylandSurface.cpp:
+        (WebCore::WaylandSurface::~WaylandSurface): Assert that the WaylandDisplay
+        instance is present before going on to destroy the surface resources.
+
 2014-09-15  Chris Dumez  <[email protected]>
 
         Rename LiveNodeLists / HTMLCollections's nodeMatches() to elementMatches()

Modified: trunk/Source/WebCore/PlatformGTK.cmake (173650 => 173651)


--- trunk/Source/WebCore/PlatformGTK.cmake	2014-09-16 06:26:57 UTC (rev 173650)
+++ trunk/Source/WebCore/PlatformGTK.cmake	2014-09-16 06:53:30 UTC (rev 173651)
@@ -430,6 +430,7 @@
 
 if (ENABLE_WAYLAND_TARGET)
     list(APPEND WebCorePlatformGTK_SOURCES
+        platform/graphics/wayland/WaylandDisplay.cpp
         platform/graphics/wayland/WaylandEventSource.cpp
         platform/graphics/wayland/WaylandSurface.cpp
 

Added: trunk/Source/WebCore/platform/graphics/wayland/WaylandDisplay.cpp (0 => 173651)


--- trunk/Source/WebCore/platform/graphics/wayland/WaylandDisplay.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/wayland/WaylandDisplay.cpp	2014-09-16 06:53:30 UTC (rev 173651)
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WaylandDisplay.h"
+
+#if PLATFORM(WAYLAND)
+
+#include "GLContextEGL.h"
+#include "WaylandSurface.h"
+#include <cstring>
+#include <glib.h>
+
+namespace WebCore {
+
+const struct wl_registry_listener WaylandDisplay::m_registryListener = {
+    WaylandDisplay::globalCallback,
+    WaylandDisplay::globalRemoveCallback
+};
+
+void WaylandDisplay::globalCallback(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t)
+{
+    auto display = static_cast<WaylandDisplay*>(data);
+    if (!std::strcmp(interface, "wl_compositor"))
+        display->m_compositor = static_cast<struct wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, 1));
+    else if (!std::strcmp(interface, "wl_webkitgtk"))
+        display->m_webkitgtk = static_cast<struct wl_webkitgtk*>(wl_registry_bind(registry, name, &wl_webkitgtk_interface, 1));
+}
+
+void WaylandDisplay::globalRemoveCallback(void*, struct wl_registry*, uint32_t)
+{
+    // FIXME: if this can happen without the UI Process getting shut down
+    // we should probably destroy our cached display instance.
+}
+
+WaylandDisplay* WaylandDisplay::instance()
+{
+    static WaylandDisplay* display = nullptr;
+    static bool initialized = false;
+    if (initialized)
+        return display;
+
+    initialized = true;
+    struct wl_display* wlDisplay = wl_display_connect("webkitgtk-wayland-compositor-socket");
+    if (!wlDisplay)
+        return nullptr;
+
+    display = new WaylandDisplay(wlDisplay);
+    if (!display->isInitialized()) {
+        delete display;
+        return nullptr;
+    }
+
+    return display;
+}
+
+WaylandDisplay::WaylandDisplay(struct wl_display* wlDisplay)
+    : m_display(wlDisplay)
+    , m_registry(wl_display_get_registry(m_display))
+    , m_eglConfigChosen(false)
+{
+    wl_registry_add_listener(m_registry, &m_registryListener, this);
+    wl_display_roundtrip(m_display);
+
+    static const EGLint configAttributes[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_RED_SIZE, 1,
+        EGL_GREEN_SIZE, 1,
+        EGL_BLUE_SIZE, 1,
+        EGL_ALPHA_SIZE, 1,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_NONE
+    };
+
+    m_eglDisplay = eglGetDisplay(m_display);
+    if (m_eglDisplay == EGL_NO_DISPLAY) {
+        g_warning("WaylandDisplay initialization: failed to acquire EGL display.");
+        return;
+    }
+
+    if (eglInitialize(m_eglDisplay, 0, 0) == EGL_FALSE) {
+        g_warning("WaylandDisplay initialization: failed to initialize the EGL display.");
+        return;
+    }
+
+    if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
+        g_warning("WaylandDisplay initialization: failed to set EGL_OPENGL_ES_API as the rendering API.");
+        return;
+    }
+
+    EGLint numberOfConfigs;
+    if (!eglChooseConfig(m_eglDisplay, configAttributes, &m_eglConfig, 1, &numberOfConfigs) || numberOfConfigs != 1) {
+        g_warning("WaylandDisplay initialization: failed to find the desired EGL configuration.");
+        return;
+    }
+
+    m_eglConfigChosen = true;
+}
+
+std::unique_ptr<WaylandSurface> WaylandDisplay::createSurface(const IntSize& size, int widgetId)
+{
+    struct wl_surface* wlSurface = wl_compositor_create_surface(m_compositor);
+    // We keep the minimum size at 1x1px since Mesa returns null values in wl_egl_window_create() for zero width or height.
+    EGLNativeWindowType nativeWindow = wl_egl_window_create(wlSurface, std::max(1, size.width()), std::max(1, size.height()));
+
+    wl_webkitgtk_set_surface_for_widget(m_webkitgtk, wlSurface, widgetId);
+    wl_display_roundtrip(m_display);
+
+    return std::make_unique<WaylandSurface>(wlSurface, nativeWindow);
+}
+
+PassOwnPtr<GLContextEGL> WaylandDisplay::createSharingGLContext()
+{
+    struct wl_surface* wlSurface = wl_compositor_create_surface(m_compositor);
+    EGLNativeWindowType nativeWindow = wl_egl_window_create(wlSurface, 1, 1);
+    return GLContextEGL::createWindowContext(nativeWindow, nullptr);
+}
+
+} // namespace WebCore
+
+#endif // PLATFORM(WAYLAND)

Added: trunk/Source/WebCore/platform/graphics/wayland/WaylandDisplay.h (0 => 173651)


--- trunk/Source/WebCore/platform/graphics/wayland/WaylandDisplay.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/wayland/WaylandDisplay.h	2014-09-16 06:53:30 UTC (rev 173651)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef  WaylandDisplay_h
+#define  WaylandDisplay_h
+
+#if PLATFORM(WAYLAND)
+
+#include "WebKitGtkWaylandClientProtocol.h"
+#include <memory>
+#include <wayland-client.h>
+#include <wtf/PassOwnPtr.h>
+
+#include <wayland-egl.h>
+#include <EGL/egl.h>
+
+namespace WebCore {
+
+class GLContextEGL;
+class IntSize;
+class WaylandSurface;
+
+class WaylandDisplay {
+public:
+    static WaylandDisplay* instance();
+
+    struct wl_display* nativeDisplay() const { return m_display; }
+    EGLDisplay eglDisplay() const { return m_eglDisplay; }
+
+    std::unique_ptr<WaylandSurface> createSurface(const IntSize&, int widgetID);
+
+    PassOwnPtr<GLContextEGL> createSharingGLContext();
+
+private:
+    static const struct wl_registry_listener m_registryListener;
+    static void globalCallback(void* data, struct wl_registry*, uint32_t name, const char* interface, uint32_t version);
+    static void globalRemoveCallback(void* data, struct wl_registry*, uint32_t name);
+
+    WaylandDisplay(struct wl_display*);
+    bool isInitialized() { return m_compositor && m_webkitgtk && m_eglDisplay != EGL_NO_DISPLAY && m_eglConfigChosen; }
+
+    struct wl_display* m_display;
+    struct wl_registry* m_registry;
+    struct wl_compositor* m_compositor;
+    struct wl_webkitgtk* m_webkitgtk;
+
+    EGLDisplay m_eglDisplay;
+    EGLConfig m_eglConfig;
+    bool m_eglConfigChosen;
+};
+
+} // namespace WebCore
+
+#endif // PLATFORM(WAYLAND)
+
+#endif // WaylandDisplay_h

Modified: trunk/Source/WebCore/platform/graphics/wayland/WaylandSurface.cpp (173650 => 173651)


--- trunk/Source/WebCore/platform/graphics/wayland/WaylandSurface.cpp	2014-09-16 06:26:57 UTC (rev 173650)
+++ trunk/Source/WebCore/platform/graphics/wayland/WaylandSurface.cpp	2014-09-16 06:53:30 UTC (rev 173651)
@@ -53,6 +53,8 @@
 
 WaylandSurface::~WaylandSurface()
 {
+    // The surface couldn't have been created in the first place if WaylandDisplay wasn't properly initialized.
+    ASSERT(WaylandDisplay::instance());
     eglMakeCurrent(WaylandDisplay::instance()->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 
     wl_egl_window_destroy(m_nativeWindow);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to