Stop crashing after process swap
This commit is contained in:
parent
cf71752886
commit
1b26ebec47
@ -0,0 +1,76 @@
|
|||||||
|
From 951ce45d4c229a4f6abea39acd4f7dc759d9ef10 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Catanzaro <mcatanzaro@gnome.org>
|
||||||
|
Date: Fri, 9 Apr 2021 13:10:02 -0500
|
||||||
|
Subject: [PATCH 01/13] Add some checks to ensure we properly bind server
|
||||||
|
globals
|
||||||
|
|
||||||
|
If we fail to bind any global objects, we are going to crash. Let's do
|
||||||
|
that as nicely as possible using g_error(), rather than dereferencing
|
||||||
|
null pointers later on.
|
||||||
|
|
||||||
|
Suggested by #145
|
||||||
|
|
||||||
|
(cherry picked from commit a4eb79d12fc851ea7cef616afa0d77668e83ea61)
|
||||||
|
---
|
||||||
|
src/extensions/audio.cpp | 3 +++
|
||||||
|
src/extensions/video-plane-display-dmabuf.cpp | 3 +++
|
||||||
|
src/ws-client.cpp | 8 ++++++++
|
||||||
|
3 files changed, 14 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/extensions/audio.cpp b/src/extensions/audio.cpp
|
||||||
|
index b3043ac..5d2dd91 100644
|
||||||
|
--- a/src/extensions/audio.cpp
|
||||||
|
+++ b/src/extensions/audio.cpp
|
||||||
|
@@ -159,6 +159,9 @@ public:
|
||||||
|
wl_display_roundtrip_queue(display, eventQueue);
|
||||||
|
wl_registry_destroy(registry);
|
||||||
|
|
||||||
|
+ if (!m_wl.audio)
|
||||||
|
+ g_error("Failed to bind wpe_audio");
|
||||||
|
+
|
||||||
|
wl_event_queue_destroy(eventQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/extensions/video-plane-display-dmabuf.cpp b/src/extensions/video-plane-display-dmabuf.cpp
|
||||||
|
index 953cb4c..96fabcf 100644
|
||||||
|
--- a/src/extensions/video-plane-display-dmabuf.cpp
|
||||||
|
+++ b/src/extensions/video-plane-display-dmabuf.cpp
|
||||||
|
@@ -159,6 +159,9 @@ public:
|
||||||
|
wl_display_roundtrip_queue(display, eventQueue);
|
||||||
|
wl_registry_destroy(registry);
|
||||||
|
|
||||||
|
+ if (!m_wl.videoPlaneDisplayDmaBuf)
|
||||||
|
+ g_error("Failed to bind wpe_video_plane_display_dmabuf");
|
||||||
|
+
|
||||||
|
wl_event_queue_destroy(eventQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/ws-client.cpp b/src/ws-client.cpp
|
||||||
|
index 6dc98ca..4ffa090 100644
|
||||||
|
--- a/src/ws-client.cpp
|
||||||
|
+++ b/src/ws-client.cpp
|
||||||
|
@@ -126,6 +126,9 @@ BaseBackend::BaseBackend(int hostFD)
|
||||||
|
wl_display_roundtrip(m_wl.display);
|
||||||
|
wl_registry_destroy(registry);
|
||||||
|
|
||||||
|
+ if (!m_wl.wpeBridge)
|
||||||
|
+ g_error("Failed to bind wpe_bridge");
|
||||||
|
+
|
||||||
|
wpe_bridge_add_listener(m_wl.wpeBridge, &s_bridgeListener, this);
|
||||||
|
wpe_bridge_initialize(m_wl.wpeBridge);
|
||||||
|
wl_display_roundtrip(m_wl.display);
|
||||||
|
@@ -204,6 +207,11 @@ void BaseTarget::initialize(BaseBackend& backend)
|
||||||
|
wl_display_roundtrip_queue(display, m_wl.eventQueue);
|
||||||
|
wl_registry_destroy(registry);
|
||||||
|
|
||||||
|
+ if (!m_wl.compositor)
|
||||||
|
+ g_error("Failed to bind wl_compositor");
|
||||||
|
+ if (!m_wl.wpeBridge)
|
||||||
|
+ g_error("Failed to bind wpe_bridge");
|
||||||
|
+
|
||||||
|
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);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
63
0002-ws-Remove-unneeded-Surface-id-member.patch
Normal file
63
0002-ws-Remove-unneeded-Surface-id-member.patch
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
From 6963a05959d8be52d4b8ee0cafc49da72a04a6dd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Perez de Castro <aperez@igalia.com>
|
||||||
|
Date: Tue, 13 Apr 2021 00:30:08 +0300
|
||||||
|
Subject: [PATCH 02/13] ws: Remove unneeded Surface::id member
|
||||||
|
|
||||||
|
The Wayland resource identifier is not used at the moment, and moreover
|
||||||
|
if ever needed wl_resource_get_id(surface->bufferResource) can be used
|
||||||
|
to retrieve it.
|
||||||
|
|
||||||
|
(cherry picked from commit 55d05be5529635b7797f34b3e9871612909859fc)
|
||||||
|
---
|
||||||
|
src/ws.cpp | 6 ++----
|
||||||
|
src/ws.h | 9 ++++++---
|
||||||
|
2 files changed, 8 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/ws.cpp b/src/ws.cpp
|
||||||
|
index 5602595..c23e53c 100644
|
||||||
|
--- a/src/ws.cpp
|
||||||
|
+++ b/src/ws.cpp
|
||||||
|
@@ -144,9 +144,7 @@ static const struct wl_compositor_interface s_compositorInterface = {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- auto* surface = new Surface;
|
||||||
|
- surface->client = client;
|
||||||
|
- surface->id = id;
|
||||||
|
+ auto* surface = new Surface {surfaceResource};
|
||||||
|
wl_resource_set_implementation(surfaceResource, &s_surfaceInterface, surface,
|
||||||
|
[](struct wl_resource* resource)
|
||||||
|
{
|
||||||
|
@@ -524,7 +522,7 @@ struct wl_client* Instance::registerViewBackend(uint32_t surfaceId, APIClient& a
|
||||||
|
g_error("Instance::registerViewBackend(): " "Cannot find surface %" PRIu32 " in view backend map.", surfaceId);
|
||||||
|
|
||||||
|
it->second->apiClient = &apiClient;
|
||||||
|
- return it->second->client;
|
||||||
|
+ return wl_resource_get_client(it->second->resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instance::unregisterViewBackend(uint32_t surfaceId)
|
||||||
|
diff --git a/src/ws.h b/src/ws.h
|
||||||
|
index d4376c4..683b679 100644
|
||||||
|
--- a/src/ws.h
|
||||||
|
+++ b/src/ws.h
|
||||||
|
@@ -48,10 +48,13 @@ struct APIClient {
|
||||||
|
virtual void exportEGLStreamProducer(struct wl_resource*) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
-struct Surface;
|
||||||
|
struct Surface {
|
||||||
|
- uint32_t id { 0 };
|
||||||
|
- struct wl_client* client { nullptr };
|
||||||
|
+ explicit Surface(struct wl_resource* surfaceResource):
|
||||||
|
+ resource {surfaceResource}
|
||||||
|
+ {
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ struct wl_resource* resource;
|
||||||
|
|
||||||
|
APIClient* apiClient { nullptr };
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
135
0003-ws-Rename-surfaceId-to-bridgeId-where-appropriate.patch
Normal file
135
0003-ws-Rename-surfaceId-to-bridgeId-where-appropriate.patch
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
From 2722e7369ae746cc71604bcd13e1f4c6dd5816c3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Perez de Castro <aperez@igalia.com>
|
||||||
|
Date: Tue, 13 Apr 2021 01:06:41 +0300
|
||||||
|
Subject: [PATCH 03/13] ws: Rename surfaceId to bridgeId where appropriate
|
||||||
|
|
||||||
|
The fact is that WS::Instance::m_viewBackendMap associated wpe_bridge
|
||||||
|
identifiers with a Surface, therefore it is clearer when reading the
|
||||||
|
code to name variables accordingly.
|
||||||
|
|
||||||
|
(cherry picked from commit 2d58520c94cd1c06d940621acaf409480ef908e8)
|
||||||
|
---
|
||||||
|
src/view-backend-private.cpp | 23 +++++++++++------------
|
||||||
|
src/view-backend-private.h | 2 +-
|
||||||
|
src/ws.cpp | 10 +++++-----
|
||||||
|
src/ws.h | 1 +
|
||||||
|
4 files changed, 18 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/view-backend-private.cpp b/src/view-backend-private.cpp
|
||||||
|
index 78f0e2f..367e6c3 100644
|
||||||
|
--- a/src/view-backend-private.cpp
|
||||||
|
+++ b/src/view-backend-private.cpp
|
||||||
|
@@ -41,7 +41,7 @@ ViewBackend::ViewBackend(ClientBundle* clientBundle, struct wpe_view_backend* ba
|
||||||
|
|
||||||
|
ViewBackend::~ViewBackend()
|
||||||
|
{
|
||||||
|
- unregisterSurface(m_surfaceId);
|
||||||
|
+ unregisterSurface(m_bridgeId);
|
||||||
|
if (m_clientFd != -1)
|
||||||
|
close(m_clientFd);
|
||||||
|
}
|
||||||
|
@@ -131,29 +131,28 @@ void ViewBackend::clientDestroyNotify(struct wl_listener* listener, void*)
|
||||||
|
ViewBackend* self = wl_container_of(listener, self, m_clientDestroy);
|
||||||
|
|
||||||
|
self->clearFrameCallbacks();
|
||||||
|
- WS::Instance::singleton().unregisterViewBackend(self->m_surfaceId);
|
||||||
|
+ WS::Instance::singleton().unregisterViewBackend(self->m_bridgeId);
|
||||||
|
self->m_client = nullptr;
|
||||||
|
- self->m_surfaceId = 0;
|
||||||
|
+ self->m_bridgeId = 0;
|
||||||
|
|
||||||
|
wl_list_remove(&self->m_clientDestroy.link);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void ViewBackend::registerSurface(uint32_t surfaceId)
|
||||||
|
+void ViewBackend::registerSurface(uint32_t bridgeId)
|
||||||
|
{
|
||||||
|
-
|
||||||
|
- if (m_surfaceId == surfaceId)
|
||||||
|
+ if (m_bridgeId == bridgeId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- unregisterSurface(m_surfaceId);
|
||||||
|
+ unregisterSurface(m_bridgeId);
|
||||||
|
|
||||||
|
- m_surfaceId = surfaceId;
|
||||||
|
- m_client = WS::Instance::singleton().registerViewBackend(m_surfaceId, *this);
|
||||||
|
+ m_bridgeId = bridgeId;
|
||||||
|
+ m_client = WS::Instance::singleton().registerViewBackend(m_bridgeId, *this);
|
||||||
|
wl_client_add_destroy_listener(m_client, &m_clientDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void ViewBackend::unregisterSurface(uint32_t surfaceId)
|
||||||
|
+void ViewBackend::unregisterSurface(uint32_t bridgeId)
|
||||||
|
{
|
||||||
|
- if (!surfaceId || m_surfaceId != surfaceId)
|
||||||
|
+ if (!bridgeId || m_bridgeId != bridgeId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If the surfaceId is valid, we cannot have an invalid wl_client.
|
||||||
|
@@ -165,7 +164,7 @@ void ViewBackend::unregisterSurface(uint32_t surfaceId)
|
||||||
|
|
||||||
|
// After destroying the client, none of these can be valid.
|
||||||
|
g_assert(m_client == nullptr);
|
||||||
|
- g_assert(m_surfaceId == 0);
|
||||||
|
+ g_assert(m_bridgeId == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::didReceiveMessage(uint32_t messageId, uint32_t messageBody)
|
||||||
|
diff --git a/src/view-backend-private.h b/src/view-backend-private.h
|
||||||
|
index 918ec0e..9500262 100644
|
||||||
|
--- a/src/view-backend-private.h
|
||||||
|
+++ b/src/view-backend-private.h
|
||||||
|
@@ -90,7 +90,7 @@ private:
|
||||||
|
|
||||||
|
static gboolean s_socketCallback(GSocket*, GIOCondition, gpointer);
|
||||||
|
|
||||||
|
- uint32_t m_surfaceId { 0 };
|
||||||
|
+ uint32_t m_bridgeId { 0 };
|
||||||
|
|
||||||
|
static void clientDestroyNotify(struct wl_listener*, void*);
|
||||||
|
struct wl_listener m_clientDestroy { {}, clientDestroyNotify };
|
||||||
|
diff --git a/src/ws.cpp b/src/ws.cpp
|
||||||
|
index c23e53c..a044b2e 100644
|
||||||
|
--- a/src/ws.cpp
|
||||||
|
+++ b/src/ws.cpp
|
||||||
|
@@ -515,19 +515,19 @@ void Instance::releaseAudioPacketExport(struct wpe_audio_packet_export* packet_e
|
||||||
|
wpe_audio_packet_export_send_release(packet_export->exportResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
-struct wl_client* Instance::registerViewBackend(uint32_t surfaceId, APIClient& apiClient)
|
||||||
|
+struct wl_client* Instance::registerViewBackend(uint32_t bridgeId, APIClient& apiClient)
|
||||||
|
{
|
||||||
|
- auto it = m_viewBackendMap.find(surfaceId);
|
||||||
|
+ auto it = m_viewBackendMap.find(bridgeId);
|
||||||
|
if (it == m_viewBackendMap.end())
|
||||||
|
- g_error("Instance::registerViewBackend(): " "Cannot find surface %" PRIu32 " in view backend map.", surfaceId);
|
||||||
|
+ g_error("Instance::registerViewBackend(): " "Cannot find surface with bridgeId %" PRIu32 " in view backend map.", bridgeId);
|
||||||
|
|
||||||
|
it->second->apiClient = &apiClient;
|
||||||
|
return wl_resource_get_client(it->second->resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void Instance::unregisterViewBackend(uint32_t surfaceId)
|
||||||
|
+void Instance::unregisterViewBackend(uint32_t bridgeId)
|
||||||
|
{
|
||||||
|
- auto it = m_viewBackendMap.find(surfaceId);
|
||||||
|
+ auto it = m_viewBackendMap.find(bridgeId);
|
||||||
|
if (it != m_viewBackendMap.end()) {
|
||||||
|
it->second->apiClient = nullptr;
|
||||||
|
m_viewBackendMap.erase(it);
|
||||||
|
diff --git a/src/ws.h b/src/ws.h
|
||||||
|
index 683b679..aa0c083 100644
|
||||||
|
--- a/src/ws.h
|
||||||
|
+++ b/src/ws.h
|
||||||
|
@@ -128,6 +128,7 @@ private:
|
||||||
|
struct wl_global* m_wpeBridge { nullptr };
|
||||||
|
GSource* m_source { nullptr };
|
||||||
|
|
||||||
|
+ // (bridgeId -> Surface)
|
||||||
|
std::unordered_map<uint32_t, Surface*> m_viewBackendMap;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
262
0004-ws-Accumulate-surface-frame-callbacks-until-commit.patch
Normal file
262
0004-ws-Accumulate-surface-frame-callbacks-until-commit.patch
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
From 98ad602e5f5d51162ec715a023b87d06a71d627b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Perez de Castro <aperez@igalia.com>
|
||||||
|
Date: Thu, 8 Apr 2021 00:57:49 +0300
|
||||||
|
Subject: [PATCH 04/13] ws: Accumulate surface frame callbacks until commit
|
||||||
|
|
||||||
|
Move code around to accumulate surface frame callback additions until
|
||||||
|
changes are comitted to the surface, as intended according to the base
|
||||||
|
Wayland protocol specification.
|
||||||
|
|
||||||
|
As a bonus, remove the auxiliar ViewBackend::FrameCallbackResource
|
||||||
|
by passing a destruction callback to wl_resource_set_implementation()
|
||||||
|
and using the internal wl_resource list link.
|
||||||
|
|
||||||
|
(cherry picked from commit 3ab4a3c9770d333ebbc65ab42a604836c6da57ec)
|
||||||
|
---
|
||||||
|
src/view-backend-private.cpp | 45 ++----------------------------------
|
||||||
|
src/view-backend-private.h | 14 -----------
|
||||||
|
src/ws.cpp | 19 +++++++++++++--
|
||||||
|
src/ws.h | 39 ++++++++++++++++++++++++++++++-
|
||||||
|
4 files changed, 57 insertions(+), 60 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/view-backend-private.cpp b/src/view-backend-private.cpp
|
||||||
|
index 367e6c3..f04a57e 100644
|
||||||
|
--- a/src/view-backend-private.cpp
|
||||||
|
+++ b/src/view-backend-private.cpp
|
||||||
|
@@ -35,7 +35,6 @@ ViewBackend::ViewBackend(ClientBundle* clientBundle, struct wpe_view_backend* ba
|
||||||
|
{
|
||||||
|
m_clientBundle->viewBackend = this;
|
||||||
|
|
||||||
|
- wl_list_init(&m_frameCallbacks);
|
||||||
|
wl_list_init(&m_clientDestroy.link);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -72,15 +71,6 @@ int ViewBackend::clientFd()
|
||||||
|
return dup(m_clientFd);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void ViewBackend::frameCallback(struct wl_resource* callback)
|
||||||
|
-{
|
||||||
|
- auto* resource = new FrameCallbackResource;
|
||||||
|
- resource->resource = callback;
|
||||||
|
- resource->destroyListener.notify = FrameCallbackResource::destroyNotify;
|
||||||
|
- wl_resource_add_destroy_listener(callback, &resource->destroyListener);
|
||||||
|
- wl_list_insert(&m_frameCallbacks, &resource->link);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void ViewBackend::exportBufferResource(struct wl_resource* bufferResource)
|
||||||
|
{
|
||||||
|
m_clientBundle->exportBuffer(bufferResource);
|
||||||
|
@@ -103,16 +93,8 @@ void ViewBackend::exportEGLStreamProducer(struct wl_resource* bufferResource)
|
||||||
|
|
||||||
|
void ViewBackend::dispatchFrameCallbacks()
|
||||||
|
{
|
||||||
|
- if (G_UNLIKELY(!m_client))
|
||||||
|
- return;
|
||||||
|
-
|
||||||
|
- FrameCallbackResource* resource;
|
||||||
|
- wl_list_for_each(resource, &m_frameCallbacks, link) {
|
||||||
|
- wl_callback_send_done(resource->resource, 0);
|
||||||
|
- }
|
||||||
|
- clearFrameCallbacks();
|
||||||
|
-
|
||||||
|
- wl_client_flush(m_client);
|
||||||
|
+ if (G_LIKELY(m_bridgeId))
|
||||||
|
+ WS::Instance::singleton().dispatchFrameCallbacks(m_bridgeId);
|
||||||
|
|
||||||
|
wpe_view_backend_dispatch_frame_displayed(m_backend);
|
||||||
|
}
|
||||||
|
@@ -130,7 +112,6 @@ void ViewBackend::clientDestroyNotify(struct wl_listener* listener, void*)
|
||||||
|
{
|
||||||
|
ViewBackend* self = wl_container_of(listener, self, m_clientDestroy);
|
||||||
|
|
||||||
|
- self->clearFrameCallbacks();
|
||||||
|
WS::Instance::singleton().unregisterViewBackend(self->m_bridgeId);
|
||||||
|
self->m_client = nullptr;
|
||||||
|
self->m_bridgeId = 0;
|
||||||
|
@@ -180,25 +161,3 @@ void ViewBackend::didReceiveMessage(uint32_t messageId, uint32_t messageBody)
|
||||||
|
assert(!"WPE fdo received an invalid IPC message");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
-void ViewBackend::clearFrameCallbacks()
|
||||||
|
-{
|
||||||
|
- FrameCallbackResource* resource;
|
||||||
|
- FrameCallbackResource* next;
|
||||||
|
- wl_list_for_each_safe(resource, next, &m_frameCallbacks, link) {
|
||||||
|
- wl_list_remove(&resource->link);
|
||||||
|
- wl_list_remove(&resource->destroyListener.link);
|
||||||
|
- wl_resource_destroy(resource->resource);
|
||||||
|
- delete resource;
|
||||||
|
- }
|
||||||
|
- wl_list_init(&m_frameCallbacks);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void ViewBackend::FrameCallbackResource::destroyNotify(struct wl_listener* listener, void*)
|
||||||
|
-{
|
||||||
|
- FrameCallbackResource* resource;
|
||||||
|
- resource = wl_container_of(listener, resource, destroyListener);
|
||||||
|
-
|
||||||
|
- wl_list_remove(&resource->link);
|
||||||
|
- delete resource;
|
||||||
|
-}
|
||||||
|
diff --git a/src/view-backend-private.h b/src/view-backend-private.h
|
||||||
|
index 9500262..a598dee 100644
|
||||||
|
--- a/src/view-backend-private.h
|
||||||
|
+++ b/src/view-backend-private.h
|
||||||
|
@@ -63,7 +63,6 @@ public:
|
||||||
|
|
||||||
|
void initialize();
|
||||||
|
int clientFd();
|
||||||
|
- void frameCallback(struct wl_resource* callbackResource) override;
|
||||||
|
void exportBufferResource(struct wl_resource* bufferResource) override;
|
||||||
|
void exportLinuxDmabuf(const struct linux_dmabuf_buffer *dmabuf_buffer) override;
|
||||||
|
void exportShmBuffer(struct wl_resource* bufferResource, struct wl_shm_buffer* shmBuffer) override;
|
||||||
|
@@ -72,22 +71,11 @@ public:
|
||||||
|
void releaseBuffer(struct wl_resource* buffer_resource);
|
||||||
|
|
||||||
|
private:
|
||||||
|
- struct FrameCallbackResource {
|
||||||
|
- struct wl_resource* resource;
|
||||||
|
-
|
||||||
|
- struct wl_list link;
|
||||||
|
- struct wl_listener destroyListener;
|
||||||
|
-
|
||||||
|
- static void destroyNotify(struct wl_listener*, void*);
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
void didReceiveMessage(uint32_t messageId, uint32_t messageBody) override;
|
||||||
|
|
||||||
|
void registerSurface(uint32_t);
|
||||||
|
void unregisterSurface(uint32_t);
|
||||||
|
|
||||||
|
- void clearFrameCallbacks();
|
||||||
|
-
|
||||||
|
static gboolean s_socketCallback(GSocket*, GIOCondition, gpointer);
|
||||||
|
|
||||||
|
uint32_t m_bridgeId { 0 };
|
||||||
|
@@ -99,8 +87,6 @@ private:
|
||||||
|
ClientBundle* m_clientBundle;
|
||||||
|
struct wpe_view_backend* m_backend;
|
||||||
|
|
||||||
|
- struct wl_list m_frameCallbacks;
|
||||||
|
-
|
||||||
|
std::unique_ptr<FdoIPC::Connection> m_socket;
|
||||||
|
int m_clientFd { -1 };
|
||||||
|
};
|
||||||
|
diff --git a/src/ws.cpp b/src/ws.cpp
|
||||||
|
index a044b2e..87faaf3 100644
|
||||||
|
--- a/src/ws.cpp
|
||||||
|
+++ b/src/ws.cpp
|
||||||
|
@@ -110,8 +110,11 @@ static const struct wl_surface_interface s_surfaceInterface = {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- wl_resource_set_implementation(callbackResource, nullptr, nullptr, nullptr);
|
||||||
|
- surface.apiClient->frameCallback(callbackResource);
|
||||||
|
+ wl_resource_set_implementation(callbackResource, nullptr, nullptr,
|
||||||
|
+ [](struct wl_resource* resource) {
|
||||||
|
+ wl_list_remove(wl_resource_get_link(resource));
|
||||||
|
+ });
|
||||||
|
+ surface.addFrameCallback(callbackResource);
|
||||||
|
},
|
||||||
|
// set_opaque_region
|
||||||
|
[](struct wl_client*, struct wl_resource*, struct wl_resource*) { },
|
||||||
|
@@ -121,6 +124,7 @@ static const struct wl_surface_interface s_surfaceInterface = {
|
||||||
|
[](struct wl_client*, struct wl_resource* surfaceResource)
|
||||||
|
{
|
||||||
|
auto& surface = *static_cast<Surface*>(wl_resource_get_user_data(surfaceResource));
|
||||||
|
+ surface.commit();
|
||||||
|
WS::Instance::singleton().impl().surfaceCommit(surface);
|
||||||
|
},
|
||||||
|
// set_buffer_transform
|
||||||
|
@@ -534,4 +538,15 @@ void Instance::unregisterViewBackend(uint32_t bridgeId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void Instance::dispatchFrameCallbacks(uint32_t bridgeId)
|
||||||
|
+{
|
||||||
|
+ auto it = m_viewBackendMap.find(bridgeId);
|
||||||
|
+ if (it == m_viewBackendMap.end()) {
|
||||||
|
+ g_error("Instance::dispatchFrameCallbacks(): "
|
||||||
|
+ "Cannot find surface with bridgeId %" PRIu32 " in view backend map.", bridgeId);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ it->second->dispatchFrameCallbacks();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
} // namespace WS
|
||||||
|
diff --git a/src/ws.h b/src/ws.h
|
||||||
|
index aa0c083..30baf8e 100644
|
||||||
|
--- a/src/ws.h
|
||||||
|
+++ b/src/ws.h
|
||||||
|
@@ -41,7 +41,6 @@ namespace WS {
|
||||||
|
struct APIClient {
|
||||||
|
virtual ~APIClient() = default;
|
||||||
|
|
||||||
|
- virtual void frameCallback(struct wl_resource*) = 0;
|
||||||
|
virtual void exportBufferResource(struct wl_resource*) = 0;
|
||||||
|
virtual void exportLinuxDmabuf(const struct linux_dmabuf_buffer *dmabuf_buffer) = 0;
|
||||||
|
virtual void exportShmBuffer(struct wl_resource*, struct wl_shm_buffer*) = 0;
|
||||||
|
@@ -52,6 +51,18 @@ struct Surface {
|
||||||
|
explicit Surface(struct wl_resource* surfaceResource):
|
||||||
|
resource {surfaceResource}
|
||||||
|
{
|
||||||
|
+ wl_list_init(&m_pendingFrameCallbacks);
|
||||||
|
+ wl_list_init(&m_currentFrameCallbacks);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ~Surface()
|
||||||
|
+ {
|
||||||
|
+ struct wl_resource* resource;
|
||||||
|
+ struct wl_resource* tmp;
|
||||||
|
+ wl_resource_for_each_safe(resource, tmp, &m_pendingFrameCallbacks)
|
||||||
|
+ wl_resource_destroy(resource);
|
||||||
|
+ wl_resource_for_each_safe(resource, tmp, &m_currentFrameCallbacks)
|
||||||
|
+ wl_resource_destroy(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_resource* resource;
|
||||||
|
@@ -61,6 +72,31 @@ struct Surface {
|
||||||
|
struct wl_resource* bufferResource { nullptr };
|
||||||
|
const struct linux_dmabuf_buffer* dmabufBuffer { nullptr };
|
||||||
|
struct wl_shm_buffer* shmBuffer { nullptr };
|
||||||
|
+
|
||||||
|
+ void commit()
|
||||||
|
+ {
|
||||||
|
+ wl_list_insert_list(&m_currentFrameCallbacks, &m_pendingFrameCallbacks);
|
||||||
|
+ wl_list_init(&m_pendingFrameCallbacks);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void addFrameCallback(struct wl_resource* resource)
|
||||||
|
+ {
|
||||||
|
+ wl_list_insert(m_pendingFrameCallbacks.prev, wl_resource_get_link(resource));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void dispatchFrameCallbacks()
|
||||||
|
+ {
|
||||||
|
+ struct wl_resource* resource;
|
||||||
|
+ struct wl_resource* tmp;
|
||||||
|
+ wl_resource_for_each_safe(resource, tmp, &m_currentFrameCallbacks) {
|
||||||
|
+ wl_callback_send_done(resource, 0);
|
||||||
|
+ wl_resource_destroy(resource);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+private:
|
||||||
|
+ struct wl_list m_pendingFrameCallbacks;
|
||||||
|
+ struct wl_list m_currentFrameCallbacks;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Instance {
|
||||||
|
@@ -95,6 +131,7 @@ public:
|
||||||
|
void registerSurface(uint32_t, Surface*);
|
||||||
|
struct wl_client* registerViewBackend(uint32_t, APIClient&);
|
||||||
|
void unregisterViewBackend(uint32_t);
|
||||||
|
+ void dispatchFrameCallbacks(uint32_t);
|
||||||
|
|
||||||
|
using VideoPlaneDisplayDmaBufCallback = std::function<void(struct wpe_video_plane_display_dmabuf_export*, uint32_t, int, int32_t, int32_t, int32_t, int32_t, uint32_t)>;
|
||||||
|
using VideoPlaneDisplayDmaBufEndOfStreamCallback = std::function<void(uint32_t)>;
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From 89e4b1683ad51c1b066fc10c748e5d524fb37cd2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Perez de Castro <aperez@igalia.com>
|
||||||
|
Date: Wed, 14 Apr 2021 21:56:12 +0300
|
||||||
|
Subject: [PATCH 06/13] meson: Make scripts/version.py work with older Pythons
|
||||||
|
|
||||||
|
Older Python versions (3.5, 2.x) do not have a __getitem__ method
|
||||||
|
on regex match objects, so use the .group() method instead, which is
|
||||||
|
available in all versions.
|
||||||
|
|
||||||
|
(cherry picked from commit 8c4b29f973500a9a596e27a2b3042923e4c905f7)
|
||||||
|
---
|
||||||
|
scripts/version.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/scripts/version.py b/scripts/version.py
|
||||||
|
index 1dbbdb3..e2af013 100644
|
||||||
|
--- a/scripts/version.py
|
||||||
|
+++ b/scripts/version.py
|
||||||
|
@@ -18,6 +18,6 @@ with open(version_file, "r") as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
m = version_re.match(line)
|
||||||
|
if m:
|
||||||
|
- version[m[1]] = m[2]
|
||||||
|
+ version[m.group(1)] = m.group(2)
|
||||||
|
|
||||||
|
print("{}.{}.{}".format(version["MAJOR"], version["MINOR"], version["MICRO"]))
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
132
0007-Revert-view-backend-Properly-unregister-surfaces.patch
Normal file
132
0007-Revert-view-backend-Properly-unregister-surfaces.patch
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
From 4657edaf9f798863d16d94e61a3f467ee656e908 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Perez de Castro <aperez@igalia.com>
|
||||||
|
Date: Sat, 10 Apr 2021 18:27:42 +0300
|
||||||
|
Subject: [PATCH 07/13] Revert "view backend: Properly unregister surfaces"
|
||||||
|
|
||||||
|
This reverts commit 99bd04019800f84a722ae99bf1a352f225d93002.
|
||||||
|
---
|
||||||
|
src/view-backend-private.cpp | 52 +++++++++++++-----------------------
|
||||||
|
src/view-backend-private.h | 8 +++---
|
||||||
|
2 files changed, 24 insertions(+), 36 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/view-backend-private.cpp b/src/view-backend-private.cpp
|
||||||
|
index f04a57e..4920037 100644
|
||||||
|
--- a/src/view-backend-private.cpp
|
||||||
|
+++ b/src/view-backend-private.cpp
|
||||||
|
@@ -34,13 +34,12 @@ ViewBackend::ViewBackend(ClientBundle* clientBundle, struct wpe_view_backend* ba
|
||||||
|
, m_backend(backend)
|
||||||
|
{
|
||||||
|
m_clientBundle->viewBackend = this;
|
||||||
|
-
|
||||||
|
- wl_list_init(&m_clientDestroy.link);
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewBackend::~ViewBackend()
|
||||||
|
{
|
||||||
|
unregisterSurface(m_bridgeId);
|
||||||
|
+
|
||||||
|
if (m_clientFd != -1)
|
||||||
|
close(m_clientFd);
|
||||||
|
}
|
||||||
|
@@ -96,39 +95,24 @@ void ViewBackend::dispatchFrameCallbacks()
|
||||||
|
if (G_LIKELY(m_bridgeId))
|
||||||
|
WS::Instance::singleton().dispatchFrameCallbacks(m_bridgeId);
|
||||||
|
|
||||||
|
+ if (m_client.object)
|
||||||
|
+ wl_client_flush(m_client.object);
|
||||||
|
wpe_view_backend_dispatch_frame_displayed(m_backend);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::releaseBuffer(struct wl_resource* buffer_resource)
|
||||||
|
{
|
||||||
|
- if (G_UNLIKELY(!m_client))
|
||||||
|
- return;
|
||||||
|
-
|
||||||
|
wl_buffer_send_release(buffer_resource);
|
||||||
|
- wl_client_flush(m_client);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void ViewBackend::clientDestroyNotify(struct wl_listener* listener, void*)
|
||||||
|
-{
|
||||||
|
- ViewBackend* self = wl_container_of(listener, self, m_clientDestroy);
|
||||||
|
-
|
||||||
|
- WS::Instance::singleton().unregisterViewBackend(self->m_bridgeId);
|
||||||
|
- self->m_client = nullptr;
|
||||||
|
- self->m_bridgeId = 0;
|
||||||
|
-
|
||||||
|
- wl_list_remove(&self->m_clientDestroy.link);
|
||||||
|
+ if (m_client.object)
|
||||||
|
+ wl_client_flush(m_client.object);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::registerSurface(uint32_t bridgeId)
|
||||||
|
{
|
||||||
|
- if (m_bridgeId == bridgeId)
|
||||||
|
- return;
|
||||||
|
-
|
||||||
|
- unregisterSurface(m_bridgeId);
|
||||||
|
-
|
||||||
|
m_bridgeId = bridgeId;
|
||||||
|
- m_client = WS::Instance::singleton().registerViewBackend(m_bridgeId, *this);
|
||||||
|
- wl_client_add_destroy_listener(m_client, &m_clientDestroy);
|
||||||
|
+ m_client.object = WS::Instance::singleton().registerViewBackend(m_bridgeId, *this);
|
||||||
|
+ m_client.destroyListener.notify = Client::destroyNotify;
|
||||||
|
+ wl_client_add_destroy_listener(m_client.object, &m_client.destroyListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::unregisterSurface(uint32_t bridgeId)
|
||||||
|
@@ -136,16 +120,10 @@ void ViewBackend::unregisterSurface(uint32_t bridgeId)
|
||||||
|
if (!bridgeId || m_bridgeId != bridgeId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- // If the surfaceId is valid, we cannot have an invalid wl_client.
|
||||||
|
- g_assert(m_client != nullptr);
|
||||||
|
-
|
||||||
|
- // Destroying the client triggers the m_clientDestroy callback,
|
||||||
|
- // the rest of the teardown is done from there.
|
||||||
|
- wl_client_destroy(m_client);
|
||||||
|
+ g_clear_pointer(&m_client.object, wl_client_destroy);
|
||||||
|
|
||||||
|
- // After destroying the client, none of these can be valid.
|
||||||
|
- g_assert(m_client == nullptr);
|
||||||
|
- g_assert(m_bridgeId == 0);
|
||||||
|
+ WS::Instance::singleton().unregisterViewBackend(m_bridgeId);
|
||||||
|
+ m_bridgeId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::didReceiveMessage(uint32_t messageId, uint32_t messageBody)
|
||||||
|
@@ -161,3 +139,11 @@ void ViewBackend::didReceiveMessage(uint32_t messageId, uint32_t messageBody)
|
||||||
|
assert(!"WPE fdo received an invalid IPC message");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void ViewBackend::Client::destroyNotify(struct wl_listener* listener, void*)
|
||||||
|
+{
|
||||||
|
+ Client* client;
|
||||||
|
+ client = wl_container_of(listener, client, destroyListener);
|
||||||
|
+
|
||||||
|
+ client->object = nullptr;
|
||||||
|
+}
|
||||||
|
diff --git a/src/view-backend-private.h b/src/view-backend-private.h
|
||||||
|
index a598dee..37eab08 100644
|
||||||
|
--- a/src/view-backend-private.h
|
||||||
|
+++ b/src/view-backend-private.h
|
||||||
|
@@ -79,10 +79,12 @@ private:
|
||||||
|
static gboolean s_socketCallback(GSocket*, GIOCondition, gpointer);
|
||||||
|
|
||||||
|
uint32_t m_bridgeId { 0 };
|
||||||
|
+ struct Client {
|
||||||
|
+ struct wl_client* object { nullptr };
|
||||||
|
+ struct wl_listener destroyListener;
|
||||||
|
|
||||||
|
- static void clientDestroyNotify(struct wl_listener*, void*);
|
||||||
|
- struct wl_listener m_clientDestroy { {}, clientDestroyNotify };
|
||||||
|
- struct wl_client* m_client { nullptr };
|
||||||
|
+ static void destroyNotify(struct wl_listener*, void*);
|
||||||
|
+ } m_client;
|
||||||
|
|
||||||
|
ClientBundle* m_clientBundle;
|
||||||
|
struct wpe_view_backend* m_backend;
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
From 00a6f6d61cb20af45714360bf458348aeaf08751 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Perez de Castro <aperez@igalia.com>
|
||||||
|
Date: Sat, 10 Apr 2021 18:27:55 +0300
|
||||||
|
Subject: [PATCH 08/13] Revert "view-backend-private: Move wl_client_destroy to
|
||||||
|
unregisterSurface()"
|
||||||
|
|
||||||
|
This reverts commit f54135e65a6894bdf509153d2f6e96a627352306.
|
||||||
|
---
|
||||||
|
src/view-backend-private.cpp | 2 --
|
||||||
|
src/ws.cpp | 1 +
|
||||||
|
2 files changed, 1 insertion(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/view-backend-private.cpp b/src/view-backend-private.cpp
|
||||||
|
index 4920037..e1554bb 100644
|
||||||
|
--- a/src/view-backend-private.cpp
|
||||||
|
+++ b/src/view-backend-private.cpp
|
||||||
|
@@ -120,8 +120,6 @@ void ViewBackend::unregisterSurface(uint32_t bridgeId)
|
||||||
|
if (!bridgeId || m_bridgeId != bridgeId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- g_clear_pointer(&m_client.object, wl_client_destroy);
|
||||||
|
-
|
||||||
|
WS::Instance::singleton().unregisterViewBackend(m_bridgeId);
|
||||||
|
m_bridgeId = 0;
|
||||||
|
}
|
||||||
|
diff --git a/src/ws.cpp b/src/ws.cpp
|
||||||
|
index 87faaf3..80cb39b 100644
|
||||||
|
--- a/src/ws.cpp
|
||||||
|
+++ b/src/ws.cpp
|
||||||
|
@@ -534,6 +534,7 @@ void Instance::unregisterViewBackend(uint32_t bridgeId)
|
||||||
|
auto it = m_viewBackendMap.find(bridgeId);
|
||||||
|
if (it != m_viewBackendMap.end()) {
|
||||||
|
it->second->apiClient = nullptr;
|
||||||
|
+ wl_client_destroy(wl_resource_get_client(it->second->resource));
|
||||||
|
m_viewBackendMap.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
From 542587bae6b894bdd1a5cfd38223f8054d166fc3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Perez de Castro <aperez@igalia.com>
|
||||||
|
Date: Sat, 10 Apr 2021 18:28:43 +0300
|
||||||
|
Subject: [PATCH 09/13] Revert "ws: Call wl_client_destroy for the created
|
||||||
|
wl_client in Instance::unregisterViewBackend()"
|
||||||
|
|
||||||
|
This reverts commit 9a0e6cb62bfae44ef3496d950899ecb34ddd24a5.
|
||||||
|
---
|
||||||
|
src/ws.cpp | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/ws.cpp b/src/ws.cpp
|
||||||
|
index 80cb39b..87faaf3 100644
|
||||||
|
--- a/src/ws.cpp
|
||||||
|
+++ b/src/ws.cpp
|
||||||
|
@@ -534,7 +534,6 @@ void Instance::unregisterViewBackend(uint32_t bridgeId)
|
||||||
|
auto it = m_viewBackendMap.find(bridgeId);
|
||||||
|
if (it != m_viewBackendMap.end()) {
|
||||||
|
it->second->apiClient = nullptr;
|
||||||
|
- wl_client_destroy(wl_resource_get_client(it->second->resource));
|
||||||
|
m_viewBackendMap.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
101
0010-Revert-Cleanups.patch
Normal file
101
0010-Revert-Cleanups.patch
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
From 18244c702bba27d32a022bd8a2ff9269fcb18cc5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Perez de Castro <aperez@igalia.com>
|
||||||
|
Date: Sat, 10 Apr 2021 18:29:05 +0300
|
||||||
|
Subject: [PATCH 10/13] Revert "Cleanups."
|
||||||
|
|
||||||
|
This reverts commit 9e7dfbe7cbca8bc59c81d1e6421a527a87796880.
|
||||||
|
---
|
||||||
|
src/view-backend-private.cpp | 31 ++++++++++++++++---------------
|
||||||
|
src/view-backend-private.h | 12 ++++++------
|
||||||
|
2 files changed, 22 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/view-backend-private.cpp b/src/view-backend-private.cpp
|
||||||
|
index e1554bb..6ba3fcb 100644
|
||||||
|
--- a/src/view-backend-private.cpp
|
||||||
|
+++ b/src/view-backend-private.cpp
|
||||||
|
@@ -95,24 +95,33 @@ void ViewBackend::dispatchFrameCallbacks()
|
||||||
|
if (G_LIKELY(m_bridgeId))
|
||||||
|
WS::Instance::singleton().dispatchFrameCallbacks(m_bridgeId);
|
||||||
|
|
||||||
|
- if (m_client.object)
|
||||||
|
- wl_client_flush(m_client.object);
|
||||||
|
+ if (m_client)
|
||||||
|
+ wl_client_flush(m_client);
|
||||||
|
wpe_view_backend_dispatch_frame_displayed(m_backend);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::releaseBuffer(struct wl_resource* buffer_resource)
|
||||||
|
{
|
||||||
|
wl_buffer_send_release(buffer_resource);
|
||||||
|
- if (m_client.object)
|
||||||
|
- wl_client_flush(m_client.object);
|
||||||
|
+ if (m_client)
|
||||||
|
+ wl_client_flush(m_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::registerSurface(uint32_t bridgeId)
|
||||||
|
{
|
||||||
|
m_bridgeId = bridgeId;
|
||||||
|
- m_client.object = WS::Instance::singleton().registerViewBackend(m_bridgeId, *this);
|
||||||
|
- m_client.destroyListener.notify = Client::destroyNotify;
|
||||||
|
- wl_client_add_destroy_listener(m_client.object, &m_client.destroyListener);
|
||||||
|
+ m_client = WS::Instance::singleton().registerViewBackend(m_bridgeId, *this);
|
||||||
|
+
|
||||||
|
+ struct wl_client_destroy_listener *listener = new wl_client_destroy_listener {this, };
|
||||||
|
+ listener->destroyClientListener.notify = (wl_notify_func_t) [](struct wl_listener* listener, void* data)
|
||||||
|
+ {
|
||||||
|
+ struct wl_client_destroy_listener *container;
|
||||||
|
+ container = wl_container_of(listener, container, destroyClientListener);
|
||||||
|
+ container->backend->m_client = NULL;
|
||||||
|
+ delete container; // Release the wl_client_destroy_listener instance since this is not longer needed.
|
||||||
|
+ };
|
||||||
|
+ wl_client_add_destroy_listener(m_client,
|
||||||
|
+ &listener->destroyClientListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::unregisterSurface(uint32_t bridgeId)
|
||||||
|
@@ -137,11 +146,3 @@ void ViewBackend::didReceiveMessage(uint32_t messageId, uint32_t messageBody)
|
||||||
|
assert(!"WPE fdo received an invalid IPC message");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
-void ViewBackend::Client::destroyNotify(struct wl_listener* listener, void*)
|
||||||
|
-{
|
||||||
|
- Client* client;
|
||||||
|
- client = wl_container_of(listener, client, destroyListener);
|
||||||
|
-
|
||||||
|
- client->object = nullptr;
|
||||||
|
-}
|
||||||
|
diff --git a/src/view-backend-private.h b/src/view-backend-private.h
|
||||||
|
index 37eab08..81b083c 100644
|
||||||
|
--- a/src/view-backend-private.h
|
||||||
|
+++ b/src/view-backend-private.h
|
||||||
|
@@ -79,12 +79,7 @@ private:
|
||||||
|
static gboolean s_socketCallback(GSocket*, GIOCondition, gpointer);
|
||||||
|
|
||||||
|
uint32_t m_bridgeId { 0 };
|
||||||
|
- struct Client {
|
||||||
|
- struct wl_client* object { nullptr };
|
||||||
|
- struct wl_listener destroyListener;
|
||||||
|
-
|
||||||
|
- static void destroyNotify(struct wl_listener*, void*);
|
||||||
|
- } m_client;
|
||||||
|
+ struct wl_client* m_client { nullptr };
|
||||||
|
|
||||||
|
ClientBundle* m_clientBundle;
|
||||||
|
struct wpe_view_backend* m_backend;
|
||||||
|
@@ -93,6 +88,11 @@ private:
|
||||||
|
int m_clientFd { -1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct wl_client_destroy_listener {
|
||||||
|
+ ViewBackend* backend;
|
||||||
|
+ struct wl_listener destroyClientListener;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct wpe_view_backend_private {
|
||||||
|
wpe_view_backend_private(std::unique_ptr<ClientBundle>&& clientBundle, struct wpe_view_backend* backend)
|
||||||
|
: clientBundle(std::move(clientBundle))
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
From 862764947c6a62e27371d0b31660ff41cd70b674 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Perez de Castro <aperez@igalia.com>
|
||||||
|
Date: Sat, 10 Apr 2021 18:29:13 +0300
|
||||||
|
Subject: [PATCH 11/13] Revert "view-backend-exportable-private: Move
|
||||||
|
ViewBackend::m_destroyClientListener"
|
||||||
|
|
||||||
|
This reverts commit d7577891d505a3fb037ec14e54568fe59e310941.
|
||||||
|
---
|
||||||
|
src/view-backend-private.cpp | 14 +++++++-------
|
||||||
|
src/view-backend-private.h | 6 +-----
|
||||||
|
2 files changed, 8 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/view-backend-private.cpp b/src/view-backend-private.cpp
|
||||||
|
index 6ba3fcb..af5472f 100644
|
||||||
|
--- a/src/view-backend-private.cpp
|
||||||
|
+++ b/src/view-backend-private.cpp
|
||||||
|
@@ -112,16 +112,16 @@ void ViewBackend::registerSurface(uint32_t bridgeId)
|
||||||
|
m_bridgeId = bridgeId;
|
||||||
|
m_client = WS::Instance::singleton().registerViewBackend(m_bridgeId, *this);
|
||||||
|
|
||||||
|
- struct wl_client_destroy_listener *listener = new wl_client_destroy_listener {this, };
|
||||||
|
- listener->destroyClientListener.notify = (wl_notify_func_t) [](struct wl_listener* listener, void* data)
|
||||||
|
+ this->m_destroyClientListener.notify = (wl_notify_func_t) [](struct wl_listener* listener, void* data)
|
||||||
|
{
|
||||||
|
- struct wl_client_destroy_listener *container;
|
||||||
|
- container = wl_container_of(listener, container, destroyClientListener);
|
||||||
|
- container->backend->m_client = NULL;
|
||||||
|
- delete container; // Release the wl_client_destroy_listener instance since this is not longer needed.
|
||||||
|
+ ViewBackend *viewBackend = wl_container_of(listener, viewBackend, m_destroyClientListener);
|
||||||
|
+
|
||||||
|
+ struct wl_client* client = (struct wl_client*) data;
|
||||||
|
+ g_debug("ViewBackend <%p>: wl_client <%p> destroy notification for fd %d", viewBackend, data, wl_client_get_fd(client));
|
||||||
|
+ viewBackend->m_client = NULL;
|
||||||
|
};
|
||||||
|
wl_client_add_destroy_listener(m_client,
|
||||||
|
- &listener->destroyClientListener);
|
||||||
|
+ &this->m_destroyClientListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::unregisterSurface(uint32_t bridgeId)
|
||||||
|
diff --git a/src/view-backend-private.h b/src/view-backend-private.h
|
||||||
|
index 81b083c..599382b 100644
|
||||||
|
--- a/src/view-backend-private.h
|
||||||
|
+++ b/src/view-backend-private.h
|
||||||
|
@@ -86,11 +86,7 @@ private:
|
||||||
|
|
||||||
|
std::unique_ptr<FdoIPC::Connection> m_socket;
|
||||||
|
int m_clientFd { -1 };
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-struct wl_client_destroy_listener {
|
||||||
|
- ViewBackend* backend;
|
||||||
|
- struct wl_listener destroyClientListener;
|
||||||
|
+ struct wl_listener m_destroyClientListener;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wpe_view_backend_private {
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,67 @@
|
|||||||
|
From 229b2601804049d94f09006e8c4a542c78158ab9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Perez de Castro <aperez@igalia.com>
|
||||||
|
Date: Sat, 10 Apr 2021 18:29:24 +0300
|
||||||
|
Subject: [PATCH 12/13] Revert "view-backend-exportable-private: Add
|
||||||
|
wl_client_add_destroy_listener in the ViewBackend"
|
||||||
|
|
||||||
|
This reverts commit d688cd2558807c1ed15d67e5b0ecfad52a2bf90b.
|
||||||
|
---
|
||||||
|
src/view-backend-private.cpp | 17 ++---------------
|
||||||
|
src/view-backend-private.h | 1 -
|
||||||
|
2 files changed, 2 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/view-backend-private.cpp b/src/view-backend-private.cpp
|
||||||
|
index af5472f..b78831d 100644
|
||||||
|
--- a/src/view-backend-private.cpp
|
||||||
|
+++ b/src/view-backend-private.cpp
|
||||||
|
@@ -95,33 +95,20 @@ void ViewBackend::dispatchFrameCallbacks()
|
||||||
|
if (G_LIKELY(m_bridgeId))
|
||||||
|
WS::Instance::singleton().dispatchFrameCallbacks(m_bridgeId);
|
||||||
|
|
||||||
|
- if (m_client)
|
||||||
|
- wl_client_flush(m_client);
|
||||||
|
+ wl_client_flush(m_client);
|
||||||
|
wpe_view_backend_dispatch_frame_displayed(m_backend);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::releaseBuffer(struct wl_resource* buffer_resource)
|
||||||
|
{
|
||||||
|
wl_buffer_send_release(buffer_resource);
|
||||||
|
- if (m_client)
|
||||||
|
- wl_client_flush(m_client);
|
||||||
|
+ wl_client_flush(m_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::registerSurface(uint32_t bridgeId)
|
||||||
|
{
|
||||||
|
m_bridgeId = bridgeId;
|
||||||
|
m_client = WS::Instance::singleton().registerViewBackend(m_bridgeId, *this);
|
||||||
|
-
|
||||||
|
- this->m_destroyClientListener.notify = (wl_notify_func_t) [](struct wl_listener* listener, void* data)
|
||||||
|
- {
|
||||||
|
- ViewBackend *viewBackend = wl_container_of(listener, viewBackend, m_destroyClientListener);
|
||||||
|
-
|
||||||
|
- struct wl_client* client = (struct wl_client*) data;
|
||||||
|
- g_debug("ViewBackend <%p>: wl_client <%p> destroy notification for fd %d", viewBackend, data, wl_client_get_fd(client));
|
||||||
|
- viewBackend->m_client = NULL;
|
||||||
|
- };
|
||||||
|
- wl_client_add_destroy_listener(m_client,
|
||||||
|
- &this->m_destroyClientListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::unregisterSurface(uint32_t bridgeId)
|
||||||
|
diff --git a/src/view-backend-private.h b/src/view-backend-private.h
|
||||||
|
index 599382b..15e98e6 100644
|
||||||
|
--- a/src/view-backend-private.h
|
||||||
|
+++ b/src/view-backend-private.h
|
||||||
|
@@ -86,7 +86,6 @@ private:
|
||||||
|
|
||||||
|
std::unique_ptr<FdoIPC::Connection> m_socket;
|
||||||
|
int m_clientFd { -1 };
|
||||||
|
- struct wl_listener m_destroyClientListener;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wpe_view_backend_private {
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
122
0013-ws-Remove-wl_client-pointer-that-can-end-up-dangling.patch
Normal file
122
0013-ws-Remove-wl_client-pointer-that-can-end-up-dangling.patch
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
From 328397f4f4d0e6a3608f6fd8c3ec0abdd5763135 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Perez de Castro <aperez@igalia.com>
|
||||||
|
Date: Wed, 14 Apr 2021 15:55:59 +0300
|
||||||
|
Subject: [PATCH 13/13] ws: Remove wl_client pointer that can end up dangling
|
||||||
|
|
||||||
|
Instead of trying to keep track of the destruction of the wl_client
|
||||||
|
references from ViewBackend::m_client, completely remove the member
|
||||||
|
variable and instead:
|
||||||
|
|
||||||
|
- In ViewBackend::releaseBuffer() use wl_resource_get_client() to obtain
|
||||||
|
the wl_client from the buffer resource. Given that the buffer resource
|
||||||
|
has just been used, it is guaranteed that the wl_client it refers to
|
||||||
|
should be still valid.
|
||||||
|
|
||||||
|
- In ViewBackend::dispatchFrameCallbacks() remove the flush call, and
|
||||||
|
instead do it in WS::Surface::dispatchFrameCallbacks(), and pick the
|
||||||
|
wl_client from the callback resource objects, if any callback was
|
||||||
|
dispatched at all. Again, if any callback was dispatched their
|
||||||
|
associated wl_client should be still valid. Skipping the flush if
|
||||||
|
no callbacks are dispatched is fine because in that case there would
|
||||||
|
not be any messages pending be sent over the wire anyway to trigger
|
||||||
|
dispatching the callbacks in the client side.
|
||||||
|
---
|
||||||
|
src/view-backend-private.cpp | 5 ++---
|
||||||
|
src/view-backend-private.h | 1 -
|
||||||
|
src/ws.cpp | 3 +--
|
||||||
|
src/ws.h | 9 ++++++++-
|
||||||
|
4 files changed, 11 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/view-backend-private.cpp b/src/view-backend-private.cpp
|
||||||
|
index b78831d..7e3a738 100644
|
||||||
|
--- a/src/view-backend-private.cpp
|
||||||
|
+++ b/src/view-backend-private.cpp
|
||||||
|
@@ -95,20 +95,19 @@ void ViewBackend::dispatchFrameCallbacks()
|
||||||
|
if (G_LIKELY(m_bridgeId))
|
||||||
|
WS::Instance::singleton().dispatchFrameCallbacks(m_bridgeId);
|
||||||
|
|
||||||
|
- wl_client_flush(m_client);
|
||||||
|
wpe_view_backend_dispatch_frame_displayed(m_backend);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::releaseBuffer(struct wl_resource* buffer_resource)
|
||||||
|
{
|
||||||
|
wl_buffer_send_release(buffer_resource);
|
||||||
|
- wl_client_flush(m_client);
|
||||||
|
+ wl_client_flush(wl_resource_get_client(buffer_resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::registerSurface(uint32_t bridgeId)
|
||||||
|
{
|
||||||
|
m_bridgeId = bridgeId;
|
||||||
|
- m_client = WS::Instance::singleton().registerViewBackend(m_bridgeId, *this);
|
||||||
|
+ WS::Instance::singleton().registerViewBackend(m_bridgeId, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewBackend::unregisterSurface(uint32_t bridgeId)
|
||||||
|
diff --git a/src/view-backend-private.h b/src/view-backend-private.h
|
||||||
|
index 15e98e6..363b787 100644
|
||||||
|
--- a/src/view-backend-private.h
|
||||||
|
+++ b/src/view-backend-private.h
|
||||||
|
@@ -79,7 +79,6 @@ private:
|
||||||
|
static gboolean s_socketCallback(GSocket*, GIOCondition, gpointer);
|
||||||
|
|
||||||
|
uint32_t m_bridgeId { 0 };
|
||||||
|
- struct wl_client* m_client { nullptr };
|
||||||
|
|
||||||
|
ClientBundle* m_clientBundle;
|
||||||
|
struct wpe_view_backend* m_backend;
|
||||||
|
diff --git a/src/ws.cpp b/src/ws.cpp
|
||||||
|
index 87faaf3..622bbf3 100644
|
||||||
|
--- a/src/ws.cpp
|
||||||
|
+++ b/src/ws.cpp
|
||||||
|
@@ -519,14 +519,13 @@ void Instance::releaseAudioPacketExport(struct wpe_audio_packet_export* packet_e
|
||||||
|
wpe_audio_packet_export_send_release(packet_export->exportResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
-struct wl_client* Instance::registerViewBackend(uint32_t bridgeId, APIClient& apiClient)
|
||||||
|
+void Instance::registerViewBackend(uint32_t bridgeId, APIClient& apiClient)
|
||||||
|
{
|
||||||
|
auto it = m_viewBackendMap.find(bridgeId);
|
||||||
|
if (it == m_viewBackendMap.end())
|
||||||
|
g_error("Instance::registerViewBackend(): " "Cannot find surface with bridgeId %" PRIu32 " in view backend map.", bridgeId);
|
||||||
|
|
||||||
|
it->second->apiClient = &apiClient;
|
||||||
|
- return wl_resource_get_client(it->second->resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instance::unregisterViewBackend(uint32_t bridgeId)
|
||||||
|
diff --git a/src/ws.h b/src/ws.h
|
||||||
|
index 30baf8e..1bf528e 100644
|
||||||
|
--- a/src/ws.h
|
||||||
|
+++ b/src/ws.h
|
||||||
|
@@ -88,10 +88,17 @@ struct Surface {
|
||||||
|
{
|
||||||
|
struct wl_resource* resource;
|
||||||
|
struct wl_resource* tmp;
|
||||||
|
+ struct wl_client* client { nullptr };
|
||||||
|
+
|
||||||
|
wl_resource_for_each_safe(resource, tmp, &m_currentFrameCallbacks) {
|
||||||
|
+ g_assert(!client || client == wl_resource_get_client(resource));
|
||||||
|
+ client = wl_resource_get_client(resource);
|
||||||
|
wl_callback_send_done(resource, 0);
|
||||||
|
wl_resource_destroy(resource);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (client)
|
||||||
|
+ wl_client_flush(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
@@ -129,7 +136,7 @@ public:
|
||||||
|
int createClient();
|
||||||
|
|
||||||
|
void registerSurface(uint32_t, Surface*);
|
||||||
|
- struct wl_client* registerViewBackend(uint32_t, APIClient&);
|
||||||
|
+ void registerViewBackend(uint32_t, APIClient&);
|
||||||
|
void unregisterViewBackend(uint32_t);
|
||||||
|
void dispatchFrameCallbacks(uint32_t);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -2,13 +2,27 @@
|
|||||||
|
|
||||||
Name: wpebackend-fdo
|
Name: wpebackend-fdo
|
||||||
Version: 1.9.90
|
Version: 1.9.90
|
||||||
Release: 1%{?dist}
|
Release: 2%{?dist}
|
||||||
Summary: A WPE backend designed for Linux desktop systems
|
Summary: A WPE backend designed for Linux desktop systems
|
||||||
|
|
||||||
License: BSD
|
License: BSD
|
||||||
URL: https://github.com/Igalia/%{name}
|
URL: https://github.com/Igalia/%{name}
|
||||||
Source0: https://github.com/Igalia/%{name}/archive/%{version}/%{name}-%{version}.tar.xz
|
Source0: https://github.com/Igalia/%{name}/archive/%{version}/%{name}-%{version}.tar.xz
|
||||||
|
|
||||||
|
# https://github.com/Igalia/WPEBackend-fdo/issues/145
|
||||||
|
Patch0: 0001-Add-some-checks-to-ensure-we-properly-bind-server-gl.patch
|
||||||
|
Patch1: 0002-ws-Remove-unneeded-Surface-id-member.patch
|
||||||
|
Patch2: 0003-ws-Rename-surfaceId-to-bridgeId-where-appropriate.patch
|
||||||
|
Patch3: 0004-ws-Accumulate-surface-frame-callbacks-until-commit.patch
|
||||||
|
Patch4: 0006-meson-Make-scripts-version.py-work-with-older-Python.patch
|
||||||
|
Patch5: 0007-Revert-view-backend-Properly-unregister-surfaces.patch
|
||||||
|
Patch6: 0008-Revert-view-backend-private-Move-wl_client_destroy-t.patch
|
||||||
|
Patch7: 0009-Revert-ws-Call-wl_client_destroy-for-the-created-wl_.patch
|
||||||
|
Patch8: 0010-Revert-Cleanups.patch
|
||||||
|
Patch9: 0011-Revert-view-backend-exportable-private-Move-ViewBack.patch
|
||||||
|
Patch10: 0012-Revert-view-backend-exportable-private-Add-wl_client.patch
|
||||||
|
Patch11: 0013-ws-Remove-wl_client-pointer-that-can-end-up-dangling.patch
|
||||||
|
|
||||||
BuildRequires: gcc-c++
|
BuildRequires: gcc-c++
|
||||||
BuildRequires: meson
|
BuildRequires: meson
|
||||||
BuildRequires: pkgconfig(egl)
|
BuildRequires: pkgconfig(egl)
|
||||||
@ -53,6 +67,9 @@ files for developing applications that use %{name}.
|
|||||||
%{_libdir}/pkgconfig/wpebackend-fdo-1.0.pc
|
%{_libdir}/pkgconfig/wpebackend-fdo-1.0.pc
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sat Apr 17 2021 Michael Catanzaro <mcatanzaro@redhat.com> - 1.9.90-2
|
||||||
|
- Stop crashing after process swap
|
||||||
|
|
||||||
* Thu Apr 01 2021 Michael Catanzaro <mcatanzaro@redhat.com> - 1.9.90-1
|
* Thu Apr 01 2021 Michael Catanzaro <mcatanzaro@redhat.com> - 1.9.90-1
|
||||||
- Update to 1.9.90
|
- Update to 1.9.90
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user