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--- 16 interface/khronos/common/khrn_client.c | 2 +- 17 interface/khronos/common/khrn_client.h | 11 +++++- 18 interface/khronos/ext/egl_wayland.c | 50 ++++++++++++++++++++++---- 19 3 files changed, 55 insertions(+), 8 deletions(-) 20 21diff --git a/interface/khronos/common/khrn_client.c b/interface/khronos/common/khrn_client.c 22index d7e798e..60bdb63 100644 23--- a/interface/khronos/common/khrn_client.c 24+++ b/interface/khronos/common/khrn_client.c 25@@ -147,7 +147,7 @@ bool client_process_state_init(CLIENT_PROCESS_STATE_T *process) 26 { 27 if (!process->inited) { 28 #ifdef BUILD_WAYLAND 29- process->wl_global = NULL; 30+ process->wlStateMap = NULL; 31 #endif 32 33 if (!khrn_pointer_map_init(&process->contexts, 64)) 34diff --git a/interface/khronos/common/khrn_client.h b/interface/khronos/common/khrn_client.h 35index 615f7b4..4fa86f7 100644 36--- a/interface/khronos/common/khrn_client.h 37+++ b/interface/khronos/common/khrn_client.h 38@@ -170,6 +170,15 @@ static INLINE CLIENT_THREAD_STATE_T *CLIENT_GET_CHECK_THREAD_STATE(void) 39 return (CLIENT_THREAD_STATE_T *)platform_tls_get_check(client_tls); 40 } 41 42+#ifdef BUILD_WAYLAND 43+typedef struct WAYLAND_STATE 44+{ 45+ struct WAYLAND_STATE *next; 46+ struct wl_display *display; 47+ struct wl_global *wl_global; 48+} WAYLAND_STATE_T; 49+#endif 50+ 51 /* 52 per-process state 53 54@@ -318,7 +327,7 @@ struct CLIENT_PROCESS_STATE { 55 struct wl_event_queue *wl_queue; 56 57 /* Compositor-side Wayland state */ 58- struct wl_global *wl_global; 59+ WAYLAND_STATE_T *wlStateMap; 60 #endif 61 }; 62 63diff --git a/interface/khronos/ext/egl_wayland.c b/interface/khronos/ext/egl_wayland.c 64index 9ef89cd..abd5ab3 100644 65--- a/interface/khronos/ext/egl_wayland.c 66+++ b/interface/khronos/ext/egl_wayland.c 67@@ -208,17 +208,38 @@ eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) 68 { 69 CLIENT_THREAD_STATE_T *thread; 70 CLIENT_PROCESS_STATE_T *process; 71+ WAYLAND_STATE_T *stateIter; 72+ WAYLAND_STATE_T *stateNew; 73+ struct wl_global *wl_global; 74 75 if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process)) 76 return EGL_FALSE; 77 78- if (process->wl_global != NULL) 79+ stateIter= process->wlStateMap; 80+ while( stateIter ) 81+ { 82+ if ( stateIter->display == display ) 83+ goto error; 84+ stateIter= stateIter->next; 85+ } 86+ 87+ wl_global = wl_global_create(display, &wl_dispmanx_interface, 1, 88+ NULL, bind_dispmanx); 89+ if (wl_global == NULL) 90 goto error; 91 92- process->wl_global = wl_global_create(display, &wl_dispmanx_interface, 1, 93- NULL, bind_dispmanx); 94- if (process->wl_global == NULL) 95+ stateNew= (WAYLAND_STATE_T*)calloc( 1, sizeof(WAYLAND_STATE_T)); 96+ if (stateNew == NULL ) 97+ { 98+ wl_global_destroy(wl_global); 99 goto error; 100+ } 101+ 102+ stateNew->next= process->wlStateMap; 103+ stateNew->display= display; 104+ stateNew->wl_global= wl_global; 105+ process->wlStateMap= stateNew; 106+ CLIENT_UNLOCK(); 107 108 return EGL_TRUE; 109 110@@ -232,12 +253,29 @@ eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) 111 { 112 CLIENT_THREAD_STATE_T *thread; 113 CLIENT_PROCESS_STATE_T *process; 114+ WAYLAND_STATE_T *stateIter; 115+ WAYLAND_STATE_T *statePrev; 116 117 if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process)) 118 return EGL_FALSE; 119 120- wl_global_destroy(process->wl_global); 121- process->wl_global = NULL; 122+ statePrev= NULL; 123+ stateIter= process->wlStateMap; 124+ while( stateIter ) 125+ { 126+ if ( stateIter->display == display ) 127+ { 128+ wl_global_destroy(stateIter->wl_global); 129+ if ( statePrev ) 130+ statePrev->next= stateIter->next; 131+ else 132+ process->wlStateMap= stateIter->next; 133+ free( stateIter ); 134+ break; 135+ } 136+ statePrev= stateIter; 137+ stateIter= stateIter->next; 138+ } 139 140 CLIENT_UNLOCK(); 141 142