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

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