blob: 461350407e8e969b2030bb0d96b0293f1dc3f3ae [file] [log] [blame]
Brad Bishop316dfdd2018-06-25 12:45:53 -04001From 5608ec8002be8370e78c9dbb1e07cee4cfb18b58 Mon Sep 17 00:00:00 2001
Patrick Williams8b8bc412016-08-17 15:02:23 -05002From: Tomeu Vizoso <tomeu.vizoso@collabora.com>
3Date: Tue, 1 Oct 2013 13:19:20 +0200
Brad Bishop316dfdd2018-06-25 12:45:53 -04004Subject: [PATCH 02/16] wayland: Add support for the Wayland winsys
Patrick Williams8b8bc412016-08-17 15:02:23 -05005
6* Adds EGL_WL_bind_wayland_display extension
7* Adds wayland-egl library
8* Adds wl_dispmanx_buffer protocol extension
9
10TODO: Check that platform_get_dimensions() returning swapchain_count == 1 is correct
11
12TODO: Remove the requirement of passing a valid DispmanX element handle to
13the SwapBuffers and CreateSurface RPC calls. This will remove the need to open
14a DispmanX display from the clients.
15
16TODO: wl_dispmanx_server_buffer should probably be defined in a
17private header that can be included from EGL and vc_* instead of in
18vc_vchi_dispmanx.h
19---
Brad Bishop6e60e8b2018-02-01 10:27:11 -050020 .gitignore | 1 +
Patrick Williams8b8bc412016-08-17 15:02:23 -050021 CMakeLists.txt | 11 +
22 README.md | 4 +
Patrick Williamsb2e6a9b2017-02-23 20:31:26 -060023 buildme | 10 +-
24 .../linux/apps/raspicam/CMakeLists.txt | 2 +-
25 interface/khronos/CMakeLists.txt | 53 ++++-
Patrick Williams8b8bc412016-08-17 15:02:23 -050026 interface/khronos/common/khrn_client.c | 15 ++
27 interface/khronos/common/khrn_client.h | 10 +
28 interface/khronos/common/khrn_client_mangle.h | 3 +
29 interface/khronos/common/khrn_client_platform.h | 8 +
30 interface/khronos/common/khrn_client_unmangle.h | 3 +
31 .../common/linux/khrn_client_platform_linux.c | 115 ++++++++--
32 interface/khronos/common/linux/khrn_wayland.c | 215 ++++++++++++++++++
33 .../common/linux/khrn_wayland.h} | 46 +---
34 interface/khronos/egl/egl_client.c | 92 +++++---
35 interface/khronos/egl/egl_client_get_proc.c | 11 +
36 interface/khronos/egl/egl_client_surface.c | 42 +++-
37 interface/khronos/egl/egl_client_surface.h | 38 +++-
38 interface/khronos/egl/egl_int_impl.h | 2 +-
39 interface/khronos/ext/egl_wayland.c | 246 +++++++++++++++++++++
40 interface/khronos/include/EGL/eglext.h | 23 ++
41 interface/khronos/wayland-egl/wayland-egl-priv.h | 53 +++++
42 interface/khronos/wayland-egl/wayland-egl.c | 59 +++++
43 interface/khronos/wayland-egl/wayland-egl.pc.in | 10 +
44 interface/vmcs_host/CMakeLists.txt | 21 +-
45 interface/vmcs_host/vc_dispmanx.h | 10 +
46 interface/vmcs_host/vc_vchi_dispmanx.c | 42 ++++
47 interface/vmcs_host/vc_vchi_dispmanx.h | 15 ++
48 interface/wayland/dispmanx.xml | 123 +++++++++++
49 makefiles/cmake/Wayland.cmake | 72 ++++++
Brad Bishop6e60e8b2018-02-01 10:27:11 -050050 30 files changed, 1257 insertions(+), 98 deletions(-)
Patrick Williams8b8bc412016-08-17 15:02:23 -050051 create mode 100644 interface/khronos/common/linux/khrn_wayland.c
52 copy interface/{vmcs_host/vc_vchi_dispmanx.h => khronos/common/linux/khrn_wayland.h} (56%)
53 create mode 100644 interface/khronos/ext/egl_wayland.c
54 create mode 100644 interface/khronos/wayland-egl/wayland-egl-priv.h
55 create mode 100644 interface/khronos/wayland-egl/wayland-egl.c
56 create mode 100644 interface/khronos/wayland-egl/wayland-egl.pc.in
57 create mode 100644 interface/wayland/dispmanx.xml
58 create mode 100644 makefiles/cmake/Wayland.cmake
59
Brad Bishop316dfdd2018-06-25 12:45:53 -040060Index: git/.gitignore
61===================================================================
62--- git.orig/.gitignore
63+++ git/.gitignore
Brad Bishop6e60e8b2018-02-01 10:27:11 -050064@@ -30,3 +30,4 @@ build/
65 *.pts
66 *.ppm
67 *.mkv
Patrick Williams8b8bc412016-08-17 15:02:23 -050068+*~
Brad Bishop316dfdd2018-06-25 12:45:53 -040069Index: git/CMakeLists.txt
70===================================================================
71--- git.orig/CMakeLists.txt
72+++ git/CMakeLists.txt
73@@ -24,6 +24,17 @@ include(makefiles/cmake/global_settings.
Patrick Williams8b8bc412016-08-17 15:02:23 -050074 include(makefiles/cmake/arm-linux.cmake)
75 include(makefiles/cmake/vmcs.cmake)
76
77+if (BUILD_WAYLAND)
78+ include(makefiles/cmake/Wayland.cmake)
79+
80+ # Find Wayland libraries
81+ find_package(PkgConfig)
82+ pkg_check_modules(WAYLAND_CLIENT wayland-client REQUIRED)
83+ pkg_check_modules(WAYLAND_SERVER wayland-server REQUIRED)
84+
85+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBUILD_WAYLAND")
86+endif()
87+
88 enable_language(ASM)
89
90 # Global include paths
Brad Bishop316dfdd2018-06-25 12:45:53 -040091Index: git/README.md
92===================================================================
93--- git.orig/README.md
94+++ git/README.md
95@@ -6,3 +6,7 @@ Use buildme to build. It requires cmake
Patrick Williams8b8bc412016-08-17 15:02:23 -050096 https://github.com/raspberrypi/tools/tree/master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian
Brad Bishop316dfdd2018-06-25 12:45:53 -040097
98 Note that this repository does not contain the source for the edid_parser and vcdbg binaries due to licensing restrictions.
Patrick Williams8b8bc412016-08-17 15:02:23 -050099+
100+To build support for the Wayland winsys in EGL, execute the buildme script like this:
101+
102+$ BUILD_WAYLAND=1 ./buildme.
Brad Bishop316dfdd2018-06-25 12:45:53 -0400103Index: git/buildme
104===================================================================
105--- git.orig/buildme
106+++ git/buildme
Patrick Williamsb2e6a9b2017-02-23 20:31:26 -0600107@@ -8,6 +8,10 @@ fi
108
109 BUILDSUBDIR=`echo $BUILDTYPE | tr '[A-Z]' '[a-z]'`;
Patrick Williams8b8bc412016-08-17 15:02:23 -0500110
111+if [ -n "$BUILD_WAYLAND" ]; then
112+ WAYLAND_VARS="-DBUILD_WAYLAND=TRUE"
113+fi
114+
115 if [ "armv6l" = `arch` ] || [ "armv7l" = `arch` ]; then
116 # Native compile on the Raspberry Pi
Patrick Williamsb2e6a9b2017-02-23 20:31:26 -0600117 mkdir -p build/raspberry/$BUILDSUBDIR
118@@ -32,9 +36,13 @@ elif [ "$1" = "--native" ]; then
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500119 make -j `nproc` $*
Patrick Williams8b8bc412016-08-17 15:02:23 -0500120 else
121 # Cross compile on a more capable machine
Patrick Williams8b8bc412016-08-17 15:02:23 -0500122+ if [ -n "$BUILD_WAYLAND" ]; then
123+ # Use wayland-scanner from the build platform
124+ WAYLAND_VARS+=" -DWAYLAND_SCANNER_EXECUTABLE:FILEPATH=/usr/bin/wayland-scanner"
125+ fi
Patrick Williamsb2e6a9b2017-02-23 20:31:26 -0600126 mkdir -p build/arm-linux/$BUILDSUBDIR
127 pushd build/arm-linux/$BUILDSUBDIR
128- cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=$BUILDTYPE ../../..
129+ cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=$BUILDTYPE $WAYLAND_VARS ../../..
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500130 make -j `nproc`
Patrick Williams8b8bc412016-08-17 15:02:23 -0500131
132 if [ "$1" != "" ]; then
Brad Bishop316dfdd2018-06-25 12:45:53 -0400133Index: git/host_applications/linux/apps/raspicam/CMakeLists.txt
134===================================================================
135--- git.orig/host_applications/linux/apps/raspicam/CMakeLists.txt
136+++ git/host_applications/linux/apps/raspicam/CMakeLists.txt
137@@ -28,7 +28,7 @@ add_executable(raspividyuv ${COMMON_SOU
Patrick Williamsb2e6a9b2017-02-23 20:31:26 -0600138
139 set (MMAL_LIBS mmal_core mmal_util mmal_vc_client)
140
141-target_link_libraries(raspistill ${MMAL_LIBS} vcos bcm_host brcmGLESv2 brcmEGL m)
142+target_link_libraries(raspistill ${MMAL_LIBS} vcos bcm_host brcmGLESv2 brcmEGL m ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_CLIENT_LIBRARIES})
143 target_link_libraries(raspiyuv ${MMAL_LIBS} vcos bcm_host)
144 target_link_libraries(raspivid ${MMAL_LIBS} vcos bcm_host)
145 target_link_libraries(raspividyuv ${MMAL_LIBS} vcos bcm_host)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400146Index: git/interface/khronos/CMakeLists.txt
147===================================================================
148--- git.orig/interface/khronos/CMakeLists.txt
149+++ git/interface/khronos/CMakeLists.txt
Patrick Williams8b8bc412016-08-17 15:02:23 -0500150@@ -6,6 +6,12 @@
151 # have quite a few circular dependencies, and so the only way
152 # to make it work seems to be to have everything static.
153
154+if (BUILD_WAYLAND)
155+include_directories(
156+ ${WAYLAND_SERVER_INCLUDE_DIRS}
157+)
158+endif ()
159+
160 set(EGL_SOURCE
161 egl/egl_client_config.c
162 egl/egl_client_context.c
Brad Bishop316dfdd2018-06-25 12:45:53 -0400163@@ -55,12 +61,55 @@ set(CLIENT_SOURCE
Patrick Williams8b8bc412016-08-17 15:02:23 -0500164 common/khrn_int_hash_asm.s
165 common/khrn_client_cache.c)
166
167+set(EGL_LIBS
168+ khrn_client
169+ vchiq_arm
170+ vcos
Brad Bishop316dfdd2018-06-25 12:45:53 -0400171+ bcm_host)
Patrick Williams8b8bc412016-08-17 15:02:23 -0500172+
173+if (BUILD_WAYLAND)
174+ set(EGL_SOURCE
175+ ${EGL_SOURCE}
176+ ext/egl_wayland.c
177+ common/linux/khrn_wayland.c)
178+
179+ set(EGL_LIBS
180+ ${EGL_LIBS}
181+ wayland-client
182+ wayland-server)
183+
184+ set(WAYLAND_EGL_SOURCE
185+ wayland-egl/wayland-egl.c)
186+
187+ wayland_add_protocol_server(
188+ EGL_SOURCE
189+ ../../interface/wayland/dispmanx.xml
190+ dispmanx
191+ )
192+
193+ wayland_add_protocol_client(
194+ EGL_SOURCE
195+ ../../interface/wayland/dispmanx.xml
196+ dispmanx
197+ )
198+
199+ add_library(wayland-egl ${SHARED} ${WAYLAND_EGL_SOURCE})
200+ install(TARGETS wayland-egl DESTINATION lib)
201+
202+ configure_file ("wayland-egl/wayland-egl.pc.in" "wayland-egl/wayland-egl.pc" @ONLY)
203+ install (FILES "${CMAKE_CURRENT_BINARY_DIR}/wayland-egl/wayland-egl.pc"
204+ DESTINATION lib/pkgconfig)
205+endif ()
206+
207 add_library(EGL ${SHARED} ${EGL_SOURCE})
208 add_library(GLESv2 ${SHARED} ${GLES_SOURCE})
209 add_library(OpenVG ${SHARED} ${VG_SOURCE})
210 add_library(WFC ${SHARED} ${WFC_SOURCE})
211 add_library(khrn_client ${CLIENT_SOURCE})
212
213+set_target_properties(EGL PROPERTIES SOVERSION 1 VERSION 1.0.0)
214+set_target_properties(GLESv2 PROPERTIES SOVERSION 2 VERSION 2.0.0)
215+
216 # TODO do we need EGL_static and GLESv2_static now that khrn_static exists?
217 add_library(EGL_static STATIC ${EGL_SOURCE})
218 add_library(GLESv2_static STATIC ${GLES_SOURCE})
Brad Bishop316dfdd2018-06-25 12:45:53 -0400219@@ -72,8 +121,7 @@ include_directories (../../host_applicat
Patrick Williamsb2e6a9b2017-02-23 20:31:26 -0600220 set(VCSM_LIBS vcsm)
221 add_definitions(-DKHRONOS_HAVE_VCSM)
222 endif()
223-
224-target_link_libraries(EGL khrn_client vchiq_arm vcos bcm_host ${VCSM_LIBS} -lm)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400225+target_link_libraries(EGL ${EGL_LIBS} ${VCSM_LIBS} -lm)
Patrick Williams8b8bc412016-08-17 15:02:23 -0500226 target_link_libraries(GLESv2 EGL khrn_client vcos)
227 target_link_libraries(WFC EGL)
228 target_link_libraries(OpenVG EGL)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400229@@ -87,7 +135,7 @@ add_library(brcmGLESv2 ${SHARED} ${GLES_
230 add_library(brcmOpenVG ${SHARED} ${VG_SOURCE})
231 add_library(brcmWFC ${SHARED} ${WFC_SOURCE})
232
233-target_link_libraries(brcmEGL khrn_client vchiq_arm vcos bcm_host ${VCSM_LIBS} -lm)
234+target_link_libraries(brcmEGL ${EGL_LIBS} ${VCSM_LIBS} -lm)
235 target_link_libraries(brcmGLESv2 brcmEGL khrn_client vcos)
236 target_link_libraries(brcmWFC brcmEGL)
237 target_link_libraries(brcmOpenVG brcmEGL)
238Index: git/interface/khronos/common/khrn_client.c
239===================================================================
240--- git.orig/interface/khronos/common/khrn_client.c
241+++ git/interface/khronos/common/khrn_client.c
242@@ -54,6 +54,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
Patrick Williams8b8bc412016-08-17 15:02:23 -0500243 #include "applications/vmcs/khronos/khronos_server.h"
244 #endif
245
246+#ifdef BUILD_WAYLAND
247+#include "interface/khronos/common/linux/khrn_wayland.h"
248+#endif
249+
250 VCOS_LOG_CAT_T khrn_client_log = VCOS_LOG_INIT("khrn_client", VCOS_LOG_WARN);
251
252 /*
Brad Bishop316dfdd2018-06-25 12:45:53 -0400253@@ -142,6 +146,10 @@ void client_try_unload_server(CLIENT_PRO
Patrick Williams8b8bc412016-08-17 15:02:23 -0500254 bool client_process_state_init(CLIENT_PROCESS_STATE_T *process)
255 {
256 if (!process->inited) {
257+#ifdef BUILD_WAYLAND
258+ process->wl_global = NULL;
259+#endif
260+
261 if (!khrn_pointer_map_init(&process->contexts, 64))
262 return false;
263
Brad Bishop316dfdd2018-06-25 12:45:53 -0400264@@ -194,6 +202,13 @@ bool client_process_state_init(CLIENT_PR
Patrick Williams8b8bc412016-08-17 15:02:23 -0500265 }
266 #endif
267
268+#ifdef BUILD_WAYLAND
269+ struct wl_display *wl_display = khrn_platform_get_wl_display();
270+ if (wl_display)
271+ if (!init_process_wayland(process))
272+ return false;
273+#endif
274+
275 process->inited = true;
276 }
277
Brad Bishop316dfdd2018-06-25 12:45:53 -0400278Index: git/interface/khronos/common/khrn_client.h
279===================================================================
280--- git.orig/interface/khronos/common/khrn_client.h
281+++ git/interface/khronos/common/khrn_client.h
Patrick Williams8b8bc412016-08-17 15:02:23 -0500282@@ -310,6 +310,16 @@ struct CLIENT_PROCESS_STATE {
283 #ifdef RPC_LIBRARY
284 KHRONOS_SERVER_CONNECTION_T khrn_connection;
285 #endif
286+
287+#ifdef BUILD_WAYLAND
288+ /* Client-side Wayland state */
289+ struct wl_registry *wl_registry;
290+ struct wl_dispmanx *wl_dispmanx;
291+ struct wl_event_queue *wl_queue;
292+
293+ /* Compositor-side Wayland state */
294+ struct wl_global *wl_global;
295+#endif
296 };
297
298 extern bool client_process_state_init(CLIENT_PROCESS_STATE_T *process);
Brad Bishop316dfdd2018-06-25 12:45:53 -0400299Index: git/interface/khronos/common/khrn_client_mangle.h
300===================================================================
301--- git.orig/interface/khronos/common/khrn_client_mangle.h
302+++ git/interface/khronos/common/khrn_client_mangle.h
303@@ -83,6 +83,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
Patrick Williams8b8bc412016-08-17 15:02:23 -0500304 #define eglReleaseGlobalImageBRCM mangled_eglReleaseGlobalImageBRCM
305 #define eglInitGlobalImageBRCM mangled_eglInitGlobalImageBRCM
306 #define eglTermGlobalImageBRCM mangled_eglTermGlobalImageBRCM
307+#define eglBindWaylandDisplayWL mangled_eglBindWaylandDisplayWL
308+#define eglUnbindWaylandDisplayWL mangled_eglUnbindWaylandDisplayWL
309+#define eglQueryWaylandBufferWL mangled_eglQueryWaylandBufferWL
310
311 /* OpenGL ES 1.1 and 2.0 functions */
312
Brad Bishop316dfdd2018-06-25 12:45:53 -0400313Index: git/interface/khronos/common/khrn_client_platform.h
314===================================================================
315--- git.orig/interface/khronos/common/khrn_client_platform.h
316+++ git/interface/khronos/common/khrn_client_platform.h
317@@ -48,6 +48,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
Patrick Williams8b8bc412016-08-17 15:02:23 -0500318 #include "interface/khronos/common/vcos/khrn_client_platform_filler_vcos.h"
319 #endif
320
321+#ifdef BUILD_WAYLAND
322+#include <wayland-client.h>
323+#endif
324+
325 #ifdef __cplusplus
326 extern "C" {
327 #endif
328@@ -328,4 +332,8 @@ typedef struct
329
330 void *platform_wfc_bounce_thread(void *param);
331
332+#ifdef BUILD_WAYLAND
333+struct wl_display *khrn_platform_get_wl_display();
334+#endif
335+
336 #endif // KHRN_CLIENT_PLATFORM_H
Brad Bishop316dfdd2018-06-25 12:45:53 -0400337Index: git/interface/khronos/common/khrn_client_unmangle.h
338===================================================================
339--- git.orig/interface/khronos/common/khrn_client_unmangle.h
340+++ git/interface/khronos/common/khrn_client_unmangle.h
341@@ -83,6 +83,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
Patrick Williams8b8bc412016-08-17 15:02:23 -0500342 #undef eglReleaseGlobalImageBRCM
343 #undef eglInitGlobalImageBRCM
344 #undef eglTermGlobalImageBRCM
345+#undef eglBindWaylandDisplayWL
346+#undef eglUnbindWaylandDisplayWL
347+#undef eglQueryWaylandBufferWL
348
349 /* OpenGL ES 1.1 and 2.0 functions */
350
Brad Bishop316dfdd2018-06-25 12:45:53 -0400351Index: git/interface/khronos/common/linux/khrn_client_platform_linux.c
352===================================================================
353--- git.orig/interface/khronos/common/linux/khrn_client_platform_linux.c
354+++ git/interface/khronos/common/linux/khrn_client_platform_linux.c
355@@ -37,6 +37,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
Patrick Williams8b8bc412016-08-17 15:02:23 -0500356 #include "X11/Xlib.h"
357 #endif
358
359+#ifdef BUILD_WAYLAND
360+#include <wayland-client.h>
361+#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
362+#endif
363+
364 extern VCOS_LOG_CAT_T khrn_client_log;
365
366 extern void vc_vchi_khronos_init();
Brad Bishop316dfdd2018-06-25 12:45:53 -0400367@@ -464,14 +469,37 @@ EGLDisplay khrn_platform_set_display_id(
Patrick Williams8b8bc412016-08-17 15:02:23 -0500368 return EGL_NO_DISPLAY;
369 }
370 #else
371+
372+#ifdef BUILD_WAYLAND
373+static struct wl_display *hacky_display = NULL;
374+#endif
375+
376 EGLDisplay khrn_platform_set_display_id(EGLNativeDisplayType display_id)
377 {
378 if (display_id == EGL_DEFAULT_DISPLAY)
379 return (EGLDisplay)1;
380- else
381- return EGL_NO_DISPLAY;
382+ else {
383+#ifdef BUILD_WAYLAND
384+ void *first_pointer = *(void **) display_id;
385+
386+ /* wl_display is a wl_proxy, which is a wl_object.
387+ * wl_object's first element points to the interfacetype. */
388+ if (first_pointer == &wl_display_interface) {
389+ hacky_display = (struct wl_display*)display_id;
390+ return (EGLDisplay)1;
391+ } else
392+#endif
393+ return EGL_NO_DISPLAY;
394+ }
Brad Bishop316dfdd2018-06-25 12:45:53 -0400395+}
Patrick Williams8b8bc412016-08-17 15:02:23 -0500396+
397+#ifdef BUILD_WAYLAND
398+struct wl_display *khrn_platform_get_wl_display()
399+{
400+ return hacky_display;
Brad Bishop316dfdd2018-06-25 12:45:53 -0400401 }
Patrick Williams8b8bc412016-08-17 15:02:23 -0500402 #endif
Brad Bishop316dfdd2018-06-25 12:45:53 -0400403+#endif
Patrick Williams8b8bc412016-08-17 15:02:23 -0500404
405 #ifdef WANT_X
Brad Bishop316dfdd2018-06-25 12:45:53 -0400406 static void dump_hierarchy(Window w, Window thisw, Window look, int level)
407@@ -805,22 +833,81 @@ static EGL_DISPMANX_WINDOW_T *check_defa
Patrick Williams8b8bc412016-08-17 15:02:23 -0500408 void platform_get_dimensions(EGLDisplay dpy, EGLNativeWindowType win,
409 uint32_t *width, uint32_t *height, uint32_t *swapchain_count)
410 {
411- EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
412- vcos_assert(dwin);
413- vcos_assert(dwin->width < 1<<16); // sanity check
414- vcos_assert(dwin->height < 1<<16); // sanity check
415- *width = dwin->width;
416- *height = dwin->height;
417- *swapchain_count = 0;
418+#ifdef BUILD_WAYLAND
419+ if(khrn_platform_get_wl_display()) {
420+ struct wl_egl_window *wl_egl_window = (struct wl_egl_window*)win;
421+ *width = wl_egl_window->width;
422+ *height = wl_egl_window->height;
423+ /* This seems to be used for sync'ing with the VC on buffer creation, but
424+ we are managing them on the CPU side */
425+ *swapchain_count = 1;
426+ } else {
427+#endif
428+ EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
429+ vcos_assert(dwin);
430+ vcos_assert(dwin->width < 1<<16); // sanity check
431+ vcos_assert(dwin->height < 1<<16); // sanity check
432+ *width = dwin->width;
433+ *height = dwin->height;
434+ *swapchain_count = 0;
435+#ifdef BUILD_WAYLAND
436+ }
437+#endif
Brad Bishop316dfdd2018-06-25 12:45:53 -0400438+}
439+
Patrick Williams8b8bc412016-08-17 15:02:23 -0500440+#ifdef BUILD_WAYLAND
441+static DISPMANX_ELEMENT_HANDLE_T create_dummy_element()
442+{
443+ DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(0);
444+ DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);
445+ DISPMANX_ELEMENT_HANDLE_T element;
446+ VC_DISPMANX_ALPHA_T alpha = {DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0};
447+ VC_RECT_T src_rect;
448+ VC_RECT_T dst_rect;
449+
450+ src_rect.x = 0;
451+ src_rect.y = 0;
452+ src_rect.width = 1 << 16;
453+ src_rect.height = 1 << 16;
454+
455+ dst_rect.x = 0;
456+ dst_rect.y = 0;
457+ dst_rect.width = 1;
458+ dst_rect.height = 1;
459+
460+ element = vc_dispmanx_element_add(update, display, 0/*layer*/, &dst_rect,
461+ 0/*src*/, &src_rect,
462+ DISPMANX_PROTECTION_NONE, &alpha,
463+ 0/*clamp*/, 0/*transform*/);
464+
465+ vc_dispmanx_update_submit_sync(update);
466+
467+ vc_dispmanx_display_close(display);
468+
469+ return element;
Brad Bishop316dfdd2018-06-25 12:45:53 -0400470 }
Patrick Williams8b8bc412016-08-17 15:02:23 -0500471+#endif
Brad Bishop316dfdd2018-06-25 12:45:53 -0400472
Patrick Williams8b8bc412016-08-17 15:02:23 -0500473 uint32_t platform_get_handle(EGLDisplay dpy, EGLNativeWindowType win)
474 {
475- EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
476- vcos_assert(dwin);
477- vcos_assert(dwin->width < 1<<16); // sanity check
478- vcos_assert(dwin->height < 1<<16); // sanity check
479- return dwin->element;
480+#ifdef BUILD_WAYLAND
481+ if(khrn_platform_get_wl_display()) {
482+ struct wl_egl_window *wl_egl_window = (struct wl_egl_window*)win;
483+
484+ if (wl_egl_window->dummy_element == PLATFORM_WIN_NONE)
485+ wl_egl_window->dummy_element = create_dummy_element();
486+
487+ return wl_egl_window->dummy_element;
488+ } else {
489+#endif
490+ EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
491+ vcos_assert(dwin);
492+ vcos_assert(dwin->width < 1<<16); // sanity check
493+ vcos_assert(dwin->height < 1<<16); // sanity check
494+ return dwin->element;
495+#ifdef BUILD_WAYLAND
496+ }
497+#endif
498 }
499
500 #endif
Brad Bishop316dfdd2018-06-25 12:45:53 -0400501Index: git/interface/khronos/common/linux/khrn_wayland.c
502===================================================================
Patrick Williams8b8bc412016-08-17 15:02:23 -0500503--- /dev/null
Brad Bishop316dfdd2018-06-25 12:45:53 -0400504+++ git/interface/khronos/common/linux/khrn_wayland.c
Patrick Williams8b8bc412016-08-17 15:02:23 -0500505@@ -0,0 +1,215 @@
506+/*
507+Copyright (c) 2013, Raspberry Pi Foundation
508+All rights reserved.
509+
510+Redistribution and use in source and binary forms, with or without
511+modification, are permitted provided that the following conditions are met:
512+ * Redistributions of source code must retain the above copyright
513+ notice, this list of conditions and the following disclaimer.
514+ * Redistributions in binary form must reproduce the above copyright
515+ notice, this list of conditions and the following disclaimer in the
516+ documentation and/or other materials provided with the distribution.
517+ * Neither the name of the copyright holder nor the
518+ names of its contributors may be used to endorse or promote products
519+ derived from this software without specific prior written permission.
520+
521+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
522+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
523+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
524+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
525+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
526+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
527+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
528+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
529+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
530+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
531+*/
532+
533+#define VCOS_LOG_CATEGORY (&khrn_client_log)
534+
535+#include "interface/khronos/common/linux/khrn_wayland.h"
536+#include "interface/khronos/wayland-dispmanx-client-protocol.h"
537+#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
538+
539+extern VCOS_LOG_CAT_T khrn_client_log;
540+
541+static void handle_dispmanx_format(void *data, struct wl_dispmanx *dispmanx,
542+ uint32_t format)
543+{
544+}
545+
546+static void handle_dispmanx_allocated(void *data, struct wl_dispmanx *dispmanx,
547+ struct wl_buffer *wl_buffer,
548+ uint32_t resource_handle)
549+{
550+ struct wl_dispmanx_client_buffer *buffer = wl_buffer_get_user_data(wl_buffer);
551+
552+ buffer->pending_allocation = 0;
553+ buffer->resource = resource_handle;
554+}
555+
556+static const struct wl_dispmanx_listener dispmanx_listener = {
557+ handle_dispmanx_format,
558+ handle_dispmanx_allocated,
559+};
560+
561+static void
562+sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
563+{
564+ int *done = data;
565+
566+ *done = 1;
567+
568+ wl_callback_destroy(callback);
569+}
570+
571+static const struct wl_callback_listener sync_listener = {
572+ sync_callback
573+};
574+
575+static int
576+roundtrip(CLIENT_PROCESS_STATE_T *process)
577+{
578+ struct wl_display *wl_display = khrn_platform_get_wl_display();
579+ struct wl_callback *callback;
580+ int done = 0, ret = 0;
581+
582+ callback = wl_display_sync(wl_display);
583+ wl_callback_add_listener(callback, &sync_listener, &done);
584+ wl_proxy_set_queue((struct wl_proxy *) callback, process->wl_queue);
585+ while (ret != -1 && !done)
586+ ret = wl_display_dispatch_queue(wl_display, process->wl_queue);
587+
588+ if (!done)
589+ wl_callback_destroy(callback);
590+
591+ return ret;
592+}
593+
594+int do_wl_roundtrip()
595+{
596+ CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
597+ return roundtrip(process);
598+}
599+
600+static void
601+registry_handle_global(void *data, struct wl_registry *registry,
602+ uint32_t name, const char *interface, uint32_t version)
603+{
604+ struct wl_display *wl_display = khrn_platform_get_wl_display();
605+ CLIENT_PROCESS_STATE_T *process = (CLIENT_PROCESS_STATE_T *)data;
606+
607+ if (strcmp(interface, "wl_dispmanx") == 0) {
608+ process->wl_dispmanx = wl_registry_bind(registry, name,
609+ &wl_dispmanx_interface, 1);
610+
611+ wl_proxy_set_queue((struct wl_proxy *) process->wl_dispmanx,
612+ process->wl_queue);
613+ wl_dispmanx_add_listener(process->wl_dispmanx, &dispmanx_listener, wl_display);
614+ roundtrip(process);
615+ }
616+}
617+
618+static void
619+registry_handle_global_remove(void *data, struct wl_registry *registry,
620+ uint32_t name)
621+{
622+}
623+
624+static const struct wl_registry_listener registry_listener = {
625+ registry_handle_global,
626+ registry_handle_global_remove
627+};
628+
629+int
630+init_process_wayland(CLIENT_PROCESS_STATE_T *process)
631+{
632+ struct wl_display *wl_display = khrn_platform_get_wl_display();
633+
634+ process->wl_queue = wl_display_create_queue(wl_display);
635+ if (!process->wl_queue) {
636+ vcos_log_error("wl_display_create_queue failed\n");
637+ return false;
638+ }
639+ wl_display_dispatch_pending(wl_display);
640+
641+ process->wl_registry = wl_display_get_registry(wl_display);
642+ if (!process->wl_registry) {
643+ vcos_log_error("wl_display_get_registry failed\n");
644+ return false;
645+ }
646+
647+ wl_proxy_set_queue((struct wl_proxy *) process->wl_registry,
648+ process->wl_queue);
649+
650+ wl_registry_add_listener(process->wl_registry, &registry_listener, process);
651+
652+ if (roundtrip(process) < 0 || process->wl_dispmanx == NULL) {
653+ vcos_log_error("failed to get wl_dispmanx\n");
654+ return false;
655+ }
656+
657+ return true;
658+}
659+
660+#ifndef ALIGN_UP
661+#define ALIGN_UP(x,y) ((x + (y)-1) & ~((y)-1))
662+#endif
663+
664+static void handle_buffer_release(void *data, struct wl_buffer *buffer_wl)
665+{
666+ struct wl_dispmanx_client_buffer *wl_dispmanx_client_buffer = data;
667+ wl_dispmanx_client_buffer->in_use = 0;
668+}
669+
670+static const struct wl_buffer_listener buffer_listener = {
671+ handle_buffer_release
672+};
673+
674+struct wl_dispmanx_client_buffer *
675+allocate_wl_buffer(struct wl_egl_window *window, KHRN_IMAGE_FORMAT_T color)
676+{
677+ CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
678+ struct wl_dispmanx_client_buffer *wl_dispmanx_client_buffer;
679+ struct wl_buffer *wl_buffer;
680+ uint32_t stride = ALIGN_UP(window->width * 4, 16);
681+ uint32_t buffer_height = ALIGN_UP(window->height, 16);
682+ enum wl_dispmanx_format color_format;
683+ int ret = 0;
684+
685+ switch (color) {
686+ case ABGR_8888:
687+ color_format = WL_DISPMANX_FORMAT_ABGR8888;
688+ break;
689+ case XBGR_8888:
690+ color_format = WL_DISPMANX_FORMAT_XBGR8888;
691+ break;
692+ case RGB_565:
693+ color_format = WL_DISPMANX_FORMAT_RGB565;
694+ break;
695+ default:
696+ vcos_log_error("unknown KHRN_IMAGE_FORMAT_T 0x%x\n", color);
697+ return NULL;
698+ }
699+
700+ wl_buffer = wl_dispmanx_create_buffer(process->wl_dispmanx, window->width,
701+ window->height, stride, buffer_height,
702+ color_format);
703+ if (wl_buffer == NULL)
704+ return NULL;
705+
706+ wl_dispmanx_client_buffer = calloc(1, sizeof(struct wl_dispmanx_client_buffer));
707+ wl_dispmanx_client_buffer->wl_buffer = wl_buffer;
708+ wl_dispmanx_client_buffer->in_use = 0;
709+ wl_dispmanx_client_buffer->pending_allocation = 1;
710+ wl_dispmanx_client_buffer->width = window->width;
711+ wl_dispmanx_client_buffer->height = window->height;
712+
713+ wl_proxy_set_queue((struct wl_proxy *) wl_buffer, process->wl_queue);
714+ wl_buffer_add_listener(wl_buffer, &buffer_listener, wl_dispmanx_client_buffer);
715+
716+ while (ret != -1 && wl_dispmanx_client_buffer->pending_allocation)
717+ ret = do_wl_roundtrip();
718+
719+ return wl_dispmanx_client_buffer;
720+}
Brad Bishop316dfdd2018-06-25 12:45:53 -0400721Index: git/interface/vmcs_host/vc_vchi_dispmanx.h
722===================================================================
723--- git.orig/interface/vmcs_host/vc_vchi_dispmanx.h
724+++ git/interface/vmcs_host/vc_vchi_dispmanx.h
725@@ -66,4 +66,19 @@ typedef struct {
726 #define ELEMENT_CHANGE_MASK_RESOURCE (1<<4)
727 #define ELEMENT_CHANGE_TRANSFORM (1<<5)
728
729+#ifdef BUILD_WAYLAND
730+/* XXX: This should be in a private header that can be included from EGL and vc_* */
731+#include <wayland-server.h>
732+#include "interface/vmcs_host/wayland-dispmanx-server-protocol.h"
733+struct wl_dispmanx_server_buffer {
734+ struct wl_resource *resource;
735+ struct wl_dispmanx *dispmanx;
736+ enum wl_dispmanx_format format;
737+ DISPMANX_RESOURCE_HANDLE_T handle;
738+ int32_t width;
739+ int32_t height;
740+ int in_use;
741+};
742+#endif
743+
744 #endif
745Index: git/interface/khronos/common/linux/khrn_wayland.h
746===================================================================
747--- /dev/null
748+++ git/interface/khronos/common/linux/khrn_wayland.h
749@@ -0,0 +1,33 @@
750+/*
Patrick Williams8b8bc412016-08-17 15:02:23 -0500751+Copyright (c) 2013, Raspberry Pi Foundation
Brad Bishop316dfdd2018-06-25 12:45:53 -0400752+All rights reserved.
753+
754+Redistribution and use in source and binary forms, with or without
755+modification, are permitted provided that the following conditions are met:
756+ * Redistributions of source code must retain the above copyright
757+ notice, this list of conditions and the following disclaimer.
758+ * Redistributions in binary form must reproduce the above copyright
759+ notice, this list of conditions and the following disclaimer in the
760+ documentation and/or other materials provided with the distribution.
761+ * Neither the name of the copyright holder nor the
762+ names of its contributors may be used to endorse or promote products
763+ derived from this software without specific prior written permission.
764+
765+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
766+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
767+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
768+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
769+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
770+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
771+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
772+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
773+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
774+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
775+*/
776+
Patrick Williams8b8bc412016-08-17 15:02:23 -0500777+#include "interface/khronos/common/khrn_client.h"
Brad Bishop316dfdd2018-06-25 12:45:53 -0400778+
Patrick Williams8b8bc412016-08-17 15:02:23 -0500779+int init_process_wayland(CLIENT_PROCESS_STATE_T *process);
780+int do_wl_roundtrip();
Brad Bishop316dfdd2018-06-25 12:45:53 -0400781+
Patrick Williams8b8bc412016-08-17 15:02:23 -0500782+struct wl_dispmanx_client_buffer *allocate_wl_buffer(struct wl_egl_window *window, KHRN_IMAGE_FORMAT_T color);
Brad Bishop316dfdd2018-06-25 12:45:53 -0400783Index: git/interface/khronos/egl/egl_client.c
784===================================================================
785--- git.orig/interface/khronos/egl/egl_client.c
786+++ git/interface/khronos/egl/egl_client.c
Patrick Williams8b8bc412016-08-17 15:02:23 -0500787@@ -153,6 +153,10 @@ by an attribute value"
788 #include <stdlib.h>
789 #include <string.h>
790
791+#ifdef BUILD_WAYLAND
792+#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
793+#include "interface/khronos/common/linux/khrn_wayland.h"
794+#endif
795
796 #include "interface/khronos/egl/egl_client_cr.c"
797
Brad Bishop316dfdd2018-06-25 12:45:53 -0400798@@ -162,17 +166,6 @@ static void egl_current_release(CLIENT_P
Patrick Williams8b8bc412016-08-17 15:02:23 -0500799 void egl_gl_flush_callback(bool wait);
800 void egl_vg_flush_callback(bool wait);
801
802-#include "interface/vmcs_host/vc_dispmanx_types.h"
803-/**HACKHACK - give us the ability to inject a DispmanX
804- * resource handle into the CreateWindowSurface and
805- * SwapBuffers calls */
806-static DISPMANX_RESOURCE_HANDLE_T next_resource_handle;
807-
808-EGLAPI EGLBoolean EGLAPIENTRY eglSetNextResourceHandle(DISPMANX_RESOURCE_HANDLE_T handle)
809-{
810- next_resource_handle = handle;
811-}
812-
813 /*
814 TODO: do an RPC call to make sure the Khronos vll is loaded (and that it stays loaded until eglTerminate)
815 Also affects global image (and possibly others?)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400816@@ -451,6 +444,9 @@ EGLAPI const char EGLAPIENTRY * eglQuery
Patrick Williams8b8bc412016-08-17 15:02:23 -0500817 "EGL_KHR_fence_sync "
818 #endif
Brad Bishop316dfdd2018-06-25 12:45:53 -0400819 #endif
Patrick Williams8b8bc412016-08-17 15:02:23 -0500820+#if EGL_WL_bind_wayland_display
821+ "EGL_WL_bind_wayland_display "
Brad Bishop316dfdd2018-06-25 12:45:53 -0400822+#endif
Patrick Williams8b8bc412016-08-17 15:02:23 -0500823 ;
824 break;
Brad Bishop316dfdd2018-06-25 12:45:53 -0400825 case EGL_VENDOR:
826@@ -655,8 +651,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateW
Patrick Williams8b8bc412016-08-17 15:02:23 -0500827 false,
828 EGL_NO_TEXTURE,
829 EGL_NO_TEXTURE,
830- 0, 0,
831- next_resource_handle);
832+ 0, 0);
833
834 if (surface) {
835 if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
Brad Bishop316dfdd2018-06-25 12:45:53 -0400836@@ -901,7 +896,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateP
Patrick Williams8b8bc412016-08-17 15:02:23 -0500837 mipmap_texture,
838 texture_format,
839 texture_target,
840- 0, 0, 0);
841+ 0, 0);
842
843 if (surface) {
844 if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
Brad Bishop316dfdd2018-06-25 12:45:53 -0400845@@ -1043,7 +1038,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateP
Patrick Williams8b8bc412016-08-17 15:02:23 -0500846 false,
847 EGL_NO_TEXTURE,
848 EGL_NO_TEXTURE,
849- pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle, 0);
850+ pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle);
851
852 if (surface) {
853 if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
Brad Bishop316dfdd2018-06-25 12:45:53 -0400854@@ -2245,6 +2240,9 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuf
Patrick Williams8b8bc412016-08-17 15:02:23 -0500855 CLIENT_THREAD_STATE_T *thread;
856 CLIENT_PROCESS_STATE_T *process;
857 EGLBoolean result;
858+#ifdef BUILD_WAYLAND
859+ struct wl_display *wl_display = khrn_platform_get_wl_display();
860+#endif
861
862 vcos_log_trace("eglSwapBuffers start. dpy=%d. surf=%d.", (int)dpy, (int)surf);
863
Brad Bishop316dfdd2018-06-25 12:45:53 -0400864@@ -2315,18 +2313,58 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuf
Patrick Williams8b8bc412016-08-17 15:02:23 -0500865
866 vcos_log_trace("eglSwapBuffers server call");
867
868- if (next_resource_handle)
869- RPC_CALL7(eglIntSwapBuffers_impl,
870- thread,
871- EGLINTSWAPBUFFERS_ID_V2,
872- RPC_UINT(surface->serverbuffer),
873- RPC_UINT(surface->width),
874- RPC_UINT(surface->height),
875- RPC_UINT(surface->internal_handle),
876- RPC_UINT(surface->swap_behavior == EGL_BUFFER_PRESERVED ? 1 : 0),
877- RPC_UINT(khrn_platform_get_window_position(surface->win)),
878- RPC_INT(next_resource_handle));
879- else
880+#ifdef BUILD_WAYLAND
881+ if (wl_display) {
882+ struct wl_egl_window *wl_egl_window = surface->wl_egl_window;
883+ struct wl_dispmanx_client_buffer *buffer_temp;
884+ uint32_t configid;
885+ KHRN_IMAGE_FORMAT_T color;
886+ int ret = 0;
887+
888+ buffer_temp = surface->front_wl_buffer;
889+ surface->front_wl_buffer = surface->back_wl_buffer;
890+ surface->back_wl_buffer = buffer_temp;
891+
892+ configid = egl_config_to_id(surface->config);
893+ color = egl_config_get_color_format(configid);
894+
895+ if (surface->back_wl_buffer == NULL)
896+ surface->back_wl_buffer = allocate_wl_buffer(wl_egl_window, color);
897+ else if (surface->back_wl_buffer->width != width ||
898+ surface->back_wl_buffer->height != height) {
899+
900+ struct wl_dispmanx_client_buffer *buffer;
901+
902+ wl_buffer_destroy(surface->back_wl_buffer->wl_buffer);
903+ free(surface->back_wl_buffer);
904+
905+ buffer = allocate_wl_buffer(wl_egl_window, color);
906+ surface->back_wl_buffer = buffer;
907+ }
908+
909+ RPC_CALL7(eglIntSwapBuffers_impl,
910+ thread,
911+ EGLINTSWAPBUFFERS_ID_V2,
912+ RPC_UINT(surface->serverbuffer),
913+ RPC_UINT(surface->width),
914+ RPC_UINT(surface->height),
915+ RPC_UINT(surface->internal_handle),
916+ RPC_UINT(surface->swap_behavior == EGL_BUFFER_PRESERVED ? 1 : 0),
917+ RPC_UINT(khrn_platform_get_window_position(surface->win)),
918+ RPC_INT(surface->back_wl_buffer->resource));
919+
920+ surface->front_wl_buffer->in_use = 1;
921+ wl_surface_attach(wl_egl_window->wl_surface,
922+ surface->front_wl_buffer->wl_buffer,
923+ 0, 0);
924+ wl_surface_damage(wl_egl_window->wl_surface, 0, 0,
925+ surface->width, surface->height);
926+ wl_surface_commit(wl_egl_window->wl_surface);
927+
928+ while(ret != -1 && surface->back_wl_buffer->in_use)
929+ ret = wl_display_dispatch_queue(wl_display, process->wl_queue);
930+ } else
931+#endif
932 RPC_CALL6(eglIntSwapBuffers_impl,
933 thread,
934 EGLINTSWAPBUFFERS_ID,
Brad Bishop316dfdd2018-06-25 12:45:53 -0400935Index: git/interface/khronos/egl/egl_client_get_proc.c
936===================================================================
937--- git.orig/interface/khronos/egl/egl_client_get_proc.c
938+++ git/interface/khronos/egl/egl_client_get_proc.c
939@@ -254,6 +254,17 @@ EGLAPI void EGLAPIENTRY (* eglGetProcAdd
Patrick Williams8b8bc412016-08-17 15:02:23 -0500940 return (void(*)(void))eglQueryGlobalImageBRCM;
941 #endif
942
943+#ifdef BUILD_WAYLAND
944+#if EGL_WL_bind_wayland_display
945+ if (!strcmp(procname, "eglBindWaylandDisplayWL"))
946+ return (void(*)(void))eglBindWaylandDisplayWL;
947+ if (!strcmp(procname, "eglUnbindWaylandDisplayWL"))
948+ return (void(*)(void))eglUnbindWaylandDisplayWL;
949+ if (!strcmp(procname, "eglQueryWaylandBufferWL"))
950+ return (void(*)(void))eglQueryWaylandBufferWL;
951+#endif
952+#endif
953+
954 return (void(*)(void)) NULL;
955 }
956
Brad Bishop316dfdd2018-06-25 12:45:53 -0400957Index: git/interface/khronos/egl/egl_client_surface.c
958===================================================================
959--- git.orig/interface/khronos/egl/egl_client_surface.c
960+++ git/interface/khronos/egl/egl_client_surface.c
961@@ -46,6 +46,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
Patrick Williams8b8bc412016-08-17 15:02:23 -0500962 #include "interface/khronos/egl/egl_int_impl.h"
963 #endif
964
965+#ifdef BUILD_WAYLAND
966+#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
967+#include "interface/khronos/common/linux/khrn_wayland.h"
968+#endif
969+
970 #include <stdlib.h>
971
972
973@@ -314,8 +319,7 @@ EGL_SURFACE_T *egl_surface_create(
974 EGLenum texture_format,
975 EGLenum texture_target,
976 EGLNativePixmapType pixmap,
977- const uint32_t *pixmap_server_handle,
978- DISPMANX_RESOURCE_HANDLE_T next_resource_handle)
979+ const uint32_t *pixmap_server_handle)
980 {
981 KHRN_IMAGE_FORMAT_T color;
982 KHRN_IMAGE_FORMAT_T depth;
983@@ -326,6 +330,10 @@ EGL_SURFACE_T *egl_surface_create(
984 EGLint config_depth_bits;
985 EGLint config_stencil_bits;
986 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
987+#ifdef BUILD_WAYLAND
988+ struct wl_display *wl_display = khrn_platform_get_wl_display();
989+ DISPMANX_RESOURCE_HANDLE_T resource;
990+#endif
991
992 EGL_SURFACE_T *surface = egl_surface_pool_alloc();
993
994@@ -390,6 +398,18 @@ EGL_SURFACE_T *egl_surface_create(
995
996 vcos_assert(color != IMAGE_FORMAT_INVALID);
997
998+#ifdef BUILD_WAYLAND
999+ if (type == WINDOW && wl_display) {
1000+ surface->wl_egl_window = (struct wl_egl_window*)win;
1001+ surface->back_wl_buffer = allocate_wl_buffer(
1002+ surface->wl_egl_window, color);
1003+ resource = surface->back_wl_buffer->resource;
1004+ } else {
1005+ surface->wl_egl_window = NULL;
1006+ resource = DISPMANX_NO_HANDLE;
1007+ }
1008+#endif
1009+
1010 #ifdef KHRONOS_EGL_PLATFORM_OPENWFC
1011 // Create stream for this window
1012 if(type != PBUFFER)
1013@@ -474,7 +494,8 @@ EGL_SURFACE_T *egl_surface_create(
1014 #endif
1015 uint32_t results[3];
1016
1017- if (next_resource_handle)
1018+#ifdef BUILD_WAYLAND
1019+ if (resource != DISPMANX_NO_HANDLE)
1020 RPC_CALL16_OUT_CTRL(eglIntCreateSurface_impl,
1021 thread,
1022 EGLINTCREATESURFACE_ID_V2,
1023@@ -492,9 +513,10 @@ EGL_SURFACE_T *egl_surface_create(
1024 RPC_UINT(config_stencil_bits),
1025 RPC_UINT(sem_name),
1026 RPC_UINT(type),
1027- RPC_INT(next_resource_handle),
1028+ RPC_INT(resource),
1029 results);
1030 else
1031+#endif
1032 RPC_CALL15_OUT_CTRL(eglIntCreateSurface_impl,
1033 thread,
1034 EGLINTCREATESURFACE_ID,
Brad Bishop316dfdd2018-06-25 12:45:53 -04001035@@ -663,6 +685,18 @@ void egl_surface_free(EGL_SURFACE_T *sur
Patrick Williams8b8bc412016-08-17 15:02:23 -05001036 if( surface->type == WINDOW ) {
1037 vcos_log_trace("egl_surface_free: calling platform_destroy_winhandle...");
1038 platform_destroy_winhandle( surface->win, surface->internal_handle );
1039+
1040+#ifdef BUILD_WAYLAND
1041+ if (surface->back_wl_buffer) {
1042+ wl_buffer_destroy(surface->back_wl_buffer->wl_buffer);
1043+ free(surface->back_wl_buffer);
1044+ }
1045+
1046+ if (surface->front_wl_buffer) {
1047+ wl_buffer_destroy(surface->front_wl_buffer->wl_buffer);
1048+ free(surface->front_wl_buffer);
1049+ }
1050+#endif
1051 }
1052 /* return value ignored -- read performed to ensure blocking. we want this to
1053 * block so clients can safely destroy the surface's window as soon as the
Brad Bishop316dfdd2018-06-25 12:45:53 -04001054Index: git/interface/khronos/egl/egl_client_surface.h
1055===================================================================
1056--- git.orig/interface/khronos/egl/egl_client_surface.h
1057+++ git/interface/khronos/egl/egl_client_surface.h
Patrick Williams8b8bc412016-08-17 15:02:23 -05001058@@ -288,6 +288,41 @@ typedef struct {
1059 type == PIXMAP
1060 */
1061 bool server_owned;
1062+
1063+#ifdef BUILD_WAYLAND
1064+ /*
1065+ wl_egl_window
1066+
1067+ Validity:
1068+ type == WINDOW
1069+
1070+ Invariant:
1071+ wayland EGL window
1072+ */
1073+ struct wl_egl_window *wl_egl_window;
1074+
1075+ /*
1076+ front_wl_buffer
1077+
1078+ Validity:
1079+ type == WINDOW
1080+
1081+ Invariant:
1082+ client-side information about the wl_buffer in the front
1083+ */
1084+ struct wl_dispmanx_client_buffer *front_wl_buffer;
1085+
1086+ /*
1087+ back_wl_buffer
1088+
1089+ Validity:
1090+ type == WINDOW
1091+
1092+ Invariant:
1093+ client-side information about the wl_buffer in the back
1094+ */
1095+ struct wl_dispmanx_client_buffer *back_wl_buffer;
1096+#endif
1097 } EGL_SURFACE_T;
1098
1099 extern bool egl_surface_check_attribs(
Brad Bishop316dfdd2018-06-25 12:45:53 -04001100@@ -322,8 +357,7 @@ extern EGL_SURFACE_T *egl_surface_create
Patrick Williams8b8bc412016-08-17 15:02:23 -05001101 EGLenum texture_format,
1102 EGLenum texture_target,
1103 EGLNativePixmapType pixmap,
1104- const uint32_t *pixmap_server_handle,
1105- DISPMANX_RESOURCE_HANDLE_T next_resource_handle);
1106+ const uint32_t *pixmap_server_handle);
1107 extern EGL_SURFACE_T *egl_surface_from_vg_image(
1108 VGImage vg_handle,
1109 EGLSurface name,
Brad Bishop316dfdd2018-06-25 12:45:53 -04001110Index: git/interface/khronos/egl/egl_int_impl.h
1111===================================================================
1112--- git.orig/interface/khronos/egl/egl_int_impl.h
1113+++ git/interface/khronos/egl/egl_int_impl.h
Patrick Williams8b8bc412016-08-17 15:02:23 -05001114@@ -57,7 +57,7 @@ FN(int, eglIntCreateSurface_impl, (
1115 uint32_t sem,
1116 uint32_t type,
1117 uint32_t *results,
1118- DISPMANX_RESOURCE_HANDLE_T next_resource_handle))
1119+ DISPMANX_RESOURCE_HANDLE_T resource_handle))
1120
1121 FN(int, eglIntCreatePbufferFromVGImage_impl, (
1122 VGImage vg_handle,
Brad Bishop316dfdd2018-06-25 12:45:53 -04001123Index: git/interface/khronos/ext/egl_wayland.c
1124===================================================================
Patrick Williams8b8bc412016-08-17 15:02:23 -05001125--- /dev/null
Brad Bishop316dfdd2018-06-25 12:45:53 -04001126+++ git/interface/khronos/ext/egl_wayland.c
Patrick Williams8b8bc412016-08-17 15:02:23 -05001127@@ -0,0 +1,246 @@
1128+/*
1129+Copyright (c) 2013, Raspberry Pi Foundation
1130+All rights reserved.
1131+
1132+Redistribution and use in source and binary forms, with or without
1133+modification, are permitted provided that the following conditions are met:
1134+ * Redistributions of source code must retain the above copyright
1135+ notice, this list of conditions and the following disclaimer.
1136+ * Redistributions in binary form must reproduce the above copyright
1137+ notice, this list of conditions and the following disclaimer in the
1138+ documentation and/or other materials provided with the distribution.
1139+ * Neither the name of the copyright holder nor the
1140+ names of its contributors may be used to endorse or promote products
1141+ derived from this software without specific prior written permission.
1142+
1143+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1144+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1145+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1146+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
1147+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1148+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1149+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1150+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1151+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1152+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1153+*/
1154+
1155+#include "interface/khronos/common/khrn_client_mangle.h"
1156+#include "interface/khronos/common/khrn_client_rpc.h"
1157+
1158+#include "interface/khronos/ext/egl_khr_sync_client.h"
1159+#include "interface/khronos/include/EGL/egl.h"
1160+#include "interface/khronos/include/EGL/eglext.h"
1161+
1162+#include "interface/vmcs_host/vc_vchi_dispmanx.h"
1163+
1164+#include <wayland-server.h>
1165+#include "interface/khronos/wayland-dispmanx-server-protocol.h"
1166+
1167+static void
1168+destroy_buffer(struct wl_resource *resource)
1169+{
1170+ struct wl_dispmanx_server_buffer *buffer = wl_resource_get_user_data(resource);
1171+
1172+ if(!buffer->in_use)
1173+ vc_dispmanx_resource_delete(buffer->handle);
1174+
1175+ free(buffer);
1176+}
1177+
1178+static void
1179+buffer_destroy(struct wl_client *client, struct wl_resource *resource)
1180+{
1181+ wl_resource_destroy(resource);
1182+}
1183+
1184+static const struct wl_buffer_interface dispmanx_buffer_interface = {
1185+ buffer_destroy
1186+};
1187+
1188+static VC_IMAGE_TYPE_T
1189+get_vc_format(enum wl_dispmanx_format format)
1190+{
1191+ /* XXX: The app is likely to have been premultiplying in its shaders,
1192+ * but the VC scanout hardware on the RPi cannot mix premultiplied alpha
1193+ * channel with the element's alpha.
1194+ */
1195+ switch (format) {
1196+ case WL_DISPMANX_FORMAT_ABGR8888:
1197+ return VC_IMAGE_RGBA32;
1198+ case WL_DISPMANX_FORMAT_XBGR8888:
1199+ return VC_IMAGE_BGRX8888;
1200+ case WL_DISPMANX_FORMAT_RGB565:
1201+ return VC_IMAGE_RGB565;
1202+ default:
1203+ /* invalid format */
1204+ return VC_IMAGE_MIN;
1205+ }
1206+}
1207+
1208+static void
1209+dispmanx_create_buffer(struct wl_client *client, struct wl_resource *resource,
1210+ uint32_t id, int32_t width, int32_t height,
1211+ uint32_t stride, uint32_t buffer_height, uint32_t format)
1212+{
1213+ struct wl_dispmanx_server_buffer *buffer;
1214+ VC_IMAGE_TYPE_T vc_format = get_vc_format(format);
1215+ uint32_t dummy;
1216+
1217+ if(vc_format == VC_IMAGE_MIN) {
1218+ wl_resource_post_error(resource,
1219+ WL_DISPMANX_ERROR_INVALID_FORMAT,
1220+ "invalid format");
1221+ return;
1222+ }
1223+
1224+ buffer = calloc(1, sizeof *buffer);
1225+ if (buffer == NULL) {
1226+ wl_resource_post_no_memory(resource);
1227+ return;
1228+ }
1229+
1230+ buffer->handle = vc_dispmanx_resource_create(vc_format,
1231+ width | (stride << 16),
1232+ height | (buffer_height << 16),
1233+ &dummy);
1234+ if(buffer->handle == DISPMANX_NO_HANDLE) {
1235+ wl_resource_post_error(resource,
1236+ WL_DISPMANX_ERROR_ALLOC_FAILED,
1237+ "allocation failed");
1238+ free(buffer);
1239+ return;
1240+ }
1241+
1242+ buffer->width = width;
1243+ buffer->height = height;
1244+ buffer->format = format;
1245+
1246+ buffer->resource = wl_resource_create(resource->client, &wl_buffer_interface,
1247+ 1, id);
1248+ if (!buffer->resource) {
1249+ wl_resource_post_no_memory(resource);
1250+ vc_dispmanx_resource_delete(buffer->handle);
1251+ free(buffer);
1252+ return;
1253+ }
1254+
1255+ wl_resource_set_implementation(buffer->resource,
1256+ (void (**)(void)) &dispmanx_buffer_interface,
1257+ buffer, destroy_buffer);
1258+
1259+ wl_dispmanx_send_buffer_allocated(resource, buffer->resource,
1260+ buffer->handle);
1261+}
1262+
1263+static const struct wl_dispmanx_interface dispmanx_interface = {
1264+ dispmanx_create_buffer,
1265+};
1266+
1267+static void
1268+bind_dispmanx(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1269+{
1270+ struct wl_resource *resource;
1271+
1272+ resource = wl_resource_create(client, &wl_dispmanx_interface, 1, id);
1273+ wl_resource_set_implementation(resource, &dispmanx_interface, NULL, NULL);
1274+
1275+ wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
1276+ WL_DISPMANX_FORMAT_ARGB8888);
1277+
1278+ wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
1279+ WL_DISPMANX_FORMAT_XRGB8888);
1280+
1281+ wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
1282+ WL_DISPMANX_FORMAT_ABGR8888);
1283+
1284+ wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
1285+ WL_DISPMANX_FORMAT_XBGR8888);
1286+
1287+ wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
1288+ WL_DISPMANX_FORMAT_RGB565);
1289+}
1290+
1291+EGLBoolean EGLAPIENTRY
1292+eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1293+{
1294+ CLIENT_THREAD_STATE_T *thread;
1295+ CLIENT_PROCESS_STATE_T *process;
1296+
1297+ if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
1298+ return EGL_FALSE;
1299+
1300+ if (process->wl_global != NULL)
1301+ goto error;
1302+
1303+ process->wl_global = wl_global_create(display, &wl_dispmanx_interface, 1,
1304+ NULL, bind_dispmanx);
1305+ if (process->wl_global == NULL)
1306+ goto error;
1307+
1308+ return EGL_TRUE;
1309+
1310+error:
1311+ CLIENT_UNLOCK();
1312+ return EGL_FALSE;
1313+}
1314+
1315+EGLBoolean EGLAPIENTRY
1316+eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1317+{
1318+ CLIENT_THREAD_STATE_T *thread;
1319+ CLIENT_PROCESS_STATE_T *process;
1320+
1321+ if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
1322+ return EGL_FALSE;
1323+
1324+ wl_global_destroy(process->wl_global);
1325+ process->wl_global = NULL;
1326+
1327+ CLIENT_UNLOCK();
1328+
1329+ return EGL_TRUE;
1330+}
1331+
1332+static int
1333+get_egl_format(enum wl_dispmanx_format format)
1334+{
1335+ switch (format) {
1336+ case WL_DISPMANX_FORMAT_ABGR8888:
1337+ return EGL_TEXTURE_RGBA;
1338+ case WL_DISPMANX_FORMAT_XBGR8888:
1339+ return EGL_TEXTURE_RGB;
1340+ case WL_DISPMANX_FORMAT_RGB565:
1341+ return EGL_TEXTURE_RGB;
1342+ default:
1343+ /* invalid format */
1344+ return EGL_NO_TEXTURE;
1345+ }
1346+}
1347+
1348+EGLBoolean EGLAPIENTRY
1349+eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *_buffer,
1350+ EGLint attribute, EGLint *value)
1351+{
1352+ struct wl_dispmanx_server_buffer *buffer = wl_resource_get_user_data(_buffer);
1353+
1354+ if (wl_resource_instance_of(_buffer, &wl_dispmanx_interface,
1355+ &dispmanx_buffer_interface))
1356+ return EGL_FALSE;
1357+
1358+ switch (attribute) {
1359+ case EGL_TEXTURE_FORMAT:
1360+ *value = get_egl_format(buffer->format);
1361+ if (*value == EGL_NO_TEXTURE)
1362+ return EGL_FALSE;
1363+ return EGL_TRUE;
1364+ case EGL_WIDTH:
1365+ *value = buffer->width;
1366+ return EGL_TRUE;
1367+ case EGL_HEIGHT:
1368+ *value = buffer->height;
1369+ return EGL_TRUE;
1370+ }
1371+
1372+ return EGL_FALSE;
1373+}
Brad Bishop316dfdd2018-06-25 12:45:53 -04001374Index: git/interface/khronos/include/EGL/eglext.h
1375===================================================================
1376--- git.orig/interface/khronos/include/EGL/eglext.h
1377+++ git/interface/khronos/include/EGL/eglext.h
1378@@ -191,6 +191,29 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLG
Patrick Williams8b8bc412016-08-17 15:02:23 -05001379 #endif
1380
1381
1382+#ifndef EGL_WL_bind_wayland_display
1383+#define EGL_WL_bind_wayland_display 1
1384+
1385+#define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */
1386+#define EGL_WAYLAND_PLANE_WL 0x31D6 /* eglCreateImageKHR target */
1387+#define EGL_TEXTURE_Y_U_V_WL 0x31D7
1388+#define EGL_TEXTURE_Y_UV_WL 0x31D8
1389+#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
1390+
1391+struct wl_display;
1392+struct wl_resource;
1393+#ifdef EGL_EGLEXT_PROTOTYPES
1394+EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
1395+EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
1396+EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
1397+#endif
1398+typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
1399+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
1400+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
1401+
1402+#endif
1403+
1404+
1405 #ifdef __cplusplus
1406 }
1407 #endif
Brad Bishop316dfdd2018-06-25 12:45:53 -04001408Index: git/interface/khronos/wayland-egl/wayland-egl-priv.h
1409===================================================================
Patrick Williams8b8bc412016-08-17 15:02:23 -05001410--- /dev/null
Brad Bishop316dfdd2018-06-25 12:45:53 -04001411+++ git/interface/khronos/wayland-egl/wayland-egl-priv.h
Patrick Williams8b8bc412016-08-17 15:02:23 -05001412@@ -0,0 +1,53 @@
1413+/* Copied from Mesa */
1414+
1415+#ifndef _WAYLAND_EGL_PRIV_H
1416+#define _WAYLAND_EGL_PRIV_H
1417+
1418+#ifdef __cplusplus
1419+extern "C" {
1420+#endif
1421+
1422+/* GCC visibility */
1423+#if defined(__GNUC__) && __GNUC__ >= 4
1424+#define WL_EGL_EXPORT __attribute__ ((visibility("default")))
1425+#else
1426+#define WL_EGL_EXPORT
1427+#endif
1428+
1429+#include "interface/vmcs_host/vc_dispmanx.h"
1430+#include "interface/khronos/egl/egl_client_surface.h"
1431+
1432+#include <wayland-client.h>
1433+
1434+struct wl_dispmanx_client_buffer {
1435+ struct wl_buffer *wl_buffer;
1436+ DISPMANX_RESOURCE_HANDLE_T resource;
1437+
1438+ int pending_allocation;
1439+ int in_use;
1440+ int width;
1441+ int height;
1442+};
1443+
1444+struct wl_egl_window {
1445+ struct wl_surface *wl_surface;
1446+
1447+ int width;
1448+ int height;
1449+ int dx;
1450+ int dy;
1451+
1452+ int attached_width;
1453+ int attached_height;
1454+
1455+ /* XXX: The VC side seems to expect a valid element handle to be
1456+ passed to eglIntCreateSurface_impl and/or eglIntSwapBuffers_impl,
1457+ even for host-managed surfaces. */
1458+ DISPMANX_ELEMENT_HANDLE_T dummy_element;
1459+};
1460+
1461+#ifdef __cplusplus
1462+}
1463+#endif
1464+
1465+#endif
Brad Bishop316dfdd2018-06-25 12:45:53 -04001466Index: git/interface/khronos/wayland-egl/wayland-egl.c
1467===================================================================
Patrick Williams8b8bc412016-08-17 15:02:23 -05001468--- /dev/null
Brad Bishop316dfdd2018-06-25 12:45:53 -04001469+++ git/interface/khronos/wayland-egl/wayland-egl.c
Patrick Williams8b8bc412016-08-17 15:02:23 -05001470@@ -0,0 +1,59 @@
1471+/* Copied from Mesa */
1472+
1473+#include <stdlib.h>
1474+
1475+#include <wayland-client.h>
1476+#include <wayland-egl.h>
1477+#include "wayland-egl-priv.h"
1478+
1479+WL_EGL_EXPORT void
1480+wl_egl_window_resize(struct wl_egl_window *egl_window,
1481+ int width, int height,
1482+ int dx, int dy)
1483+{
1484+ if (egl_window->width == width &&
1485+ egl_window->height == height &&
1486+ egl_window->dx == dx &&
1487+ egl_window->dy == dy)
1488+ return;
1489+
1490+ egl_window->width = width;
1491+ egl_window->height = height;
1492+ egl_window->dx = dx;
1493+ egl_window->dy = dy;
1494+}
1495+
1496+WL_EGL_EXPORT struct wl_egl_window *
1497+wl_egl_window_create(struct wl_surface *surface,
1498+ int width, int height)
1499+{
1500+ struct wl_egl_window *egl_window;
1501+
1502+ egl_window = calloc(1, sizeof *egl_window);
1503+ if (!egl_window)
1504+ return NULL;
1505+
1506+ egl_window->wl_surface = surface;
1507+ wl_egl_window_resize(egl_window, width, height, 0, 0);
1508+ egl_window->attached_width = 0;
1509+ egl_window->attached_height = 0;
1510+ egl_window->dummy_element = PLATFORM_WIN_NONE;
1511+
1512+ return egl_window;
1513+}
1514+
1515+WL_EGL_EXPORT void
1516+wl_egl_window_destroy(struct wl_egl_window *egl_window)
1517+{
1518+ free(egl_window);
1519+}
1520+
1521+WL_EGL_EXPORT void
1522+wl_egl_window_get_attached_size(struct wl_egl_window *egl_window,
1523+ int *width, int *height)
1524+{
1525+ if (width)
1526+ *width = egl_window->attached_width;
1527+ if (height)
1528+ *height = egl_window->attached_height;
1529+}
Brad Bishop316dfdd2018-06-25 12:45:53 -04001530Index: git/interface/khronos/wayland-egl/wayland-egl.pc.in
1531===================================================================
Patrick Williams8b8bc412016-08-17 15:02:23 -05001532--- /dev/null
Brad Bishop316dfdd2018-06-25 12:45:53 -04001533+++ git/interface/khronos/wayland-egl/wayland-egl.pc.in
Patrick Williams8b8bc412016-08-17 15:02:23 -05001534@@ -0,0 +1,10 @@
1535+prefix=@CMAKE_INSTALL_PREFIX@
1536+exec_prefix=${prefix}
1537+libdir=${exec_prefix}/lib
1538+includedir=${prefix}/include
1539+
1540+Name: wayland-egl
1541+Description: VideoCore wayland-egl library
1542+Version: @PROJECT_APIVER@
1543+Libs: -L${libdir} -lwayland-egl
1544+Cflags: -I${includedir}
Brad Bishop316dfdd2018-06-25 12:45:53 -04001545Index: git/interface/vmcs_host/CMakeLists.txt
1546===================================================================
1547--- git.orig/interface/vmcs_host/CMakeLists.txt
1548+++ git/interface/vmcs_host/CMakeLists.txt
Patrick Williams8b8bc412016-08-17 15:02:23 -05001549@@ -9,13 +9,24 @@ add_definitions(-fno-strict-aliasing)
1550
1551 include_directories(${VMCS_TARGET}/vcfiled)
1552
1553-add_library(vchostif
1554- ${VMCS_TARGET}/vcfilesys.c ${VMCS_TARGET}/vcmisc.c
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001555- vc_vchi_gencmd.c vc_vchi_filesys.c vc_vchi_gpuserv.c
Patrick Williams8b8bc412016-08-17 15:02:23 -05001556- vc_vchi_tvservice.c vc_vchi_cecservice.c
1557- vc_vchi_dispmanx.c vc_service_common.c)
1558+set(VCHOSTIF_SOURCE
1559+ ${VMCS_TARGET}/vcfilesys.c ${VMCS_TARGET}/vcmisc.c
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001560+ vc_vchi_gencmd.c vc_vchi_filesys.c vc_vchi_gpuserv.c
Patrick Williams8b8bc412016-08-17 15:02:23 -05001561+ vc_vchi_tvservice.c vc_vchi_cecservice.c
1562+ vc_vchi_dispmanx.c vc_service_common.c)
1563 # ${VMCS_TARGET}/vmcs_main.c
1564 # vc_vchi_haud.c
1565+
1566+if (BUILD_WAYLAND)
1567+wayland_add_protocol_server(
1568+ VCHOSTIF_SOURCE
1569+ ../../interface/wayland/dispmanx.xml
1570+ dispmanx
1571+)
1572+endif ()
1573+
1574+add_library(vchostif ${VCHOSTIF_SOURCE})
1575+
1576 #add_library(bufman vc_vchi_bufman.c )
1577
1578 # OpenMAX/IL component service
Brad Bishop316dfdd2018-06-25 12:45:53 -04001579Index: git/interface/vmcs_host/vc_dispmanx.h
1580===================================================================
1581--- git.orig/interface/vmcs_host/vc_dispmanx.h
1582+++ git/interface/vmcs_host/vc_dispmanx.h
1583@@ -39,6 +39,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
Patrick Williams8b8bc412016-08-17 15:02:23 -05001584 #ifdef __cplusplus
1585 extern "C" {
1586 #endif
1587+
1588+#ifdef BUILD_WAYLAND
1589+struct wl_resource;
1590+#endif
1591+
1592 // Same function as above, to aid migration of code.
1593 VCHPRE_ int VCHPOST_ vc_dispman_init( void );
1594 // Stop the service from being used
Brad Bishop316dfdd2018-06-25 12:45:53 -04001595@@ -135,6 +140,11 @@ VCHPRE_ int VCHPOST_ vc_dispmanx_resourc
Patrick Williams8b8bc412016-08-17 15:02:23 -05001596 // Start triggering callbacks synced to vsync
1597 VCHPRE_ int VCHPOST_ vc_dispmanx_vsync_callback( DISPMANX_DISPLAY_HANDLE_T display, DISPMANX_CALLBACK_FUNC_T cb_func, void *cb_arg );
1598
1599+#ifdef BUILD_WAYLAND
1600+VCHPRE_ DISPMANX_RESOURCE_HANDLE_T VCHPOST_ vc_dispmanx_get_handle_from_wl_buffer( struct wl_resource *_buffer );
1601+
1602+VCHPRE_ void VCHPOST_ vc_dispmanx_set_wl_buffer_in_use( struct wl_resource *_buffer, int in_use );
1603+#endif
1604 #ifdef __cplusplus
1605 }
1606 #endif
Brad Bishop316dfdd2018-06-25 12:45:53 -04001607Index: git/interface/vmcs_host/vc_vchi_dispmanx.c
1608===================================================================
1609--- git.orig/interface/vmcs_host/vc_vchi_dispmanx.c
1610+++ git/interface/vmcs_host/vc_vchi_dispmanx.c
1611@@ -1319,3 +1319,45 @@ static void *dispmanx_notify_func( void
Patrick Williams8b8bc412016-08-17 15:02:23 -05001612 }
1613 return 0;
1614 }
1615+
1616+
1617+#ifdef BUILD_WAYLAND
1618+/***********************************************************
1619+ * Name: vc_dispmanx_get_handle_from_wl_buffer
1620+ *
1621+ * Arguments:
1622+ * struct wl_resource *_buffer
1623+ *
1624+ * Description: Return the handle of the resource associated to this Wayland buffer
1625+ *
1626+ * Returns: A resource handle
1627+ *
1628+ ***********************************************************/
1629+VCHPRE_ DISPMANX_RESOURCE_HANDLE_T VCHPOST_ vc_dispmanx_get_handle_from_wl_buffer( struct wl_resource *_buffer )
1630+{
1631+ struct wl_dispmanx_server_buffer *buffer = (struct wl_dispmanx_server_buffer*)_buffer->data;
1632+ if (!buffer)
1633+ return DISPMANX_NO_HANDLE;
1634+
1635+ return buffer->handle;
1636+}
1637+
1638+/***********************************************************
1639+ * Name: vc_dispmanx_set_wl_buffer_in_use
1640+ *
1641+ * Arguments:
1642+ * struct wl_resource *_buffer
1643+ * int in_use
1644+ *
1645+ * Description: Mark this Wayland buffer as being in use by the compositor
1646+ *
1647+ ***********************************************************/
1648+VCHPRE_ void VCHPOST_ vc_dispmanx_set_wl_buffer_in_use( struct wl_resource *_buffer, int in_use )
1649+{
1650+ struct wl_dispmanx_server_buffer *buffer = (struct wl_dispmanx_server_buffer*)_buffer->data;
1651+ if (!buffer)
1652+ return;
1653+
1654+ buffer->in_use = in_use;
1655+}
1656+#endif
Brad Bishop316dfdd2018-06-25 12:45:53 -04001657Index: git/interface/wayland/dispmanx.xml
1658===================================================================
Patrick Williams8b8bc412016-08-17 15:02:23 -05001659--- /dev/null
Brad Bishop316dfdd2018-06-25 12:45:53 -04001660+++ git/interface/wayland/dispmanx.xml
Patrick Williams8b8bc412016-08-17 15:02:23 -05001661@@ -0,0 +1,123 @@
1662+<?xml version="1.0" encoding="UTF-8"?>
1663+<protocol name="dispmanx">
1664+
1665+ <copyright>
1666+ Copyright © 2008-2011 Kristian Høgsberg
1667+ Copyright © 2010-2011 Intel Corporation
1668+ Copyright © 2013 Raspberry Pi Foundation
1669+
1670+ Permission to use, copy, modify, distribute, and sell this
1671+ software and its documentation for any purpose is hereby granted
1672+ without fee, provided that\n the above copyright notice appear in
1673+ all copies and that both that copyright notice and this permission
1674+ notice appear in supporting documentation, and that the name of
1675+ the copyright holders not be used in advertising or publicity
1676+ pertaining to distribution of the software without specific,
1677+ written prior permission. The copyright holders make no
1678+ representations about the suitability of this software for any
1679+ purpose. It is provided "as is" without express or implied
1680+ warranty.
1681+
1682+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
1683+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
1684+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
1685+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1686+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
1687+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1688+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
1689+ THIS SOFTWARE.
1690+ </copyright>
1691+
1692+ <!-- DispManX support. This object is created by the server and published
1693+ using the display's global event. -->
1694+ <interface name="wl_dispmanx" version="1">
1695+ <enum name="error">
1696+ <entry name="alloc_failed" value="0"/>
1697+ <entry name="invalid_format" value="1"/>
1698+ </enum>
1699+
1700+ <enum name="format">
1701+ <!-- The pixel format codes match the #defines in drm_fourcc.h.
1702+ The formats actually supported by the compositor will be
1703+ reported by the format event. -->
1704+ <entry name="c8" value="0x20203843"/>
1705+ <entry name="rgb332" value="0x38424752"/>
1706+ <entry name="bgr233" value="0x38524742"/>
1707+ <entry name="xrgb4444" value="0x32315258"/>
1708+ <entry name="xbgr4444" value="0x32314258"/>
1709+ <entry name="rgbx4444" value="0x32315852"/>
1710+ <entry name="bgrx4444" value="0x32315842"/>
1711+ <entry name="argb4444" value="0x32315241"/>
1712+ <entry name="abgr4444" value="0x32314241"/>
1713+ <entry name="rgba4444" value="0x32314152"/>
1714+ <entry name="bgra4444" value="0x32314142"/>
1715+ <entry name="xrgb1555" value="0x35315258"/>
1716+ <entry name="xbgr1555" value="0x35314258"/>
1717+ <entry name="rgbx5551" value="0x35315852"/>
1718+ <entry name="bgrx5551" value="0x35315842"/>
1719+ <entry name="argb1555" value="0x35315241"/>
1720+ <entry name="abgr1555" value="0x35314241"/>
1721+ <entry name="rgba5551" value="0x35314152"/>
1722+ <entry name="bgra5551" value="0x35314142"/>
1723+ <entry name="rgb565" value="0x36314752"/>
1724+ <entry name="bgr565" value="0x36314742"/>
1725+ <entry name="rgb888" value="0x34324752"/>
1726+ <entry name="bgr888" value="0x34324742"/>
1727+ <entry name="xrgb8888" value="0x34325258"/>
1728+ <entry name="xbgr8888" value="0x34324258"/>
1729+ <entry name="rgbx8888" value="0x34325852"/>
1730+ <entry name="bgrx8888" value="0x34325842"/>
1731+ <entry name="argb8888" value="0x34325241"/>
1732+ <entry name="abgr8888" value="0x34324241"/>
1733+ <entry name="rgba8888" value="0x34324152"/>
1734+ <entry name="bgra8888" value="0x34324142"/>
1735+ <entry name="xrgb2101010" value="0x30335258"/>
1736+ <entry name="xbgr2101010" value="0x30334258"/>
1737+ <entry name="rgbx1010102" value="0x30335852"/>
1738+ <entry name="bgrx1010102" value="0x30335842"/>
1739+ <entry name="argb2101010" value="0x30335241"/>
1740+ <entry name="abgr2101010" value="0x30334241"/>
1741+ <entry name="rgba1010102" value="0x30334152"/>
1742+ <entry name="bgra1010102" value="0x30334142"/>
1743+ <entry name="yuyv" value="0x56595559"/>
1744+ <entry name="yvyu" value="0x55595659"/>
1745+ <entry name="uyvy" value="0x59565955"/>
1746+ <entry name="vyuy" value="0x59555956"/>
1747+ <entry name="ayuv" value="0x56555941"/>
1748+ <entry name="nv12" value="0x3231564e"/>
1749+ <entry name="nv21" value="0x3132564e"/>
1750+ <entry name="nv16" value="0x3631564e"/>
1751+ <entry name="nv61" value="0x3136564e"/>
1752+ <entry name="yuv410" value="0x39565559"/>
1753+ <entry name="yvu410" value="0x39555659"/>
1754+ <entry name="yuv411" value="0x31315559"/>
1755+ <entry name="yvu411" value="0x31315659"/>
1756+ <entry name="yuv420" value="0x32315559"/>
1757+ <entry name="yvu420" value="0x32315659"/>
1758+ <entry name="yuv422" value="0x36315559"/>
1759+ <entry name="yvu422" value="0x36315659"/>
1760+ <entry name="yuv444" value="0x34325559"/>
1761+ <entry name="yvu444" value="0x34325659"/>
1762+ </enum>
1763+
1764+ <event name="format">
1765+ <arg name="format" type="uint"/>
1766+ </event>
1767+
1768+ <!-- Create a wayland buffer for the DispManX resource. -->
1769+ <request name="create_buffer">
1770+ <arg name="id" type="new_id" interface="wl_buffer"/>
1771+ <arg name="width" type="int"/>
1772+ <arg name="height" type="int"/>
1773+ <arg name="stride" type="uint"/>
1774+ <arg name="buffer_height" type="uint"/>
1775+ <arg name="format" type="uint"/>
1776+ </request>
1777+
1778+ <event name="buffer_allocated">
1779+ <arg name="buffer" type="object" interface="wl_buffer"/>
1780+ <arg name="handle" type="uint"/>
1781+ </event>
1782+ </interface>
1783+
1784+</protocol>
Brad Bishop316dfdd2018-06-25 12:45:53 -04001785Index: git/makefiles/cmake/Wayland.cmake
1786===================================================================
Patrick Williams8b8bc412016-08-17 15:02:23 -05001787--- /dev/null
Brad Bishop316dfdd2018-06-25 12:45:53 -04001788+++ git/makefiles/cmake/Wayland.cmake
Patrick Williams8b8bc412016-08-17 15:02:23 -05001789@@ -0,0 +1,72 @@
1790+#=============================================================================
1791+# Copyright (C) 2012-2013 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
1792+# All rights reserved.
1793+#
1794+# Redistribution and use in source and binary forms, with or without
1795+# modification, are permitted provided that the following conditions
1796+# are met:
1797+#
1798+# * Redistributions of source code must retain the above copyright
1799+# notice, this list of conditions and the following disclaimer.
1800+#
1801+# * Redistributions in binary form must reproduce the above copyright
1802+# notice, this list of conditions and the following disclaimer in the
1803+# documentation and/or other materials provided with the distribution.
1804+#
1805+# * Neither the name of Pier Luigi Fiorini nor the names of his
1806+# contributors may be used to endorse or promote products derived
1807+# from this software without specific prior written permission.
1808+#
1809+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1810+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1812+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1813+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1814+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1815+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1816+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1817+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1818+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1819+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1820+#=============================================================================
1821+
1822+find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
1823+
1824+# wayland_add_protocol_client(outfiles inputfile basename)
1825+function(WAYLAND_ADD_PROTOCOL_CLIENT _sources _protocol _basename)
1826+ if(NOT WAYLAND_SCANNER_EXECUTABLE)
1827+ message(FATAL "The wayland-scanner executable has nto been found on your system. You must install it.")
1828+ endif()
1829+
1830+ get_filename_component(_infile ${_protocol} ABSOLUTE)
1831+ set(_client_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-client-protocol.h")
1832+ set(_code "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-protocol.c")
1833+
1834+ add_custom_command(OUTPUT "${_client_header}"
1835+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} client-header < ${_infile} > ${_client_header}
1836+ DEPENDS ${_infile} VERBATIM)
1837+
1838+ add_custom_command(OUTPUT "${_code}"
1839+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} code < ${_infile} > ${_code}
1840+ DEPENDS ${_infile} VERBATIM)
1841+
1842+ list(APPEND ${_sources} "${_client_header}" "${_code}")
1843+ set(${_sources} ${${_sources}} PARENT_SCOPE)
1844+endfunction()
1845+
1846+# wayland_add_protocol_server(outfiles inputfile basename)
1847+function(WAYLAND_ADD_PROTOCOL_SERVER _sources _protocol _basename)
1848+ if(NOT WAYLAND_SCANNER_EXECUTABLE)
1849+ message(FATAL "The wayland-scanner executable has nto been found on your system. You must install it.")
1850+ endif()
1851+
1852+ get_filename_component(_infile ${_protocol} ABSOLUTE)
1853+ set(_server_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-server-protocol.h")
1854+
1855+ add_custom_command(OUTPUT "${_server_header}"
1856+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} server-header < ${_infile} > ${_server_header}
1857+ DEPENDS ${_infile} VERBATIM)
1858+
1859+ list(APPEND ${_sources} "${_server_header}")
1860+ set(${_sources} ${${_sources}} PARENT_SCOPE)
1861+endfunction()