Skip to content

Commit

Permalink
Merge pull request #30 from Igalia/cgarcia/wpe-bridge
Browse files Browse the repository at this point in the history
wpe bridge
  • Loading branch information
zdobersek authored Feb 21, 2019
2 parents 67184f3 + 5b570dc commit 6daf7eb
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 6 deletions.
21 changes: 21 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ find_package(EGL REQUIRED)
find_package(GLIB REQUIRED COMPONENTS gio)
find_package(Wayland REQUIRED)
find_package(WaylandEGL REQUIRED)
find_package(WaylandScanner REQUIRED)
find_package(WPE REQUIRED)

if (EGL_DEFINITIONS)
Expand All @@ -41,6 +42,7 @@ endif ()

set(WPEBACKEND_FDO_INCLUDE_DIRECTORIES
"include"
${CMAKE_BINARY_DIR}
${EGL_INCLUDE_DIRS}
${GLIB_INCLUDE_DIRS}
${WAYLAND_INCLUDE_DIRS}
Expand All @@ -64,18 +66,37 @@ set(WPEBACKEND_FDO_PUBLIC_HEADERS
include/wpe-fdo/fdo.h
)

set(WPEBACKEND_FDO_GENERATED_SOURCES
${CMAKE_BINARY_DIR}/bridge/wpe-bridge-protocol.c
)

set(WPEBACKEND_FDO_SOURCES
${WPEBACKEND_FDO_GENERATED_SOURCES}

src/fdo.cpp
src/initialize-egl.cpp
src/renderer-backend-egl.cpp
src/renderer-host.cpp
src/view-backend-exportable-fdo.cpp
src/view-backend-exportable-private.cpp
src/ws.cpp

src/linux-dmabuf/linux-dmabuf.c
src/linux-dmabuf/linux-dmabuf-protocol.c
)

file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bridge)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/bridge/wpe-bridge-protocol.c
${CMAKE_BINARY_DIR}/bridge/wpe-bridge-client-protocol.h
${CMAKE_BINARY_DIR}/bridge/wpe-bridge-server-protocol.h
DEPENDS ${CMAKE_SOURCE_DIR}/src/bridge/wpe-bridge.xml
COMMAND ${WAYLAND_SCANNER} ${WAYLAND_SCANNER_CODE_ARG} < ${CMAKE_SOURCE_DIR}/src/bridge/wpe-bridge.xml > ${CMAKE_BINARY_DIR}/bridge/wpe-bridge-protocol.c
COMMAND ${WAYLAND_SCANNER} client-header < ${CMAKE_SOURCE_DIR}/src/bridge/wpe-bridge.xml > ${CMAKE_BINARY_DIR}/bridge/wpe-bridge-client-protocol.h
COMMAND ${WAYLAND_SCANNER} server-header < ${CMAKE_SOURCE_DIR}/src/bridge/wpe-bridge.xml > ${CMAKE_BINARY_DIR}/bridge/wpe-bridge-server-protocol.h
VERBATIM
)

option(EXPORTABLE_EGL "Enable the exportable EGL interface" ON)

if (EXPORTABLE_EGL)
Expand Down
42 changes: 42 additions & 0 deletions cmake/FindWaylandScanner.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# - Try to find wayland-scanner.
# Once done, this will define
#
# WAYLAND_SCANNER_FOUND - system has Wayland.
# WAYLAND_SCANNER - the path to the wayland-scanner binary
# WAYLAND_SCANNER_CODE_ARG - the code argument to pass
#
# Copyright (C) 2019 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 THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``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 THE COPYRIGHT HOLDER OR ITS
# 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.

find_package(PkgConfig)
pkg_check_modules(WAYLAND_SCANNER wayland-scanner)

pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner)
if (WAYLAND_SCANNER_VERSION VERSION_LESS "1.15")
set(WAYLAND_SCANNER_CODE_ARG "code")
else ()
set(WAYLAND_SCANNER_CODE_ARG "private-code")
endif ()

include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SCANNER DEFAULT_MSG WAYLAND_SCANNER)
40 changes: 40 additions & 0 deletions src/bridge/wpe-bridge.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="wpe_bridge">

<copyright>
Copyright © 2019 Igalia S.L.

Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
the copyright holders not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission. The copyright holders make no
representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied
warranty.

THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
</copyright>

<interface name="wpe_bridge" version="1">
<request name="connect">
<arg name="surface" type="object" interface="wl_surface"/>
</request>

<event name="connected">
<arg name="id" type="uint"/>
</event>

</interface>

</protocol>
30 changes: 25 additions & 5 deletions src/renderer-backend-egl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include "interfaces.h"

#include "bridge/wpe-bridge-client-protocol.h"
#include <cstring>
#include <gio/gio.h>
#include <glib.h>
Expand Down Expand Up @@ -142,6 +143,7 @@ class Target {
g_clear_pointer(&m_wl.window, wl_egl_window_destroy);
g_clear_pointer(&m_wl.surface, wl_surface_destroy);

g_clear_pointer(&m_wl.wpeBridge, wpe_bridge_destroy);
g_clear_pointer(&m_wl.compositor, wl_compositor_destroy);
g_clear_pointer(&m_wl.registry, wl_registry_destroy);
g_clear_pointer(&m_wl.eventQueue, wl_event_queue_destroy);
Expand Down Expand Up @@ -170,7 +172,6 @@ class Target {
m_wl.surface = wl_compositor_create_surface(m_wl.compositor);
wl_proxy_set_queue(reinterpret_cast<struct wl_proxy*>(m_wl.surface), m_wl.eventQueue);
m_wl.window = wl_egl_window_create(m_wl.surface, width, height);
wl_display_roundtrip_queue(display, m_wl.eventQueue);

m_glib.wlSource = g_source_new(&Source::s_sourceFuncs, sizeof(Source));
{
Expand Down Expand Up @@ -203,10 +204,9 @@ class Target {
}, this, nullptr);
g_source_attach(m_glib.frameSource, g_main_context_get_thread_default());

uint32_t message[] = { 0x42, wl_proxy_get_id(reinterpret_cast<struct wl_proxy*>(m_wl.surface)) };
if (m_glib.socket)
g_socket_send(m_glib.socket, reinterpret_cast<gchar*>(message), 2 * sizeof(uint32_t),
nullptr, nullptr);
wpe_bridge_add_listener(m_wl.wpeBridge, &s_bridgeListener, this);
wpe_bridge_connect(m_wl.wpeBridge, m_wl.surface);
wl_display_roundtrip_queue(display, m_wl.eventQueue);
}

void requestFrame()
Expand All @@ -223,11 +223,20 @@ class Target {
g_source_set_ready_time(m_glib.frameSource, 0);
}

void bridgeConnected(uint32_t bridgeID)
{
uint32_t message[] = { 0x42, bridgeID };
if (m_glib.socket)
g_socket_send(m_glib.socket, reinterpret_cast<gchar*>(message), 2 * sizeof(uint32_t), nullptr, nullptr);
}

struct wl_egl_window* window() const { return m_wl.window; }

private:
static const struct wl_registry_listener s_registryListener;
static const struct wl_callback_listener s_callbackListener;
static const struct wpe_bridge_listener s_bridgeListener;

static GSourceFuncs s_sourceFuncs;

struct wpe_renderer_backend_egl_target* m_target { nullptr };
Expand All @@ -243,6 +252,7 @@ class Target {
struct wl_event_queue* eventQueue { nullptr };
struct wl_registry* registry { nullptr };
struct wl_compositor* compositor { nullptr };
struct wpe_bridge* wpeBridge { nullptr };

struct wl_surface* surface { nullptr };
struct wl_egl_window* window { nullptr };
Expand All @@ -258,6 +268,8 @@ const struct wl_registry_listener Target::s_registryListener = {

if (!std::strcmp(interface, "wl_compositor"))
target.m_wl.compositor = static_cast<struct wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, 1));
if (!std::strcmp(interface, "wpe_bridge"))
target.m_wl.wpeBridge = static_cast<struct wpe_bridge*>(wl_registry_bind(registry, name, &wpe_bridge_interface, 1));
},
// global_remove
[](void*, struct wl_registry*, uint32_t) { },
Expand All @@ -271,6 +283,14 @@ const struct wl_callback_listener Target::s_callbackListener = {
},
};

const struct wpe_bridge_listener Target::s_bridgeListener = {
// connected
[](void* data, struct wpe_bridge*, uint32_t id)
{
static_cast<Target*>(data)->bridgeConnected(id);
},
};

GSourceFuncs Target::s_sourceFuncs = {
nullptr, // prepare
nullptr, // check
Expand Down
28 changes: 27 additions & 1 deletion src/ws.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include "linux-dmabuf/linux-dmabuf.h"
#include "bridge/wpe-bridge-server-protocol.h"
#include <sys/socket.h>
#include <unistd.h>

Expand Down Expand Up @@ -167,7 +168,6 @@ static const struct wl_compositor_interface s_compositorInterface = {
auto* surface = new Surface;
surface->client = client;
surface->id = id;
Instance::singleton().createSurface(id, surface);
wl_resource_set_implementation(surfaceResource, &s_surfaceInterface, surface,
[](struct wl_resource* resource)
{
Expand All @@ -179,6 +179,21 @@ static const struct wl_compositor_interface s_compositorInterface = {
[](struct wl_client*, struct wl_resource*, uint32_t) { },
};

static const struct wpe_bridge_interface s_wpeBridgeInterface = {
// connect
[](struct wl_client*, struct wl_resource* resource, struct wl_resource* surfaceResource)
{
auto* surface = static_cast<Surface*>(wl_resource_get_user_data(surfaceResource));
if (!surface)
return;

static uint32_t bridgeID = 0;
++bridgeID;
wpe_bridge_send_connected(resource, bridgeID);
Instance::singleton().createSurface(bridgeID, surface);
},
};

Instance& Instance::singleton()
{
static Instance* s_singleton;
Expand All @@ -203,6 +218,17 @@ Instance::Instance()

wl_resource_set_implementation(resource, &s_compositorInterface, nullptr, nullptr);
});
m_wpeBridge = wl_global_create(m_display, &wpe_bridge_interface, 1, this,
[](struct wl_client* client, void*, uint32_t version, uint32_t id)
{
struct wl_resource* resource = wl_resource_create(client, &wpe_bridge_interface, version, id);
if (!resource) {
wl_client_post_no_memory(client);
return;
}

wl_resource_set_implementation(resource, &s_wpeBridgeInterface, nullptr, nullptr);
});

auto& source = *reinterpret_cast<Source*>(m_source);

Expand Down
1 change: 1 addition & 0 deletions src/ws.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class Instance {

struct wl_display* m_display;
struct wl_global* m_compositor;
struct wl_global* m_wpeBridge;
GSource* m_source;

std::unordered_map<uint32_t, Surface*> m_viewBackendMap;
Expand Down

0 comments on commit 6daf7eb

Please sign in to comment.