12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898 |
- From 75eb8ab4bec3e462607214d2e14c9f2eef73435f 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 02/21] 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>
- ---
- .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 | 21 +-
- 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, 1257 insertions(+), 99 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 4a914a7..c202204 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
- - ${VMCS_TARGET}/vcfilesys.c ${VMCS_TARGET}/vcmisc.c
- - vc_vchi_gencmd.c vc_vchi_filesys.c vc_vchi_gpuserv.c
- - vc_vchi_tvservice.c vc_vchi_cecservice.c
- - vc_vchi_dispmanx.c vc_service_common.c)
- +set(VCHOSTIF_SOURCE
- + ${VMCS_TARGET}/vcfilesys.c ${VMCS_TARGET}/vcmisc.c
- + vc_vchi_gencmd.c vc_vchi_filesys.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()
- --
- 2.27.0
|