0002-wayland-Add-support-for-the-Wayland-winsys.patch 66 KB

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