123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893 |
- From 3c1566e9c3b356cfcd8327fed0e537ed978c8e78 Mon Sep 17 00:00:00 2001
- From: Tomeu Vizoso <tomeu.vizoso@collabora.com>
- Date: Tue, 1 Oct 2013 13:19:20 +0200
- Subject: [PATCH] wayland: Add support for the Wayland winsys
- * Adds EGL_WL_bind_wayland_display extension
- * Adds wayland-egl library
- * Adds wl_dispmanx_buffer protocol extension
- TODO: Check that platform_get_dimensions() returning swapchain_count == 1 is correct
- TODO: Remove the requirement of passing a valid DispmanX element handle to
- the SwapBuffers and CreateSurface RPC calls. This will remove the need to open
- a DispmanX display from the clients.
- TODO: wl_dispmanx_server_buffer should probably be defined in a
- private header that can be included from EGL and vc_* instead of in
- vc_vchi_dispmanx.h
- Signed-off-by: Khem Raj <raj.khem@gmail.com>
- ---
- Upstream-Status: Pending
- .gitignore | 1 +
- CMakeLists.txt | 11 +
- README.md | 4 +
- buildme | 10 +-
- .../linux/apps/raspicam/CMakeLists.txt | 2 +-
- interface/khronos/CMakeLists.txt | 54 +++-
- interface/khronos/common/khrn_client.c | 15 ++
- interface/khronos/common/khrn_client.h | 10 +
- interface/khronos/common/khrn_client_mangle.h | 3 +
- .../khronos/common/khrn_client_platform.h | 8 +
- .../khronos/common/khrn_client_unmangle.h | 3 +
- .../common/linux/khrn_client_platform_linux.c | 115 +++++++-
- interface/khronos/common/linux/khrn_wayland.c | 215 +++++++++++++++
- .../common/linux/khrn_wayland.h} | 46 +---
- interface/khronos/egl/egl_client.c | 92 +++++--
- interface/khronos/egl/egl_client_get_proc.c | 11 +
- interface/khronos/egl/egl_client_surface.c | 42 ++-
- interface/khronos/egl/egl_client_surface.h | 38 ++-
- interface/khronos/egl/egl_int_impl.h | 2 +-
- interface/khronos/ext/egl_wayland.c | 246 ++++++++++++++++++
- interface/khronos/include/EGL/eglext.h | 23 ++
- .../khronos/wayland-egl/wayland-egl-priv.h | 53 ++++
- interface/khronos/wayland-egl/wayland-egl.c | 59 +++++
- .../khronos/wayland-egl/wayland-egl.pc.in | 10 +
- interface/vmcs_host/CMakeLists.txt | 13 +-
- interface/vmcs_host/vc_dispmanx.h | 10 +
- interface/vmcs_host/vc_vchi_dispmanx.c | 42 +++
- interface/vmcs_host/vc_vchi_dispmanx.h | 15 ++
- interface/wayland/dispmanx.xml | 123 +++++++++
- makefiles/cmake/Wayland.cmake | 72 +++++
- 30 files changed, 1253 insertions(+), 95 deletions(-)
- create mode 100644 interface/khronos/common/linux/khrn_wayland.c
- copy interface/{vmcs_host/vc_vchi_dispmanx.h => khronos/common/linux/khrn_wayland.h} (56%)
- create mode 100644 interface/khronos/ext/egl_wayland.c
- create mode 100644 interface/khronos/wayland-egl/wayland-egl-priv.h
- create mode 100644 interface/khronos/wayland-egl/wayland-egl.c
- create mode 100644 interface/khronos/wayland-egl/wayland-egl.pc.in
- create mode 100644 interface/wayland/dispmanx.xml
- create mode 100644 makefiles/cmake/Wayland.cmake
- diff --git a/.gitignore b/.gitignore
- index 63570f1..1459436 100644
- --- a/.gitignore
- +++ b/.gitignore
- @@ -30,3 +30,4 @@ build/
- *.pts
- *.ppm
- *.mkv
- +*~
- diff --git a/CMakeLists.txt b/CMakeLists.txt
- index fe67fc8..80337b2 100644
- --- a/CMakeLists.txt
- +++ b/CMakeLists.txt
- @@ -24,6 +24,17 @@ include(makefiles/cmake/global_settings.cmake)
- include(makefiles/cmake/arm-linux.cmake)
- include(makefiles/cmake/vmcs.cmake)
-
- +if (BUILD_WAYLAND)
- + include(makefiles/cmake/Wayland.cmake)
- +
- + # Find Wayland libraries
- + find_package(PkgConfig)
- + pkg_check_modules(WAYLAND_CLIENT wayland-client REQUIRED)
- + pkg_check_modules(WAYLAND_SERVER wayland-server REQUIRED)
- +
- + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBUILD_WAYLAND")
- +endif()
- +
- enable_language(ASM)
-
- # Global include paths
- diff --git a/README.md b/README.md
- index 404e4d4..97a6b8f 100644
- --- a/README.md
- +++ b/README.md
- @@ -8,3 +8,7 @@ https://github.com/raspberrypi/tools/tree/master/arm-bcm2708/gcc-linaro-arm-linu
- 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.
-
- Note that this repository does not contain the source for the edidparser and vcdbg binaries due to licensing restrictions.
- +
- +To build support for the Wayland winsys in EGL, execute the buildme script like this:
- +
- +$ BUILD_WAYLAND=1 ./buildme.
- diff --git a/buildme b/buildme
- index 9e2d405..7b8c0d6 100755
- --- a/buildme
- +++ b/buildme
- @@ -17,6 +17,10 @@ fi
-
- BUILDSUBDIR=`echo $BUILDTYPE | tr '[A-Z]' '[a-z]'`;
-
- +if [ -n "$BUILD_WAYLAND" ]; then
- + WAYLAND_VARS="-DBUILD_WAYLAND=TRUE"
- +fi
- +
- if [ $ARCH = "armv6l" ] || [ $ARCH = "armv7l" ] || [ $ARCH = "aarch64" ]; then
- # Native compile on the Raspberry Pi
- mkdir -p build/raspberry/$BUILDSUBDIR
- @@ -41,9 +45,13 @@ elif [ "$1" = "--native" ]; then
- make -j `nproc` $*
- else
- # Cross compile on a more capable machine
- + if [ -n "$BUILD_WAYLAND" ]; then
- + # Use wayland-scanner from the build platform
- + WAYLAND_VARS+=" -DWAYLAND_SCANNER_EXECUTABLE:FILEPATH=/usr/bin/wayland-scanner"
- + fi
- mkdir -p build/arm-linux/$BUILDSUBDIR
- pushd build/arm-linux/$BUILDSUBDIR
- - cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE -DCMAKE_BUILD_TYPE=$BUILDTYPE -DARM64=$ARM64 ../../..
- + cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE -DCMAKE_BUILD_TYPE=$BUILDTYPE -DARM64=$ARM64 $WAYLAND_VARS ../../..
- make -j `nproc`
-
- if [ "$1" != "" ]; then
- diff --git a/host_applications/linux/apps/raspicam/CMakeLists.txt b/host_applications/linux/apps/raspicam/CMakeLists.txt
- index eb1ef7c..5aeeb2e 100644
- --- a/host_applications/linux/apps/raspicam/CMakeLists.txt
- +++ b/host_applications/linux/apps/raspicam/CMakeLists.txt
- @@ -61,7 +61,7 @@ add_executable(raspivid ${COMMON_SOURCES} RaspiVid.c)
- add_executable(raspividyuv ${COMMON_SOURCES} RaspiVidYUV.c)
-
- set (MMAL_LIBS mmal_core mmal_util mmal_vc_client)
- -target_link_libraries(raspistill ${MMAL_LIBS} vcos bcm_host ${EGL_LIBS} m dl)
- +target_link_libraries(raspistill ${MMAL_LIBS} vcos bcm_host ${EGL_LIBS} m dl ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_CLIENT_LIBRARIES})
- target_link_libraries(raspiyuv ${MMAL_LIBS} vcos bcm_host m)
- target_link_libraries(raspivid ${MMAL_LIBS} vcos bcm_host m)
- target_link_libraries(raspividyuv ${MMAL_LIBS} vcos bcm_host m)
- diff --git a/interface/khronos/CMakeLists.txt b/interface/khronos/CMakeLists.txt
- index 9ad615b..95c0e11 100644
- --- a/interface/khronos/CMakeLists.txt
- +++ b/interface/khronos/CMakeLists.txt
- @@ -6,6 +6,12 @@
- # have quite a few circular dependencies, and so the only way
- # to make it work seems to be to have everything static.
-
- +if (BUILD_WAYLAND)
- +include_directories(
- + ${WAYLAND_SERVER_INCLUDE_DIRS}
- +)
- +endif ()
- +
- set(EGL_SOURCE
- egl/egl_client_config.c
- egl/egl_client_context.c
- @@ -55,12 +61,55 @@ set(CLIENT_SOURCE
- common/khrn_int_hash_asm.s
- common/khrn_client_cache.c)
-
- +set(EGL_LIBS
- + khrn_client
- + vchiq_arm
- + vcos
- + bcm_host)
- +
- +if (BUILD_WAYLAND)
- + set(EGL_SOURCE
- + ${EGL_SOURCE}
- + ext/egl_wayland.c
- + common/linux/khrn_wayland.c)
- +
- + set(EGL_LIBS
- + ${EGL_LIBS}
- + wayland-client
- + wayland-server)
- +
- + set(WAYLAND_EGL_SOURCE
- + wayland-egl/wayland-egl.c)
- +
- + wayland_add_protocol_server(
- + EGL_SOURCE
- + ../../interface/wayland/dispmanx.xml
- + dispmanx
- + )
- +
- + wayland_add_protocol_client(
- + EGL_SOURCE
- + ../../interface/wayland/dispmanx.xml
- + dispmanx
- + )
- +
- + add_library(wayland-egl ${SHARED} ${WAYLAND_EGL_SOURCE})
- + install(TARGETS wayland-egl DESTINATION lib)
- +
- + configure_file ("wayland-egl/wayland-egl.pc.in" "wayland-egl/wayland-egl.pc" @ONLY)
- + install (FILES "${CMAKE_CURRENT_BINARY_DIR}/wayland-egl/wayland-egl.pc"
- + DESTINATION lib/pkgconfig)
- +endif ()
- +
- add_library(EGL ${SHARED} ${EGL_SOURCE})
- add_library(GLESv2 ${SHARED} ${GLES_SOURCE})
- add_library(OpenVG ${SHARED} ${VG_SOURCE})
- add_library(WFC ${SHARED} ${WFC_SOURCE})
- add_library(khrn_client ${CLIENT_SOURCE})
-
- +set_target_properties(EGL PROPERTIES SOVERSION 1 VERSION 1.0.0)
- +set_target_properties(GLESv2 PROPERTIES SOVERSION 2 VERSION 2.0.0)
- +
- # TODO do we need EGL_static and GLESv2_static now that khrn_static exists?
- add_library(EGL_static STATIC ${EGL_SOURCE})
- add_library(GLESv2_static STATIC ${GLES_SOURCE})
- @@ -72,8 +121,7 @@ include_directories (../../host_applications/linux/libs/sm )
- set(VCSM_LIBS vcsm)
- add_definitions(-DKHRONOS_HAVE_VCSM)
- endif()
- -
- -target_link_libraries(EGL khrn_client vchiq_arm vcos bcm_host ${VCSM_LIBS} -lm)
- +target_link_libraries(EGL ${EGL_LIBS} ${VCSM_LIBS} -lm)
- target_link_libraries(GLESv2 EGL khrn_client vcos)
- target_link_libraries(WFC EGL)
- target_link_libraries(OpenVG EGL)
- @@ -87,7 +135,7 @@ add_library(brcmGLESv2 ${SHARED} ${GLES_SOURCE})
- add_library(brcmOpenVG ${SHARED} ${VG_SOURCE})
- add_library(brcmWFC ${SHARED} ${WFC_SOURCE})
-
- -target_link_libraries(brcmEGL khrn_client vchiq_arm vcos bcm_host ${VCSM_LIBS} -lm)
- +target_link_libraries(brcmEGL ${EGL_LIBS} ${VCSM_LIBS} -lm)
- target_link_libraries(brcmGLESv2 brcmEGL khrn_client vcos)
- target_link_libraries(brcmWFC brcmEGL)
- target_link_libraries(brcmOpenVG brcmEGL)
- diff --git a/interface/khronos/common/khrn_client.c b/interface/khronos/common/khrn_client.c
- index ef4babd..d7e798e 100644
- --- a/interface/khronos/common/khrn_client.c
- +++ b/interface/khronos/common/khrn_client.c
- @@ -54,6 +54,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #include "applications/vmcs/khronos/khronos_server.h"
- #endif
-
- +#ifdef BUILD_WAYLAND
- +#include "interface/khronos/common/linux/khrn_wayland.h"
- +#endif
- +
- VCOS_LOG_CAT_T khrn_client_log = VCOS_LOG_INIT("khrn_client", VCOS_LOG_WARN);
-
- /*
- @@ -142,6 +146,10 @@ void client_try_unload_server(CLIENT_PROCESS_STATE_T *process)
- bool client_process_state_init(CLIENT_PROCESS_STATE_T *process)
- {
- if (!process->inited) {
- +#ifdef BUILD_WAYLAND
- + process->wl_global = NULL;
- +#endif
- +
- if (!khrn_pointer_map_init(&process->contexts, 64))
- return false;
-
- @@ -194,6 +202,13 @@ bool client_process_state_init(CLIENT_PROCESS_STATE_T *process)
- }
- #endif
-
- +#ifdef BUILD_WAYLAND
- + struct wl_display *wl_display = khrn_platform_get_wl_display();
- + if (wl_display)
- + if (!init_process_wayland(process))
- + return false;
- +#endif
- +
- process->inited = true;
- }
-
- diff --git a/interface/khronos/common/khrn_client.h b/interface/khronos/common/khrn_client.h
- index 804039b..615f7b4 100644
- --- a/interface/khronos/common/khrn_client.h
- +++ b/interface/khronos/common/khrn_client.h
- @@ -310,6 +310,16 @@ struct CLIENT_PROCESS_STATE {
- #ifdef RPC_LIBRARY
- KHRONOS_SERVER_CONNECTION_T khrn_connection;
- #endif
- +
- +#ifdef BUILD_WAYLAND
- + /* Client-side Wayland state */
- + struct wl_registry *wl_registry;
- + struct wl_dispmanx *wl_dispmanx;
- + struct wl_event_queue *wl_queue;
- +
- + /* Compositor-side Wayland state */
- + struct wl_global *wl_global;
- +#endif
- };
-
- extern bool client_process_state_init(CLIENT_PROCESS_STATE_T *process);
- diff --git a/interface/khronos/common/khrn_client_mangle.h b/interface/khronos/common/khrn_client_mangle.h
- index b3c04f4..b7b21c5 100644
- --- a/interface/khronos/common/khrn_client_mangle.h
- +++ b/interface/khronos/common/khrn_client_mangle.h
- @@ -83,6 +83,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #define eglReleaseGlobalImageBRCM mangled_eglReleaseGlobalImageBRCM
- #define eglInitGlobalImageBRCM mangled_eglInitGlobalImageBRCM
- #define eglTermGlobalImageBRCM mangled_eglTermGlobalImageBRCM
- +#define eglBindWaylandDisplayWL mangled_eglBindWaylandDisplayWL
- +#define eglUnbindWaylandDisplayWL mangled_eglUnbindWaylandDisplayWL
- +#define eglQueryWaylandBufferWL mangled_eglQueryWaylandBufferWL
-
- /* OpenGL ES 1.1 and 2.0 functions */
-
- diff --git a/interface/khronos/common/khrn_client_platform.h b/interface/khronos/common/khrn_client_platform.h
- index 1c9da3a..715c67e 100644
- --- a/interface/khronos/common/khrn_client_platform.h
- +++ b/interface/khronos/common/khrn_client_platform.h
- @@ -48,6 +48,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #include "interface/khronos/common/vcos/khrn_client_platform_filler_vcos.h"
- #endif
-
- +#ifdef BUILD_WAYLAND
- +#include <wayland-client.h>
- +#endif
- +
- #ifdef __cplusplus
- extern "C" {
- #endif
- @@ -328,4 +332,8 @@ typedef struct
-
- void *platform_wfc_bounce_thread(void *param);
-
- +#ifdef BUILD_WAYLAND
- +struct wl_display *khrn_platform_get_wl_display();
- +#endif
- +
- #endif // KHRN_CLIENT_PLATFORM_H
- diff --git a/interface/khronos/common/khrn_client_unmangle.h b/interface/khronos/common/khrn_client_unmangle.h
- index 4f3ce49..84f6ec0 100644
- --- a/interface/khronos/common/khrn_client_unmangle.h
- +++ b/interface/khronos/common/khrn_client_unmangle.h
- @@ -83,6 +83,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #undef eglReleaseGlobalImageBRCM
- #undef eglInitGlobalImageBRCM
- #undef eglTermGlobalImageBRCM
- +#undef eglBindWaylandDisplayWL
- +#undef eglUnbindWaylandDisplayWL
- +#undef eglQueryWaylandBufferWL
-
- /* OpenGL ES 1.1 and 2.0 functions */
-
- diff --git a/interface/khronos/common/linux/khrn_client_platform_linux.c b/interface/khronos/common/linux/khrn_client_platform_linux.c
- index 710d20f..50d60a6 100644
- --- a/interface/khronos/common/linux/khrn_client_platform_linux.c
- +++ b/interface/khronos/common/linux/khrn_client_platform_linux.c
- @@ -37,6 +37,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #include "X11/Xlib.h"
- #endif
-
- +#ifdef BUILD_WAYLAND
- +#include <wayland-client.h>
- +#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
- +#endif
- +
- extern VCOS_LOG_CAT_T khrn_client_log;
-
- extern void vc_vchi_khronos_init();
- @@ -464,13 +469,36 @@ EGLDisplay khrn_platform_set_display_id(EGLNativeDisplayType display_id)
- return EGL_NO_DISPLAY;
- }
- #else
- +
- +#ifdef BUILD_WAYLAND
- +static struct wl_display *hacky_display = NULL;
- +#endif
- +
- EGLDisplay khrn_platform_set_display_id(EGLNativeDisplayType display_id)
- {
- if (display_id == EGL_DEFAULT_DISPLAY)
- return (EGLDisplay)1;
- - else
- - return EGL_NO_DISPLAY;
- + else {
- +#ifdef BUILD_WAYLAND
- + void *first_pointer = *(void **) display_id;
- +
- + /* wl_display is a wl_proxy, which is a wl_object.
- + * wl_object's first element points to the interfacetype. */
- + if (first_pointer == &wl_display_interface) {
- + hacky_display = (struct wl_display*)display_id;
- + return (EGLDisplay)1;
- + } else
- +#endif
- + return EGL_NO_DISPLAY;
- + }
- }
- +
- +#ifdef BUILD_WAYLAND
- +struct wl_display *khrn_platform_get_wl_display()
- +{
- + return hacky_display;
- +}
- +#endif
- #endif
-
- #ifdef WANT_X
- @@ -805,22 +833,81 @@ static EGL_DISPMANX_WINDOW_T *check_default(EGLNativeWindowType win)
- void platform_get_dimensions(EGLDisplay dpy, EGLNativeWindowType win,
- uint32_t *width, uint32_t *height, uint32_t *swapchain_count)
- {
- - EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
- - vcos_assert(dwin);
- - vcos_assert(dwin->width < 1<<16); // sanity check
- - vcos_assert(dwin->height < 1<<16); // sanity check
- - *width = dwin->width;
- - *height = dwin->height;
- - *swapchain_count = 0;
- +#ifdef BUILD_WAYLAND
- + if(khrn_platform_get_wl_display()) {
- + struct wl_egl_window *wl_egl_window = (struct wl_egl_window*)win;
- + *width = wl_egl_window->width;
- + *height = wl_egl_window->height;
- + /* This seems to be used for sync'ing with the VC on buffer creation, but
- + we are managing them on the CPU side */
- + *swapchain_count = 1;
- + } else {
- +#endif
- + EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
- + vcos_assert(dwin);
- + vcos_assert(dwin->width < 1<<16); // sanity check
- + vcos_assert(dwin->height < 1<<16); // sanity check
- + *width = dwin->width;
- + *height = dwin->height;
- + *swapchain_count = 0;
- +#ifdef BUILD_WAYLAND
- + }
- +#endif
- }
-
- +#ifdef BUILD_WAYLAND
- +static DISPMANX_ELEMENT_HANDLE_T create_dummy_element()
- +{
- + DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(0);
- + DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);
- + DISPMANX_ELEMENT_HANDLE_T element;
- + VC_DISPMANX_ALPHA_T alpha = {DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0};
- + VC_RECT_T src_rect;
- + VC_RECT_T dst_rect;
- +
- + src_rect.x = 0;
- + src_rect.y = 0;
- + src_rect.width = 1 << 16;
- + src_rect.height = 1 << 16;
- +
- + dst_rect.x = 0;
- + dst_rect.y = 0;
- + dst_rect.width = 1;
- + dst_rect.height = 1;
- +
- + element = vc_dispmanx_element_add(update, display, 0/*layer*/, &dst_rect,
- + 0/*src*/, &src_rect,
- + DISPMANX_PROTECTION_NONE, &alpha,
- + 0/*clamp*/, 0/*transform*/);
- +
- + vc_dispmanx_update_submit_sync(update);
- +
- + vc_dispmanx_display_close(display);
- +
- + return element;
- +}
- +#endif
- +
- uint32_t platform_get_handle(EGLDisplay dpy, EGLNativeWindowType win)
- {
- - EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
- - vcos_assert(dwin);
- - vcos_assert(dwin->width < 1<<16); // sanity check
- - vcos_assert(dwin->height < 1<<16); // sanity check
- - return dwin->element;
- +#ifdef BUILD_WAYLAND
- + if(khrn_platform_get_wl_display()) {
- + struct wl_egl_window *wl_egl_window = (struct wl_egl_window*)win;
- +
- + if (wl_egl_window->dummy_element == PLATFORM_WIN_NONE)
- + wl_egl_window->dummy_element = create_dummy_element();
- +
- + return wl_egl_window->dummy_element;
- + } else {
- +#endif
- + EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
- + vcos_assert(dwin);
- + vcos_assert(dwin->width < 1<<16); // sanity check
- + vcos_assert(dwin->height < 1<<16); // sanity check
- + return dwin->element;
- +#ifdef BUILD_WAYLAND
- + }
- +#endif
- }
-
- #endif
- diff --git a/interface/khronos/common/linux/khrn_wayland.c b/interface/khronos/common/linux/khrn_wayland.c
- new file mode 100644
- index 0000000..0e1b9e7
- --- /dev/null
- +++ b/interface/khronos/common/linux/khrn_wayland.c
- @@ -0,0 +1,215 @@
- +/*
- +Copyright (c) 2013, Raspberry Pi Foundation
- +All rights reserved.
- +
- +Redistribution and use in source and binary forms, with or without
- +modification, are permitted provided that the following conditions are met:
- + * Redistributions of source code must retain the above copyright
- + notice, this list of conditions and the following disclaimer.
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- + * Neither the name of the copyright holder nor the
- + names of its contributors may be used to endorse or promote products
- + derived from this software without specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +*/
- +
- +#define VCOS_LOG_CATEGORY (&khrn_client_log)
- +
- +#include "interface/khronos/common/linux/khrn_wayland.h"
- +#include "interface/khronos/wayland-dispmanx-client-protocol.h"
- +#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
- +
- +extern VCOS_LOG_CAT_T khrn_client_log;
- +
- +static void handle_dispmanx_format(void *data, struct wl_dispmanx *dispmanx,
- + uint32_t format)
- +{
- +}
- +
- +static void handle_dispmanx_allocated(void *data, struct wl_dispmanx *dispmanx,
- + struct wl_buffer *wl_buffer,
- + uint32_t resource_handle)
- +{
- + struct wl_dispmanx_client_buffer *buffer = wl_buffer_get_user_data(wl_buffer);
- +
- + buffer->pending_allocation = 0;
- + buffer->resource = resource_handle;
- +}
- +
- +static const struct wl_dispmanx_listener dispmanx_listener = {
- + handle_dispmanx_format,
- + handle_dispmanx_allocated,
- +};
- +
- +static void
- +sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
- +{
- + int *done = data;
- +
- + *done = 1;
- +
- + wl_callback_destroy(callback);
- +}
- +
- +static const struct wl_callback_listener sync_listener = {
- + sync_callback
- +};
- +
- +static int
- +roundtrip(CLIENT_PROCESS_STATE_T *process)
- +{
- + struct wl_display *wl_display = khrn_platform_get_wl_display();
- + struct wl_callback *callback;
- + int done = 0, ret = 0;
- +
- + callback = wl_display_sync(wl_display);
- + wl_callback_add_listener(callback, &sync_listener, &done);
- + wl_proxy_set_queue((struct wl_proxy *) callback, process->wl_queue);
- + while (ret != -1 && !done)
- + ret = wl_display_dispatch_queue(wl_display, process->wl_queue);
- +
- + if (!done)
- + wl_callback_destroy(callback);
- +
- + return ret;
- +}
- +
- +int do_wl_roundtrip()
- +{
- + CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
- + return roundtrip(process);
- +}
- +
- +static void
- +registry_handle_global(void *data, struct wl_registry *registry,
- + uint32_t name, const char *interface, uint32_t version)
- +{
- + struct wl_display *wl_display = khrn_platform_get_wl_display();
- + CLIENT_PROCESS_STATE_T *process = (CLIENT_PROCESS_STATE_T *)data;
- +
- + if (strcmp(interface, "wl_dispmanx") == 0) {
- + process->wl_dispmanx = wl_registry_bind(registry, name,
- + &wl_dispmanx_interface, 1);
- +
- + wl_proxy_set_queue((struct wl_proxy *) process->wl_dispmanx,
- + process->wl_queue);
- + wl_dispmanx_add_listener(process->wl_dispmanx, &dispmanx_listener, wl_display);
- + roundtrip(process);
- + }
- +}
- +
- +static void
- +registry_handle_global_remove(void *data, struct wl_registry *registry,
- + uint32_t name)
- +{
- +}
- +
- +static const struct wl_registry_listener registry_listener = {
- + registry_handle_global,
- + registry_handle_global_remove
- +};
- +
- +int
- +init_process_wayland(CLIENT_PROCESS_STATE_T *process)
- +{
- + struct wl_display *wl_display = khrn_platform_get_wl_display();
- +
- + process->wl_queue = wl_display_create_queue(wl_display);
- + if (!process->wl_queue) {
- + vcos_log_error("wl_display_create_queue failed\n");
- + return false;
- + }
- + wl_display_dispatch_pending(wl_display);
- +
- + process->wl_registry = wl_display_get_registry(wl_display);
- + if (!process->wl_registry) {
- + vcos_log_error("wl_display_get_registry failed\n");
- + return false;
- + }
- +
- + wl_proxy_set_queue((struct wl_proxy *) process->wl_registry,
- + process->wl_queue);
- +
- + wl_registry_add_listener(process->wl_registry, ®istry_listener, process);
- +
- + if (roundtrip(process) < 0 || process->wl_dispmanx == NULL) {
- + vcos_log_error("failed to get wl_dispmanx\n");
- + return false;
- + }
- +
- + return true;
- +}
- +
- +#ifndef ALIGN_UP
- +#define ALIGN_UP(x,y) ((x + (y)-1) & ~((y)-1))
- +#endif
- +
- +static void handle_buffer_release(void *data, struct wl_buffer *buffer_wl)
- +{
- + struct wl_dispmanx_client_buffer *wl_dispmanx_client_buffer = data;
- + wl_dispmanx_client_buffer->in_use = 0;
- +}
- +
- +static const struct wl_buffer_listener buffer_listener = {
- + handle_buffer_release
- +};
- +
- +struct wl_dispmanx_client_buffer *
- +allocate_wl_buffer(struct wl_egl_window *window, KHRN_IMAGE_FORMAT_T color)
- +{
- + CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
- + struct wl_dispmanx_client_buffer *wl_dispmanx_client_buffer;
- + struct wl_buffer *wl_buffer;
- + uint32_t stride = ALIGN_UP(window->width * 4, 16);
- + uint32_t buffer_height = ALIGN_UP(window->height, 16);
- + enum wl_dispmanx_format color_format;
- + int ret = 0;
- +
- + switch (color) {
- + case ABGR_8888:
- + color_format = WL_DISPMANX_FORMAT_ABGR8888;
- + break;
- + case XBGR_8888:
- + color_format = WL_DISPMANX_FORMAT_XBGR8888;
- + break;
- + case RGB_565:
- + color_format = WL_DISPMANX_FORMAT_RGB565;
- + break;
- + default:
- + vcos_log_error("unknown KHRN_IMAGE_FORMAT_T 0x%x\n", color);
- + return NULL;
- + }
- +
- + wl_buffer = wl_dispmanx_create_buffer(process->wl_dispmanx, window->width,
- + window->height, stride, buffer_height,
- + color_format);
- + if (wl_buffer == NULL)
- + return NULL;
- +
- + wl_dispmanx_client_buffer = calloc(1, sizeof(struct wl_dispmanx_client_buffer));
- + wl_dispmanx_client_buffer->wl_buffer = wl_buffer;
- + wl_dispmanx_client_buffer->in_use = 0;
- + wl_dispmanx_client_buffer->pending_allocation = 1;
- + wl_dispmanx_client_buffer->width = window->width;
- + wl_dispmanx_client_buffer->height = window->height;
- +
- + wl_proxy_set_queue((struct wl_proxy *) wl_buffer, process->wl_queue);
- + wl_buffer_add_listener(wl_buffer, &buffer_listener, wl_dispmanx_client_buffer);
- +
- + while (ret != -1 && wl_dispmanx_client_buffer->pending_allocation)
- + ret = do_wl_roundtrip();
- +
- + return wl_dispmanx_client_buffer;
- +}
- diff --git a/interface/vmcs_host/vc_vchi_dispmanx.h b/interface/khronos/common/linux/khrn_wayland.h
- similarity index 56%
- copy from interface/vmcs_host/vc_vchi_dispmanx.h
- copy to interface/khronos/common/linux/khrn_wayland.h
- index b723b76..b9bf08c 100644
- --- a/interface/vmcs_host/vc_vchi_dispmanx.h
- +++ b/interface/khronos/common/linux/khrn_wayland.h
- @@ -1,5 +1,5 @@
- /*
- -Copyright (c) 2012, Broadcom Europe Ltd
- +Copyright (c) 2013, Raspberry Pi Foundation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- @@ -25,45 +25,9 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- -#ifndef VC_VCHI_DISPMANX_H
- -#define VC_VCHI_DISPMANX_H
- +#include "interface/khronos/common/khrn_client.h"
-
- -#include "interface/peer/vc_vchi_dispmanx_common.h"
- +int init_process_wayland(CLIENT_PROCESS_STATE_T *process);
- +int do_wl_roundtrip();
-
- -#define VC_NUM_HOST_RESOURCES 64
- -#define DISPMANX_MSGFIFO_SIZE 1024
- -#define DISPMANX_CLIENT_NAME MAKE_FOURCC("DISP")
- -#define DISPMANX_NOTIFY_NAME MAKE_FOURCC("UPDH")
- -
- -//Or with command to indicate we don't need a response
- -#define DISPMANX_NO_REPLY_MASK (1<<31)
- -
- -typedef struct {
- - char description[32];
- - uint32_t width;
- - uint32_t height;
- - uint32_t aspect_pixwidth;
- - uint32_t aspect_pixheight;
- - uint32_t fieldrate_num;
- - uint32_t fieldrate_denom;
- - uint32_t fields_per_frame;
- - uint32_t transform;
- -} GET_MODES_DATA_T;
- -
- -typedef struct {
- - int32_t response;
- - uint32_t width;
- - uint32_t height;
- - uint32_t transform;
- - uint32_t input_format;
- -} GET_INFO_DATA_T;
- -
- -//Attributes changes flag mask
- -#define ELEMENT_CHANGE_LAYER (1<<0)
- -#define ELEMENT_CHANGE_OPACITY (1<<1)
- -#define ELEMENT_CHANGE_DEST_RECT (1<<2)
- -#define ELEMENT_CHANGE_SRC_RECT (1<<3)
- -#define ELEMENT_CHANGE_MASK_RESOURCE (1<<4)
- -#define ELEMENT_CHANGE_TRANSFORM (1<<5)
- -
- -#endif
- +struct wl_dispmanx_client_buffer *allocate_wl_buffer(struct wl_egl_window *window, KHRN_IMAGE_FORMAT_T color);
- diff --git a/interface/khronos/egl/egl_client.c b/interface/khronos/egl/egl_client.c
- index b8bb374..03fe67b 100644
- --- a/interface/khronos/egl/egl_client.c
- +++ b/interface/khronos/egl/egl_client.c
- @@ -153,6 +153,10 @@ by an attribute value"
- #include <stdlib.h>
- #include <string.h>
-
- +#ifdef BUILD_WAYLAND
- +#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
- +#include "interface/khronos/common/linux/khrn_wayland.h"
- +#endif
-
- #include "interface/khronos/egl/egl_client_cr.c"
-
- @@ -162,17 +166,6 @@ static void egl_current_release(CLIENT_PROCESS_STATE_T *process, EGL_CURRENT_T *
- void egl_gl_flush_callback(bool wait);
- void egl_vg_flush_callback(bool wait);
-
- -#include "interface/vmcs_host/vc_dispmanx_types.h"
- -/**HACKHACK - give us the ability to inject a DispmanX
- - * resource handle into the CreateWindowSurface and
- - * SwapBuffers calls */
- -static DISPMANX_RESOURCE_HANDLE_T next_resource_handle;
- -
- -EGLAPI EGLBoolean EGLAPIENTRY eglSetNextResourceHandle(DISPMANX_RESOURCE_HANDLE_T handle)
- -{
- - next_resource_handle = handle;
- -}
- -
- /*
- TODO: do an RPC call to make sure the Khronos vll is loaded (and that it stays loaded until eglTerminate)
- Also affects global image (and possibly others?)
- @@ -450,6 +443,9 @@ EGLAPI const char EGLAPIENTRY * eglQueryString(EGLDisplay dpy, EGLint name)
- #ifdef EGL_KHR_fence_sync
- "EGL_KHR_fence_sync "
- #endif
- +#endif
- +#if EGL_WL_bind_wayland_display
- + "EGL_WL_bind_wayland_display "
- #endif
- ;
- break;
- @@ -655,8 +651,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig c
- false,
- EGL_NO_TEXTURE,
- EGL_NO_TEXTURE,
- - 0, 0,
- - next_resource_handle);
- + 0, 0);
-
- if (surface) {
- if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
- @@ -901,7 +896,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig
- mipmap_texture,
- texture_format,
- texture_target,
- - 0, 0, 0);
- + 0, 0);
-
- if (surface) {
- if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
- @@ -1043,7 +1038,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig c
- false,
- EGL_NO_TEXTURE,
- EGL_NO_TEXTURE,
- - pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle, 0);
- + pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle);
-
- if (surface) {
- if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
- @@ -2245,6 +2240,9 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
- CLIENT_THREAD_STATE_T *thread;
- CLIENT_PROCESS_STATE_T *process;
- EGLBoolean result;
- +#ifdef BUILD_WAYLAND
- + struct wl_display *wl_display = khrn_platform_get_wl_display();
- +#endif
-
- vcos_log_trace("eglSwapBuffers start. dpy=%d. surf=%d.", (int)dpy, (int)surf);
-
- @@ -2315,18 +2313,58 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
-
- vcos_log_trace("eglSwapBuffers server call");
-
- - if (next_resource_handle)
- - RPC_CALL7(eglIntSwapBuffers_impl,
- - thread,
- - EGLINTSWAPBUFFERS_ID_V2,
- - RPC_UINT(surface->serverbuffer),
- - RPC_UINT(surface->width),
- - RPC_UINT(surface->height),
- - RPC_UINT(surface->internal_handle),
- - RPC_UINT(surface->swap_behavior == EGL_BUFFER_PRESERVED ? 1 : 0),
- - RPC_UINT(khrn_platform_get_window_position(surface->win)),
- - RPC_INT(next_resource_handle));
- - else
- +#ifdef BUILD_WAYLAND
- + if (wl_display) {
- + struct wl_egl_window *wl_egl_window = surface->wl_egl_window;
- + struct wl_dispmanx_client_buffer *buffer_temp;
- + uint32_t configid;
- + KHRN_IMAGE_FORMAT_T color;
- + int ret = 0;
- +
- + buffer_temp = surface->front_wl_buffer;
- + surface->front_wl_buffer = surface->back_wl_buffer;
- + surface->back_wl_buffer = buffer_temp;
- +
- + configid = egl_config_to_id(surface->config);
- + color = egl_config_get_color_format(configid);
- +
- + if (surface->back_wl_buffer == NULL)
- + surface->back_wl_buffer = allocate_wl_buffer(wl_egl_window, color);
- + else if (surface->back_wl_buffer->width != width ||
- + surface->back_wl_buffer->height != height) {
- +
- + struct wl_dispmanx_client_buffer *buffer;
- +
- + wl_buffer_destroy(surface->back_wl_buffer->wl_buffer);
- + free(surface->back_wl_buffer);
- +
- + buffer = allocate_wl_buffer(wl_egl_window, color);
- + surface->back_wl_buffer = buffer;
- + }
- +
- + RPC_CALL7(eglIntSwapBuffers_impl,
- + thread,
- + EGLINTSWAPBUFFERS_ID_V2,
- + RPC_UINT(surface->serverbuffer),
- + RPC_UINT(surface->width),
- + RPC_UINT(surface->height),
- + RPC_UINT(surface->internal_handle),
- + RPC_UINT(surface->swap_behavior == EGL_BUFFER_PRESERVED ? 1 : 0),
- + RPC_UINT(khrn_platform_get_window_position(surface->win)),
- + RPC_INT(surface->back_wl_buffer->resource));
- +
- + surface->front_wl_buffer->in_use = 1;
- + wl_surface_attach(wl_egl_window->wl_surface,
- + surface->front_wl_buffer->wl_buffer,
- + 0, 0);
- + wl_surface_damage(wl_egl_window->wl_surface, 0, 0,
- + surface->width, surface->height);
- + wl_surface_commit(wl_egl_window->wl_surface);
- +
- + while(ret != -1 && surface->back_wl_buffer->in_use)
- + ret = wl_display_dispatch_queue(wl_display, process->wl_queue);
- + } else
- +#endif
- RPC_CALL6(eglIntSwapBuffers_impl,
- thread,
- EGLINTSWAPBUFFERS_ID,
- diff --git a/interface/khronos/egl/egl_client_get_proc.c b/interface/khronos/egl/egl_client_get_proc.c
- index 4cfa9ff..6a715af 100644
- --- a/interface/khronos/egl/egl_client_get_proc.c
- +++ b/interface/khronos/egl/egl_client_get_proc.c
- @@ -254,6 +254,17 @@ EGLAPI void EGLAPIENTRY (* eglGetProcAddress(const char *procname))(void)
- return (void(*)(void))eglQueryGlobalImageBRCM;
- #endif
-
- +#ifdef BUILD_WAYLAND
- +#if EGL_WL_bind_wayland_display
- + if (!strcmp(procname, "eglBindWaylandDisplayWL"))
- + return (void(*)(void))eglBindWaylandDisplayWL;
- + if (!strcmp(procname, "eglUnbindWaylandDisplayWL"))
- + return (void(*)(void))eglUnbindWaylandDisplayWL;
- + if (!strcmp(procname, "eglQueryWaylandBufferWL"))
- + return (void(*)(void))eglQueryWaylandBufferWL;
- +#endif
- +#endif
- +
- return (void(*)(void)) NULL;
- }
-
- diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c
- index 128325e..42350bf 100644
- --- a/interface/khronos/egl/egl_client_surface.c
- +++ b/interface/khronos/egl/egl_client_surface.c
- @@ -46,6 +46,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #include "interface/khronos/egl/egl_int_impl.h"
- #endif
-
- +#ifdef BUILD_WAYLAND
- +#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
- +#include "interface/khronos/common/linux/khrn_wayland.h"
- +#endif
- +
- #include <stdlib.h>
-
-
- @@ -314,8 +319,7 @@ EGL_SURFACE_T *egl_surface_create(
- EGLenum texture_format,
- EGLenum texture_target,
- EGLNativePixmapType pixmap,
- - const uint32_t *pixmap_server_handle,
- - DISPMANX_RESOURCE_HANDLE_T next_resource_handle)
- + const uint32_t *pixmap_server_handle)
- {
- KHRN_IMAGE_FORMAT_T color;
- KHRN_IMAGE_FORMAT_T depth;
- @@ -326,6 +330,10 @@ EGL_SURFACE_T *egl_surface_create(
- EGLint config_depth_bits;
- EGLint config_stencil_bits;
- CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
- +#ifdef BUILD_WAYLAND
- + struct wl_display *wl_display = khrn_platform_get_wl_display();
- + DISPMANX_RESOURCE_HANDLE_T resource;
- +#endif
-
- EGL_SURFACE_T *surface = egl_surface_pool_alloc();
-
- @@ -390,6 +398,18 @@ EGL_SURFACE_T *egl_surface_create(
-
- vcos_assert(color != IMAGE_FORMAT_INVALID);
-
- +#ifdef BUILD_WAYLAND
- + if (type == WINDOW && wl_display) {
- + surface->wl_egl_window = (struct wl_egl_window*)win;
- + surface->back_wl_buffer = allocate_wl_buffer(
- + surface->wl_egl_window, color);
- + resource = surface->back_wl_buffer->resource;
- + } else {
- + surface->wl_egl_window = NULL;
- + resource = DISPMANX_NO_HANDLE;
- + }
- +#endif
- +
- #ifdef KHRONOS_EGL_PLATFORM_OPENWFC
- // Create stream for this window
- if(type != PBUFFER)
- @@ -474,7 +494,8 @@ EGL_SURFACE_T *egl_surface_create(
- #endif
- uint32_t results[3];
-
- - if (next_resource_handle)
- +#ifdef BUILD_WAYLAND
- + if (resource != DISPMANX_NO_HANDLE)
- RPC_CALL16_OUT_CTRL(eglIntCreateSurface_impl,
- thread,
- EGLINTCREATESURFACE_ID_V2,
- @@ -492,9 +513,10 @@ EGL_SURFACE_T *egl_surface_create(
- RPC_UINT(config_stencil_bits),
- RPC_UINT(sem_name),
- RPC_UINT(type),
- - RPC_INT(next_resource_handle),
- + RPC_INT(resource),
- results);
- else
- +#endif
- RPC_CALL15_OUT_CTRL(eglIntCreateSurface_impl,
- thread,
- EGLINTCREATESURFACE_ID,
- @@ -663,6 +685,18 @@ void egl_surface_free(EGL_SURFACE_T *surface)
- if( surface->type == WINDOW ) {
- vcos_log_trace("egl_surface_free: calling platform_destroy_winhandle...");
- platform_destroy_winhandle( surface->win, surface->internal_handle );
- +
- +#ifdef BUILD_WAYLAND
- + if (surface->back_wl_buffer) {
- + wl_buffer_destroy(surface->back_wl_buffer->wl_buffer);
- + free(surface->back_wl_buffer);
- + }
- +
- + if (surface->front_wl_buffer) {
- + wl_buffer_destroy(surface->front_wl_buffer->wl_buffer);
- + free(surface->front_wl_buffer);
- + }
- +#endif
- }
- /* return value ignored -- read performed to ensure blocking. we want this to
- * block so clients can safely destroy the surface's window as soon as the
- diff --git a/interface/khronos/egl/egl_client_surface.h b/interface/khronos/egl/egl_client_surface.h
- index b5bf70a..e328b77 100644
- --- a/interface/khronos/egl/egl_client_surface.h
- +++ b/interface/khronos/egl/egl_client_surface.h
- @@ -288,6 +288,41 @@ typedef struct {
- type == PIXMAP
- */
- bool server_owned;
- +
- +#ifdef BUILD_WAYLAND
- + /*
- + wl_egl_window
- +
- + Validity:
- + type == WINDOW
- +
- + Invariant:
- + wayland EGL window
- + */
- + struct wl_egl_window *wl_egl_window;
- +
- + /*
- + front_wl_buffer
- +
- + Validity:
- + type == WINDOW
- +
- + Invariant:
- + client-side information about the wl_buffer in the front
- + */
- + struct wl_dispmanx_client_buffer *front_wl_buffer;
- +
- + /*
- + back_wl_buffer
- +
- + Validity:
- + type == WINDOW
- +
- + Invariant:
- + client-side information about the wl_buffer in the back
- + */
- + struct wl_dispmanx_client_buffer *back_wl_buffer;
- +#endif
- } EGL_SURFACE_T;
-
- extern bool egl_surface_check_attribs(
- @@ -322,8 +357,7 @@ extern EGL_SURFACE_T *egl_surface_create(
- EGLenum texture_format,
- EGLenum texture_target,
- EGLNativePixmapType pixmap,
- - const uint32_t *pixmap_server_handle,
- - DISPMANX_RESOURCE_HANDLE_T next_resource_handle);
- + const uint32_t *pixmap_server_handle);
- extern EGL_SURFACE_T *egl_surface_from_vg_image(
- VGImage vg_handle,
- EGLSurface name,
- diff --git a/interface/khronos/egl/egl_int_impl.h b/interface/khronos/egl/egl_int_impl.h
- index 51b3580..6863a3b 100644
- --- a/interface/khronos/egl/egl_int_impl.h
- +++ b/interface/khronos/egl/egl_int_impl.h
- @@ -57,7 +57,7 @@ FN(int, eglIntCreateSurface_impl, (
- uint32_t sem,
- uint32_t type,
- uint32_t *results,
- - DISPMANX_RESOURCE_HANDLE_T next_resource_handle))
- + DISPMANX_RESOURCE_HANDLE_T resource_handle))
-
- FN(int, eglIntCreatePbufferFromVGImage_impl, (
- VGImage vg_handle,
- diff --git a/interface/khronos/ext/egl_wayland.c b/interface/khronos/ext/egl_wayland.c
- new file mode 100644
- index 0000000..5730743
- --- /dev/null
- +++ b/interface/khronos/ext/egl_wayland.c
- @@ -0,0 +1,246 @@
- +/*
- +Copyright (c) 2013, Raspberry Pi Foundation
- +All rights reserved.
- +
- +Redistribution and use in source and binary forms, with or without
- +modification, are permitted provided that the following conditions are met:
- + * Redistributions of source code must retain the above copyright
- + notice, this list of conditions and the following disclaimer.
- + * Redistributions in binary form must reproduce the above copyright
- + notice, this list of conditions and the following disclaimer in the
- + documentation and/or other materials provided with the distribution.
- + * Neither the name of the copyright holder nor the
- + names of its contributors may be used to endorse or promote products
- + derived from this software without specific prior written permission.
- +
- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +*/
- +
- +#include "interface/khronos/common/khrn_client_mangle.h"
- +#include "interface/khronos/common/khrn_client_rpc.h"
- +
- +#include "interface/khronos/ext/egl_khr_sync_client.h"
- +#include "interface/khronos/include/EGL/egl.h"
- +#include "interface/khronos/include/EGL/eglext.h"
- +
- +#include "interface/vmcs_host/vc_vchi_dispmanx.h"
- +
- +#include <wayland-server.h>
- +#include "interface/khronos/wayland-dispmanx-server-protocol.h"
- +
- +static void
- +destroy_buffer(struct wl_resource *resource)
- +{
- + struct wl_dispmanx_server_buffer *buffer = wl_resource_get_user_data(resource);
- +
- + if(!buffer->in_use)
- + vc_dispmanx_resource_delete(buffer->handle);
- +
- + free(buffer);
- +}
- +
- +static void
- +buffer_destroy(struct wl_client *client, struct wl_resource *resource)
- +{
- + wl_resource_destroy(resource);
- +}
- +
- +static const struct wl_buffer_interface dispmanx_buffer_interface = {
- + buffer_destroy
- +};
- +
- +static VC_IMAGE_TYPE_T
- +get_vc_format(enum wl_dispmanx_format format)
- +{
- + /* XXX: The app is likely to have been premultiplying in its shaders,
- + * but the VC scanout hardware on the RPi cannot mix premultiplied alpha
- + * channel with the element's alpha.
- + */
- + switch (format) {
- + case WL_DISPMANX_FORMAT_ABGR8888:
- + return VC_IMAGE_RGBA32;
- + case WL_DISPMANX_FORMAT_XBGR8888:
- + return VC_IMAGE_BGRX8888;
- + case WL_DISPMANX_FORMAT_RGB565:
- + return VC_IMAGE_RGB565;
- + default:
- + /* invalid format */
- + return VC_IMAGE_MIN;
- + }
- +}
- +
- +static void
- +dispmanx_create_buffer(struct wl_client *client, struct wl_resource *resource,
- + uint32_t id, int32_t width, int32_t height,
- + uint32_t stride, uint32_t buffer_height, uint32_t format)
- +{
- + struct wl_dispmanx_server_buffer *buffer;
- + VC_IMAGE_TYPE_T vc_format = get_vc_format(format);
- + uint32_t dummy;
- +
- + if(vc_format == VC_IMAGE_MIN) {
- + wl_resource_post_error(resource,
- + WL_DISPMANX_ERROR_INVALID_FORMAT,
- + "invalid format");
- + return;
- + }
- +
- + buffer = calloc(1, sizeof *buffer);
- + if (buffer == NULL) {
- + wl_resource_post_no_memory(resource);
- + return;
- + }
- +
- + buffer->handle = vc_dispmanx_resource_create(vc_format,
- + width | (stride << 16),
- + height | (buffer_height << 16),
- + &dummy);
- + if(buffer->handle == DISPMANX_NO_HANDLE) {
- + wl_resource_post_error(resource,
- + WL_DISPMANX_ERROR_ALLOC_FAILED,
- + "allocation failed");
- + free(buffer);
- + return;
- + }
- +
- + buffer->width = width;
- + buffer->height = height;
- + buffer->format = format;
- +
- + buffer->resource = wl_resource_create(resource->client, &wl_buffer_interface,
- + 1, id);
- + if (!buffer->resource) {
- + wl_resource_post_no_memory(resource);
- + vc_dispmanx_resource_delete(buffer->handle);
- + free(buffer);
- + return;
- + }
- +
- + wl_resource_set_implementation(buffer->resource,
- + (void (**)(void)) &dispmanx_buffer_interface,
- + buffer, destroy_buffer);
- +
- + wl_dispmanx_send_buffer_allocated(resource, buffer->resource,
- + buffer->handle);
- +}
- +
- +static const struct wl_dispmanx_interface dispmanx_interface = {
- + dispmanx_create_buffer,
- +};
- +
- +static void
- +bind_dispmanx(struct wl_client *client, void *data, uint32_t version, uint32_t id)
- +{
- + struct wl_resource *resource;
- +
- + resource = wl_resource_create(client, &wl_dispmanx_interface, 1, id);
- + wl_resource_set_implementation(resource, &dispmanx_interface, NULL, NULL);
- +
- + wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
- + WL_DISPMANX_FORMAT_ARGB8888);
- +
- + wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
- + WL_DISPMANX_FORMAT_XRGB8888);
- +
- + wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
- + WL_DISPMANX_FORMAT_ABGR8888);
- +
- + wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
- + WL_DISPMANX_FORMAT_XBGR8888);
- +
- + wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
- + WL_DISPMANX_FORMAT_RGB565);
- +}
- +
- +EGLBoolean EGLAPIENTRY
- +eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
- +{
- + CLIENT_THREAD_STATE_T *thread;
- + CLIENT_PROCESS_STATE_T *process;
- +
- + if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
- + return EGL_FALSE;
- +
- + if (process->wl_global != NULL)
- + goto error;
- +
- + process->wl_global = wl_global_create(display, &wl_dispmanx_interface, 1,
- + NULL, bind_dispmanx);
- + if (process->wl_global == NULL)
- + goto error;
- +
- + return EGL_TRUE;
- +
- +error:
- + CLIENT_UNLOCK();
- + return EGL_FALSE;
- +}
- +
- +EGLBoolean EGLAPIENTRY
- +eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
- +{
- + CLIENT_THREAD_STATE_T *thread;
- + CLIENT_PROCESS_STATE_T *process;
- +
- + if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
- + return EGL_FALSE;
- +
- + wl_global_destroy(process->wl_global);
- + process->wl_global = NULL;
- +
- + CLIENT_UNLOCK();
- +
- + return EGL_TRUE;
- +}
- +
- +static int
- +get_egl_format(enum wl_dispmanx_format format)
- +{
- + switch (format) {
- + case WL_DISPMANX_FORMAT_ABGR8888:
- + return EGL_TEXTURE_RGBA;
- + case WL_DISPMANX_FORMAT_XBGR8888:
- + return EGL_TEXTURE_RGB;
- + case WL_DISPMANX_FORMAT_RGB565:
- + return EGL_TEXTURE_RGB;
- + default:
- + /* invalid format */
- + return EGL_NO_TEXTURE;
- + }
- +}
- +
- +EGLBoolean EGLAPIENTRY
- +eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *_buffer,
- + EGLint attribute, EGLint *value)
- +{
- + struct wl_dispmanx_server_buffer *buffer = wl_resource_get_user_data(_buffer);
- +
- + if (wl_resource_instance_of(_buffer, &wl_dispmanx_interface,
- + &dispmanx_buffer_interface))
- + return EGL_FALSE;
- +
- + switch (attribute) {
- + case EGL_TEXTURE_FORMAT:
- + *value = get_egl_format(buffer->format);
- + if (*value == EGL_NO_TEXTURE)
- + return EGL_FALSE;
- + return EGL_TRUE;
- + case EGL_WIDTH:
- + *value = buffer->width;
- + return EGL_TRUE;
- + case EGL_HEIGHT:
- + *value = buffer->height;
- + return EGL_TRUE;
- + }
- +
- + return EGL_FALSE;
- +}
- diff --git a/interface/khronos/include/EGL/eglext.h b/interface/khronos/include/EGL/eglext.h
- index 89a3369..d7e5ba7 100755
- --- a/interface/khronos/include/EGL/eglext.h
- +++ b/interface/khronos/include/EGL/eglext.h
- @@ -191,6 +191,29 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EG
- #endif
-
-
- +#ifndef EGL_WL_bind_wayland_display
- +#define EGL_WL_bind_wayland_display 1
- +
- +#define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */
- +#define EGL_WAYLAND_PLANE_WL 0x31D6 /* eglCreateImageKHR target */
- +#define EGL_TEXTURE_Y_U_V_WL 0x31D7
- +#define EGL_TEXTURE_Y_UV_WL 0x31D8
- +#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
- +
- +struct wl_display;
- +struct wl_resource;
- +#ifdef EGL_EGLEXT_PROTOTYPES
- +EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
- +EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
- +EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
- +#endif
- +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
- +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
- +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
- +
- +#endif
- +
- +
- #ifdef __cplusplus
- }
- #endif
- diff --git a/interface/khronos/wayland-egl/wayland-egl-priv.h b/interface/khronos/wayland-egl/wayland-egl-priv.h
- new file mode 100644
- index 0000000..8e38d36
- --- /dev/null
- +++ b/interface/khronos/wayland-egl/wayland-egl-priv.h
- @@ -0,0 +1,53 @@
- +/* Copied from Mesa */
- +
- +#ifndef _WAYLAND_EGL_PRIV_H
- +#define _WAYLAND_EGL_PRIV_H
- +
- +#ifdef __cplusplus
- +extern "C" {
- +#endif
- +
- +/* GCC visibility */
- +#if defined(__GNUC__) && __GNUC__ >= 4
- +#define WL_EGL_EXPORT __attribute__ ((visibility("default")))
- +#else
- +#define WL_EGL_EXPORT
- +#endif
- +
- +#include "interface/vmcs_host/vc_dispmanx.h"
- +#include "interface/khronos/egl/egl_client_surface.h"
- +
- +#include <wayland-client.h>
- +
- +struct wl_dispmanx_client_buffer {
- + struct wl_buffer *wl_buffer;
- + DISPMANX_RESOURCE_HANDLE_T resource;
- +
- + int pending_allocation;
- + int in_use;
- + int width;
- + int height;
- +};
- +
- +struct wl_egl_window {
- + struct wl_surface *wl_surface;
- +
- + int width;
- + int height;
- + int dx;
- + int dy;
- +
- + int attached_width;
- + int attached_height;
- +
- + /* XXX: The VC side seems to expect a valid element handle to be
- + passed to eglIntCreateSurface_impl and/or eglIntSwapBuffers_impl,
- + even for host-managed surfaces. */
- + DISPMANX_ELEMENT_HANDLE_T dummy_element;
- +};
- +
- +#ifdef __cplusplus
- +}
- +#endif
- +
- +#endif
- diff --git a/interface/khronos/wayland-egl/wayland-egl.c b/interface/khronos/wayland-egl/wayland-egl.c
- new file mode 100644
- index 0000000..b8f050b
- --- /dev/null
- +++ b/interface/khronos/wayland-egl/wayland-egl.c
- @@ -0,0 +1,59 @@
- +/* Copied from Mesa */
- +
- +#include <stdlib.h>
- +
- +#include <wayland-client.h>
- +#include <wayland-egl.h>
- +#include "wayland-egl-priv.h"
- +
- +WL_EGL_EXPORT void
- +wl_egl_window_resize(struct wl_egl_window *egl_window,
- + int width, int height,
- + int dx, int dy)
- +{
- + if (egl_window->width == width &&
- + egl_window->height == height &&
- + egl_window->dx == dx &&
- + egl_window->dy == dy)
- + return;
- +
- + egl_window->width = width;
- + egl_window->height = height;
- + egl_window->dx = dx;
- + egl_window->dy = dy;
- +}
- +
- +WL_EGL_EXPORT struct wl_egl_window *
- +wl_egl_window_create(struct wl_surface *surface,
- + int width, int height)
- +{
- + struct wl_egl_window *egl_window;
- +
- + egl_window = calloc(1, sizeof *egl_window);
- + if (!egl_window)
- + return NULL;
- +
- + egl_window->wl_surface = surface;
- + wl_egl_window_resize(egl_window, width, height, 0, 0);
- + egl_window->attached_width = 0;
- + egl_window->attached_height = 0;
- + egl_window->dummy_element = PLATFORM_WIN_NONE;
- +
- + return egl_window;
- +}
- +
- +WL_EGL_EXPORT void
- +wl_egl_window_destroy(struct wl_egl_window *egl_window)
- +{
- + free(egl_window);
- +}
- +
- +WL_EGL_EXPORT void
- +wl_egl_window_get_attached_size(struct wl_egl_window *egl_window,
- + int *width, int *height)
- +{
- + if (width)
- + *width = egl_window->attached_width;
- + if (height)
- + *height = egl_window->attached_height;
- +}
- diff --git a/interface/khronos/wayland-egl/wayland-egl.pc.in b/interface/khronos/wayland-egl/wayland-egl.pc.in
- new file mode 100644
- index 0000000..8bafc15
- --- /dev/null
- +++ b/interface/khronos/wayland-egl/wayland-egl.pc.in
- @@ -0,0 +1,10 @@
- +prefix=@CMAKE_INSTALL_PREFIX@
- +exec_prefix=${prefix}
- +libdir=${exec_prefix}/lib
- +includedir=${prefix}/include
- +
- +Name: wayland-egl
- +Description: VideoCore wayland-egl library
- +Version: @PROJECT_APIVER@
- +Libs: -L${libdir} -lwayland-egl
- +Cflags: -I${includedir}
- diff --git a/interface/vmcs_host/CMakeLists.txt b/interface/vmcs_host/CMakeLists.txt
- index cbef80c..552312a 100755
- --- a/interface/vmcs_host/CMakeLists.txt
- +++ b/interface/vmcs_host/CMakeLists.txt
- @@ -7,13 +7,24 @@
- # vc_vchi_gencmd.c has a type-punning problem in vc_gencmd_read_response
- add_definitions(-fno-strict-aliasing)
-
- -add_library(vchostif
- +set(VCHOSTIF_SOURCE
- ${VMCS_TARGET}/vcmisc.c
- vc_vchi_gencmd.c vc_vchi_gpuserv.c
- vc_vchi_tvservice.c vc_vchi_cecservice.c
- vc_vchi_dispmanx.c vc_service_common.c)
- # ${VMCS_TARGET}/vmcs_main.c
- # vc_vchi_haud.c
- +
- +if (BUILD_WAYLAND)
- +wayland_add_protocol_server(
- + VCHOSTIF_SOURCE
- + ../../interface/wayland/dispmanx.xml
- + dispmanx
- +)
- +endif ()
- +
- +add_library(vchostif ${VCHOSTIF_SOURCE})
- +
- #add_library(bufman vc_vchi_bufman.c )
- set(INSTALL_TARGETS vchostif)
-
- diff --git a/interface/vmcs_host/vc_dispmanx.h b/interface/vmcs_host/vc_dispmanx.h
- index 37fdae1..fe3619a 100755
- --- a/interface/vmcs_host/vc_dispmanx.h
- +++ b/interface/vmcs_host/vc_dispmanx.h
- @@ -39,6 +39,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #ifdef __cplusplus
- extern "C" {
- #endif
- +
- +#ifdef BUILD_WAYLAND
- +struct wl_resource;
- +#endif
- +
- // Same function as above, to aid migration of code.
- VCHPRE_ int VCHPOST_ vc_dispman_init( void );
- // Stop the service from being used
- @@ -135,6 +140,11 @@ VCHPRE_ int VCHPOST_ vc_dispmanx_resource_set_palette( DISPMANX_RESOURCE_HANDLE_
- // Start triggering callbacks synced to vsync
- VCHPRE_ int VCHPOST_ vc_dispmanx_vsync_callback( DISPMANX_DISPLAY_HANDLE_T display, DISPMANX_CALLBACK_FUNC_T cb_func, void *cb_arg );
-
- +#ifdef BUILD_WAYLAND
- +VCHPRE_ DISPMANX_RESOURCE_HANDLE_T VCHPOST_ vc_dispmanx_get_handle_from_wl_buffer( struct wl_resource *_buffer );
- +
- +VCHPRE_ void VCHPOST_ vc_dispmanx_set_wl_buffer_in_use( struct wl_resource *_buffer, int in_use );
- +#endif
- #ifdef __cplusplus
- }
- #endif
- diff --git a/interface/vmcs_host/vc_vchi_dispmanx.c b/interface/vmcs_host/vc_vchi_dispmanx.c
- index 7a6cdcd..eab146e 100755
- --- a/interface/vmcs_host/vc_vchi_dispmanx.c
- +++ b/interface/vmcs_host/vc_vchi_dispmanx.c
- @@ -1319,3 +1319,45 @@ static void *dispmanx_notify_func( void *arg ) {
- }
- return 0;
- }
- +
- +
- +#ifdef BUILD_WAYLAND
- +/***********************************************************
- + * Name: vc_dispmanx_get_handle_from_wl_buffer
- + *
- + * Arguments:
- + * struct wl_resource *_buffer
- + *
- + * Description: Return the handle of the resource associated to this Wayland buffer
- + *
- + * Returns: A resource handle
- + *
- + ***********************************************************/
- +VCHPRE_ DISPMANX_RESOURCE_HANDLE_T VCHPOST_ vc_dispmanx_get_handle_from_wl_buffer( struct wl_resource *_buffer )
- +{
- + struct wl_dispmanx_server_buffer *buffer = (struct wl_dispmanx_server_buffer*)_buffer->data;
- + if (!buffer)
- + return DISPMANX_NO_HANDLE;
- +
- + return buffer->handle;
- +}
- +
- +/***********************************************************
- + * Name: vc_dispmanx_set_wl_buffer_in_use
- + *
- + * Arguments:
- + * struct wl_resource *_buffer
- + * int in_use
- + *
- + * Description: Mark this Wayland buffer as being in use by the compositor
- + *
- + ***********************************************************/
- +VCHPRE_ void VCHPOST_ vc_dispmanx_set_wl_buffer_in_use( struct wl_resource *_buffer, int in_use )
- +{
- + struct wl_dispmanx_server_buffer *buffer = (struct wl_dispmanx_server_buffer*)_buffer->data;
- + if (!buffer)
- + return;
- +
- + buffer->in_use = in_use;
- +}
- +#endif
- diff --git a/interface/vmcs_host/vc_vchi_dispmanx.h b/interface/vmcs_host/vc_vchi_dispmanx.h
- index b723b76..f0bae30 100644
- --- a/interface/vmcs_host/vc_vchi_dispmanx.h
- +++ b/interface/vmcs_host/vc_vchi_dispmanx.h
- @@ -66,4 +66,19 @@ typedef struct {
- #define ELEMENT_CHANGE_MASK_RESOURCE (1<<4)
- #define ELEMENT_CHANGE_TRANSFORM (1<<5)
-
- +#ifdef BUILD_WAYLAND
- +/* XXX: This should be in a private header that can be included from EGL and vc_* */
- +#include <wayland-server.h>
- +#include "interface/vmcs_host/wayland-dispmanx-server-protocol.h"
- +struct wl_dispmanx_server_buffer {
- + struct wl_resource *resource;
- + struct wl_dispmanx *dispmanx;
- + enum wl_dispmanx_format format;
- + DISPMANX_RESOURCE_HANDLE_T handle;
- + int32_t width;
- + int32_t height;
- + int in_use;
- +};
- +#endif
- +
- #endif
- diff --git a/interface/wayland/dispmanx.xml b/interface/wayland/dispmanx.xml
- new file mode 100644
- index 0000000..c18626d
- --- /dev/null
- +++ b/interface/wayland/dispmanx.xml
- @@ -0,0 +1,123 @@
- +<?xml version="1.0" encoding="UTF-8"?>
- +<protocol name="dispmanx">
- +
- + <copyright>
- + Copyright © 2008-2011 Kristian Høgsberg
- + Copyright © 2010-2011 Intel Corporation
- + Copyright © 2013 Raspberry Pi Foundation
- +
- + Permission to use, copy, modify, distribute, and sell this
- + software and its documentation for any purpose is hereby granted
- + without fee, provided that\n the above copyright notice appear in
- + all copies and that both that copyright notice and this permission
- + notice appear in supporting documentation, and that the name of
- + the copyright holders not be used in advertising or publicity
- + pertaining to distribution of the software without specific,
- + written prior permission. The copyright holders make no
- + representations about the suitability of this software for any
- + purpose. It is provided "as is" without express or implied
- + warranty.
- +
- + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
- + THIS SOFTWARE.
- + </copyright>
- +
- + <!-- DispManX support. This object is created by the server and published
- + using the display's global event. -->
- + <interface name="wl_dispmanx" version="1">
- + <enum name="error">
- + <entry name="alloc_failed" value="0"/>
- + <entry name="invalid_format" value="1"/>
- + </enum>
- +
- + <enum name="format">
- + <!-- The pixel format codes match the #defines in drm_fourcc.h.
- + The formats actually supported by the compositor will be
- + reported by the format event. -->
- + <entry name="c8" value="0x20203843"/>
- + <entry name="rgb332" value="0x38424752"/>
- + <entry name="bgr233" value="0x38524742"/>
- + <entry name="xrgb4444" value="0x32315258"/>
- + <entry name="xbgr4444" value="0x32314258"/>
- + <entry name="rgbx4444" value="0x32315852"/>
- + <entry name="bgrx4444" value="0x32315842"/>
- + <entry name="argb4444" value="0x32315241"/>
- + <entry name="abgr4444" value="0x32314241"/>
- + <entry name="rgba4444" value="0x32314152"/>
- + <entry name="bgra4444" value="0x32314142"/>
- + <entry name="xrgb1555" value="0x35315258"/>
- + <entry name="xbgr1555" value="0x35314258"/>
- + <entry name="rgbx5551" value="0x35315852"/>
- + <entry name="bgrx5551" value="0x35315842"/>
- + <entry name="argb1555" value="0x35315241"/>
- + <entry name="abgr1555" value="0x35314241"/>
- + <entry name="rgba5551" value="0x35314152"/>
- + <entry name="bgra5551" value="0x35314142"/>
- + <entry name="rgb565" value="0x36314752"/>
- + <entry name="bgr565" value="0x36314742"/>
- + <entry name="rgb888" value="0x34324752"/>
- + <entry name="bgr888" value="0x34324742"/>
- + <entry name="xrgb8888" value="0x34325258"/>
- + <entry name="xbgr8888" value="0x34324258"/>
- + <entry name="rgbx8888" value="0x34325852"/>
- + <entry name="bgrx8888" value="0x34325842"/>
- + <entry name="argb8888" value="0x34325241"/>
- + <entry name="abgr8888" value="0x34324241"/>
- + <entry name="rgba8888" value="0x34324152"/>
- + <entry name="bgra8888" value="0x34324142"/>
- + <entry name="xrgb2101010" value="0x30335258"/>
- + <entry name="xbgr2101010" value="0x30334258"/>
- + <entry name="rgbx1010102" value="0x30335852"/>
- + <entry name="bgrx1010102" value="0x30335842"/>
- + <entry name="argb2101010" value="0x30335241"/>
- + <entry name="abgr2101010" value="0x30334241"/>
- + <entry name="rgba1010102" value="0x30334152"/>
- + <entry name="bgra1010102" value="0x30334142"/>
- + <entry name="yuyv" value="0x56595559"/>
- + <entry name="yvyu" value="0x55595659"/>
- + <entry name="uyvy" value="0x59565955"/>
- + <entry name="vyuy" value="0x59555956"/>
- + <entry name="ayuv" value="0x56555941"/>
- + <entry name="nv12" value="0x3231564e"/>
- + <entry name="nv21" value="0x3132564e"/>
- + <entry name="nv16" value="0x3631564e"/>
- + <entry name="nv61" value="0x3136564e"/>
- + <entry name="yuv410" value="0x39565559"/>
- + <entry name="yvu410" value="0x39555659"/>
- + <entry name="yuv411" value="0x31315559"/>
- + <entry name="yvu411" value="0x31315659"/>
- + <entry name="yuv420" value="0x32315559"/>
- + <entry name="yvu420" value="0x32315659"/>
- + <entry name="yuv422" value="0x36315559"/>
- + <entry name="yvu422" value="0x36315659"/>
- + <entry name="yuv444" value="0x34325559"/>
- + <entry name="yvu444" value="0x34325659"/>
- + </enum>
- +
- + <event name="format">
- + <arg name="format" type="uint"/>
- + </event>
- +
- + <!-- Create a wayland buffer for the DispManX resource. -->
- + <request name="create_buffer">
- + <arg name="id" type="new_id" interface="wl_buffer"/>
- + <arg name="width" type="int"/>
- + <arg name="height" type="int"/>
- + <arg name="stride" type="uint"/>
- + <arg name="buffer_height" type="uint"/>
- + <arg name="format" type="uint"/>
- + </request>
- +
- + <event name="buffer_allocated">
- + <arg name="buffer" type="object" interface="wl_buffer"/>
- + <arg name="handle" type="uint"/>
- + </event>
- + </interface>
- +
- +</protocol>
- diff --git a/makefiles/cmake/Wayland.cmake b/makefiles/cmake/Wayland.cmake
- new file mode 100644
- index 0000000..ad90d30
- --- /dev/null
- +++ b/makefiles/cmake/Wayland.cmake
- @@ -0,0 +1,72 @@
- +#=============================================================================
- +# Copyright (C) 2012-2013 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
- +# All rights reserved.
- +#
- +# Redistribution and use in source and binary forms, with or without
- +# modification, are permitted provided that the following conditions
- +# are met:
- +#
- +# * Redistributions of source code must retain the above copyright
- +# notice, this list of conditions and the following disclaimer.
- +#
- +# * Redistributions in binary form must reproduce the above copyright
- +# notice, this list of conditions and the following disclaimer in the
- +# documentation and/or other materials provided with the distribution.
- +#
- +# * Neither the name of Pier Luigi Fiorini nor the names of his
- +# contributors may be used to endorse or promote products derived
- +# from this software without specific prior written permission.
- +#
- +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- +#=============================================================================
- +
- +find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
- +
- +# wayland_add_protocol_client(outfiles inputfile basename)
- +function(WAYLAND_ADD_PROTOCOL_CLIENT _sources _protocol _basename)
- + if(NOT WAYLAND_SCANNER_EXECUTABLE)
- + message(FATAL "The wayland-scanner executable has nto been found on your system. You must install it.")
- + endif()
- +
- + get_filename_component(_infile ${_protocol} ABSOLUTE)
- + set(_client_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-client-protocol.h")
- + set(_code "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-protocol.c")
- +
- + add_custom_command(OUTPUT "${_client_header}"
- + COMMAND ${WAYLAND_SCANNER_EXECUTABLE} client-header < ${_infile} > ${_client_header}
- + DEPENDS ${_infile} VERBATIM)
- +
- + add_custom_command(OUTPUT "${_code}"
- + COMMAND ${WAYLAND_SCANNER_EXECUTABLE} code < ${_infile} > ${_code}
- + DEPENDS ${_infile} VERBATIM)
- +
- + list(APPEND ${_sources} "${_client_header}" "${_code}")
- + set(${_sources} ${${_sources}} PARENT_SCOPE)
- +endfunction()
- +
- +# wayland_add_protocol_server(outfiles inputfile basename)
- +function(WAYLAND_ADD_PROTOCOL_SERVER _sources _protocol _basename)
- + if(NOT WAYLAND_SCANNER_EXECUTABLE)
- + message(FATAL "The wayland-scanner executable has nto been found on your system. You must install it.")
- + endif()
- +
- + get_filename_component(_infile ${_protocol} ABSOLUTE)
- + set(_server_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-server-protocol.h")
- +
- + add_custom_command(OUTPUT "${_server_header}"
- + COMMAND ${WAYLAND_SCANNER_EXECUTABLE} server-header < ${_infile} > ${_server_header}
- + DEPENDS ${_infile} VERBATIM)
- +
- + list(APPEND ${_sources} "${_server_header}")
- + set(${_sources} ${${_sources}} PARENT_SCOPE)
- +endfunction()
|