blob: 37ca45600a35afb6af9ab67c9bc14bfb013abbe9 [file] [log] [blame]
Andrew Geissler26e4bea2020-11-30 19:54:03 -06001From c5969e5e5c50e2c9b32c6f945040a8e5763ba06c Mon Sep 17 00:00:00 2001
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08002From: Jeff Wannamaker <jeff_wannamaker@cable.comcast.com>
3Date: Sat, 27 Jan 2018 12:28:31 -0500
Andrew Geissler26e4bea2020-11-30 19:54:03 -06004Subject: [PATCH] Allow multiple wayland compositor state data per process
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08005
6When eglBindWaylandDisplayWL is called store the wl_global
7created in a list associated with the wayland display.
8This allows multiple wayland compositor instances to be
9created and used per process. This scenario is common for
10applications integrating externl process UI elements
11via embedded composition e.g. westeros
12
13Signed-off-by: Jeff Wannamaker <jeff_wannamaker@cable.comcast.com>
14Signed-off-by: Khem Raj <raj.khem@gmail.com>
15---
Patrick Williams520786c2023-06-25 16:20:36 -050016Upstream-Status: Pending
17
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080018 interface/khronos/common/khrn_client.c | 2 +-
19 interface/khronos/common/khrn_client.h | 11 +++++-
20 interface/khronos/ext/egl_wayland.c | 50 ++++++++++++++++++++++----
21 3 files changed, 55 insertions(+), 8 deletions(-)
22
23diff --git a/interface/khronos/common/khrn_client.c b/interface/khronos/common/khrn_client.c
24index d7e798e..60bdb63 100644
25--- a/interface/khronos/common/khrn_client.c
26+++ b/interface/khronos/common/khrn_client.c
27@@ -147,7 +147,7 @@ bool client_process_state_init(CLIENT_PROCESS_STATE_T *process)
28 {
29 if (!process->inited) {
30 #ifdef BUILD_WAYLAND
31- process->wl_global = NULL;
32+ process->wlStateMap = NULL;
33 #endif
34
35 if (!khrn_pointer_map_init(&process->contexts, 64))
36diff --git a/interface/khronos/common/khrn_client.h b/interface/khronos/common/khrn_client.h
37index 615f7b4..4fa86f7 100644
38--- a/interface/khronos/common/khrn_client.h
39+++ b/interface/khronos/common/khrn_client.h
40@@ -170,6 +170,15 @@ static INLINE CLIENT_THREAD_STATE_T *CLIENT_GET_CHECK_THREAD_STATE(void)
41 return (CLIENT_THREAD_STATE_T *)platform_tls_get_check(client_tls);
42 }
43
44+#ifdef BUILD_WAYLAND
45+typedef struct WAYLAND_STATE
46+{
47+ struct WAYLAND_STATE *next;
48+ struct wl_display *display;
49+ struct wl_global *wl_global;
50+} WAYLAND_STATE_T;
51+#endif
52+
53 /*
54 per-process state
55
56@@ -318,7 +327,7 @@ struct CLIENT_PROCESS_STATE {
57 struct wl_event_queue *wl_queue;
58
59 /* Compositor-side Wayland state */
60- struct wl_global *wl_global;
61+ WAYLAND_STATE_T *wlStateMap;
62 #endif
63 };
64
65diff --git a/interface/khronos/ext/egl_wayland.c b/interface/khronos/ext/egl_wayland.c
66index 9ef89cd..abd5ab3 100644
67--- a/interface/khronos/ext/egl_wayland.c
68+++ b/interface/khronos/ext/egl_wayland.c
69@@ -208,17 +208,38 @@ eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
70 {
71 CLIENT_THREAD_STATE_T *thread;
72 CLIENT_PROCESS_STATE_T *process;
73+ WAYLAND_STATE_T *stateIter;
74+ WAYLAND_STATE_T *stateNew;
75+ struct wl_global *wl_global;
76
77 if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
78 return EGL_FALSE;
79
80- if (process->wl_global != NULL)
81+ stateIter= process->wlStateMap;
82+ while( stateIter )
83+ {
84+ if ( stateIter->display == display )
85+ goto error;
86+ stateIter= stateIter->next;
87+ }
88+
89+ wl_global = wl_global_create(display, &wl_dispmanx_interface, 1,
90+ NULL, bind_dispmanx);
91+ if (wl_global == NULL)
92 goto error;
93
94- process->wl_global = wl_global_create(display, &wl_dispmanx_interface, 1,
95- NULL, bind_dispmanx);
96- if (process->wl_global == NULL)
97+ stateNew= (WAYLAND_STATE_T*)calloc( 1, sizeof(WAYLAND_STATE_T));
98+ if (stateNew == NULL )
99+ {
100+ wl_global_destroy(wl_global);
101 goto error;
102+ }
103+
104+ stateNew->next= process->wlStateMap;
105+ stateNew->display= display;
106+ stateNew->wl_global= wl_global;
107+ process->wlStateMap= stateNew;
108+ CLIENT_UNLOCK();
109
110 return EGL_TRUE;
111
112@@ -232,12 +253,29 @@ eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
113 {
114 CLIENT_THREAD_STATE_T *thread;
115 CLIENT_PROCESS_STATE_T *process;
116+ WAYLAND_STATE_T *stateIter;
117+ WAYLAND_STATE_T *statePrev;
118
119 if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
120 return EGL_FALSE;
121
122- wl_global_destroy(process->wl_global);
123- process->wl_global = NULL;
124+ statePrev= NULL;
125+ stateIter= process->wlStateMap;
126+ while( stateIter )
127+ {
128+ if ( stateIter->display == display )
129+ {
130+ wl_global_destroy(stateIter->wl_global);
131+ if ( statePrev )
132+ statePrev->next= stateIter->next;
133+ else
134+ process->wlStateMap= stateIter->next;
135+ free( stateIter );
136+ break;
137+ }
138+ statePrev= stateIter;
139+ stateIter= stateIter->next;
140+ }
141
142 CLIENT_UNLOCK();
143