1From c5969e5e5c50e2c9b32c6f945040a8e5763ba06c Mon Sep 17 00:00:00 2001 2From: Jeff Wannamaker <jeff_wannamaker@cable.comcast.com> 3Date: Sat, 27 Jan 2018 12:28:31 -0500 4Subject: [PATCH] Allow multiple wayland compositor state data per process 5 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--- 16Upstream-Status: Pending 17 18 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 144