Source/WebCore/ChangeLog

 12014-08-31 Iago Toral <itoral@igalia.com> and Zan Dobersek <zdobersek@igalia.com>
 2
 3 [GTK] Add WaylandDisplay
 4 https://bugs.webkit.org/show_bug.cgi?id=136216
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Add the WaylandDisplay class. This class is used in the LayerTreeHostGtk,
 9 in the WebProcess, and controls the connection to the nested Wayland
 10 compositor in the UIProcess. Only one instance of the class is used in the
 11 WebProcess, accessible via the static WaylandDisplay::instance() method.
 12
 13 The WaylandDisplay constructor performs the EGL initialization while also
 14 querying the Wayland register, resulting in initializing client-side objects
 15 that can interact with the wl_compositor and wl_webkitgtk interfaces
 16 implemented in the nested Wayland compositor. The single class instance is
 17 only deemed properly initialized if it picked up the Wayland interface objects
 18 and has properly acquired the EGL display and config.
 19
 20 WaylandDisplay::createSurface() is called by the LayerTreeHostGtk during
 21 its own initialization. The method creates a new wl_surface object via the
 22 wl_compositor interface and a new wl_egl_window object that's based on that
 23 surface. For the wl_egl_window object, we fall back to a width or height of 1
 24 in case the passed-in value for either is 0. This avoids problems in Mesa
 25 where widths or heights of 0 are not supported.
 26
 27 We associate the created surface with the passed-in widget ID, as provided
 28 by LayerTreeHostGtk, via the wl_webkitgtk interface. This enables proper
 29 mapping of Wayland surfaces and the GtkWidgets in the UIProcess and makes
 30 it possible for the nested Wayland compositor to correctly determine which
 31 GtkWidget has to be redrawn after some surface has been committed.
 32
 33 WaylandDisplay::createSharingGLContext() creates a new GLContextEGL object
 34 that's to be used as a sharing context. The method creates a new surface
 35 via the wl_compositor interface and uses it to create a dummy native EGL
 36 window that's 1x1px in size. The GLContextEGL object is then created
 37 through the static GLContextEGL::createWindowContext() method.
 38
 39 * PlatformGTK.cmake:
 40 * platform/graphics/wayland/WaylandDisplay.cpp: Added.
 41 (WebCore::WaylandDisplay::globalCallback):
 42 (WebCore::WaylandDisplay::globalRemoveCallback):
 43 (WebCore::WaylandDisplay::instance):
 44 (WebCore::WaylandDisplay::WaylandDisplay):
 45 (WebCore::WaylandDisplay::createSurface):
 46 (WebCore::WaylandDisplay::createSharingGLContext):
 47 * platform/graphics/wayland/WaylandDisplay.h: Added.
 48 (WebCore::WaylandDisplay::nativeDisplay):
 49 (WebCore::WaylandDisplay::eglDisplay):
 50 * platform/graphics/wayland/WaylandSurface.cpp:
 51 (WebCore::WaylandSurface::~WaylandSurface): Assert that the WaylandDisplay
 52 instance is present before going on to destroy the surface resources.
 53
1542014-08-31 Gyuyoung Kim <gyuyoung.kim@samsung.com>
255
356 Unreviewed, fix build break on EFL and GTK since r173152.
173153

Source/WebCore/PlatformGTK.cmake

@@add_custom_command(
430430
431431if (ENABLE_WAYLAND_TARGET)
432432 list(APPEND WebCorePlatformGTK_SOURCES
 433 platform/graphics/wayland/WaylandDisplay.cpp
433434 platform/graphics/wayland/WaylandEventSource.cpp
434435 platform/graphics/wayland/WaylandSurface.cpp
435436
173153

Source/WebCore/platform/graphics/wayland/WaylandDisplay.cpp

 1/*
 2 * Copyright (C) 2014 Igalia S.L.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "WaylandDisplay.h"
 28
 29#if PLATFORM(WAYLAND)
 30
 31#include "GLContextEGL.h"
 32#include "WaylandSurface.h"
 33#include <cstring>
 34#include <glib.h>
 35
 36namespace WebCore {
 37
 38const struct wl_registry_listener WaylandDisplay::m_registryListener = {
 39 WaylandDisplay::globalCallback,
 40 WaylandDisplay::globalRemoveCallback
 41};
 42
 43void WaylandDisplay::globalCallback(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t)
 44{
 45 auto display = static_cast<WaylandDisplay*>(data);
 46 if (!std::strcmp(interface, "wl_compositor"))
 47 display->m_compositor = static_cast<struct wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, 1));
 48 else if (!std::strcmp(interface, "wl_webkitgtk"))
 49 display->m_webkitgtk = static_cast<struct wl_webkitgtk*>(wl_registry_bind(registry, name, &wl_webkitgtk_interface, 1));
 50}
 51
 52void WaylandDisplay::globalRemoveCallback(void*, struct wl_registry*, uint32_t)
 53{
 54 // FIXME: if this can happen without the UI Process getting shut down
 55 // we should probably destroy our cached display instance.
 56}
 57
 58WaylandDisplay* WaylandDisplay::instance()
 59{
 60 static WaylandDisplay* display = nullptr;
 61 static bool initialized = false;
 62 if (initialized)
 63 return display;
 64
 65 initialized = true;
 66 struct wl_display* wlDisplay = wl_display_connect("webkitgtk-wayland-compositor-socket");
 67 if (!wlDisplay)
 68 return nullptr;
 69
 70 display = new WaylandDisplay(wlDisplay);
 71 if (!display->isInitialized()) {
 72 delete display;
 73 return nullptr;
 74 }
 75
 76 return display;
 77}
 78
 79WaylandDisplay::WaylandDisplay(struct wl_display* wlDisplay)
 80 : m_display(wlDisplay)
 81 , m_registry(wl_display_get_registry(m_display))
 82 , m_eglConfigChosen(false)
 83{
 84 wl_registry_add_listener(m_registry, &m_registryListener, this);
 85 wl_display_roundtrip(m_display);
 86
 87 static const EGLint configAttributes[] = {
 88 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
 89 EGL_RED_SIZE, 1,
 90 EGL_GREEN_SIZE, 1,
 91 EGL_BLUE_SIZE, 1,
 92 EGL_ALPHA_SIZE, 1,
 93 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
 94 EGL_NONE
 95 };
 96
 97 m_eglDisplay = eglGetDisplay(m_display);
 98 if (m_eglDisplay == EGL_NO_DISPLAY) {
 99 g_warning("WaylandDisplay initialization: failed to acquire EGL display.");
 100 return;
 101 }
 102
 103 if (eglInitialize(m_eglDisplay, 0, 0) == EGL_FALSE) {
 104 g_warning("WaylandDisplay initialization: failed to initialize the EGL display.");
 105 return;
 106 }
 107
 108 if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
 109 g_warning("WaylandDisplay initialization: failed to set EGL_OPENGL_ES_API as the rendering API.");
 110 return;
 111 }
 112
 113 EGLint numberOfConfigs;
 114 if (!eglChooseConfig(m_eglDisplay, configAttributes, &m_eglConfig, 1, &numberOfConfigs) || numberOfConfigs != 1) {
 115 g_warning("WaylandDisplay initialization: failed to find the desired EGL configuration.");
 116 return;
 117 }
 118
 119 m_eglConfigChosen = true;
 120}
 121
 122std::unique_ptr<WaylandSurface> WaylandDisplay::createSurface(const IntSize& size, int widgetId)
 123{
 124 struct wl_surface* wlSurface = wl_compositor_create_surface(m_compositor);
 125 // We keep the minimum size at 1x1px since Mesa returns null values in wl_egl_window_create() for zero width or height.
 126 EGLNativeWindowType nativeWindow = wl_egl_window_create(wlSurface, std::max(1, size.width()), std::max(1, size.height()));
 127
 128 wl_webkitgtk_set_surface_for_widget(m_webkitgtk, wlSurface, widgetId);
 129 wl_display_roundtrip(m_display);
 130
 131 return std::make_unique<WaylandSurface>(wlSurface, nativeWindow);
 132}
 133
 134PassOwnPtr<GLContextEGL> WaylandDisplay::createSharingGLContext()
 135{
 136 struct wl_surface* wlSurface = wl_compositor_create_surface(m_compositor);
 137 EGLNativeWindowType nativeWindow = wl_egl_window_create(wlSurface, 1, 1);
 138 return GLContextEGL::createWindowContext(nativeWindow, nullptr);
 139}
 140
 141} // namespace WebCore
 142
 143#endif // PLATFORM(WAYLAND)
0

Source/WebCore/platform/graphics/wayland/WaylandDisplay.h

 1/*
 2 * Copyright (C) 2014 Igalia S.L.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef WaylandDisplay_h
 27#define WaylandDisplay_h
 28
 29#if PLATFORM(WAYLAND)
 30
 31#include "WebKitGtkWaylandClientProtocol.h"
 32#include <memory>
 33#include <wayland-client.h>
 34#include <wtf/PassOwnPtr.h>
 35
 36#include <wayland-egl.h>
 37#include <EGL/egl.h>
 38
 39namespace WebCore {
 40
 41class GLContextEGL;
 42class IntSize;
 43class WaylandSurface;
 44
 45class WaylandDisplay {
 46public:
 47 static WaylandDisplay* instance();
 48
 49 struct wl_display* nativeDisplay() const { return m_display; }
 50 EGLDisplay eglDisplay() const { return m_eglDisplay; }
 51
 52 std::unique_ptr<WaylandSurface> createSurface(const IntSize&, int widgetID);
 53
 54 PassOwnPtr<GLContextEGL> createSharingGLContext();
 55
 56private:
 57 static const struct wl_registry_listener m_registryListener;
 58 static void globalCallback(void* data, struct wl_registry*, uint32_t name, const char* interface, uint32_t version);
 59 static void globalRemoveCallback(void* data, struct wl_registry*, uint32_t name);
 60
 61 WaylandDisplay(struct wl_display*);
 62 bool isInitialized() { return m_compositor && m_webkitgtk && m_eglDisplay != EGL_NO_DISPLAY && m_eglConfigChosen; }
 63
 64 struct wl_display* m_display;
 65 struct wl_registry* m_registry;
 66 struct wl_compositor* m_compositor;
 67 struct wl_webkitgtk* m_webkitgtk;
 68
 69 EGLDisplay m_eglDisplay;
 70 EGLConfig m_eglConfig;
 71 bool m_eglConfigChosen;
 72};
 73
 74} // namespace WebCore
 75
 76#endif // PLATFORM(WAYLAND)
 77
 78#endif // WaylandDisplay_h
0

Source/WebCore/platform/graphics/wayland/WaylandSurface.cpp

@@WaylandSurface::WaylandSurface(struct wl
5353
5454WaylandSurface::~WaylandSurface()
5555{
 56 // The surface couldn't have been created in the first place if WaylandDisplay wasn't properly initialized.
 57 ASSERT(WaylandDisplay::instance());
5658 eglMakeCurrent(WaylandDisplay::instance()->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
5759
5860 wl_egl_window_destroy(m_nativeWindow);
173153