diff options
Diffstat (limited to 'import-layers/meta-raspberrypi/recipes-graphics/userland/userland')
16 files changed, 0 insertions, 3641 deletions
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0001-Allow-applications-to-set-next-resource-handle.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0001-Allow-applications-to-set-next-resource-handle.patch deleted file mode 100644 index 933f279af..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0001-Allow-applications-to-set-next-resource-handle.patch +++ /dev/null @@ -1,208 +0,0 @@ -From 0a64dc61d3d7db69389157ae757203b4b3afdbfa Mon Sep 17 00:00:00 2001 -From: Dom Cobley <dc4@broadcom.com> -Date: Tue, 9 Jul 2013 09:26:26 -0400 -Subject: [PATCH 01/16] Allow applications to set next resource handle - -This patch adds provisions in userland to -let apps callers set the next rendereing dispmanx resource. -It's useful for implementing, say, a buffer carousel. ---- - interface/khronos/common/khrn_client_rpc.h | 2 ++ - interface/khronos/common/khrn_int_ids.h | 2 ++ - interface/khronos/egl/egl_client.c | 30 +++++++++++++++++++++++++++--- - interface/khronos/egl/egl_client_surface.c | 24 +++++++++++++++++++++++- - interface/khronos/egl/egl_client_surface.h | 3 ++- - interface/khronos/egl/egl_int_impl.h | 5 +++-- - 6 files changed, 59 insertions(+), 7 deletions(-) - -diff --git a/interface/khronos/common/khrn_client_rpc.h b/interface/khronos/common/khrn_client_rpc.h -index dc4351d..10ea060 100644 ---- a/interface/khronos/common/khrn_client_rpc.h -+++ b/interface/khronos/common/khrn_client_rpc.h -@@ -685,6 +685,7 @@ static INLINE void rpc_call12_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id - static INLINE void rpc_call13_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); } - static INLINE void rpc_call14_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, uint32_t p12, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); } - static INLINE void rpc_call15_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, uint32_t p12, uint32_t p13, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); } -+static INLINE void rpc_call16_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, uint32_t p12, uint32_t p13, uint32_t p14, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); } - #endif - - #define RPC_CALL1_OUT_CTRL(fn, thread, id, out) rpc_call1_out_ctrl(thread, id, out) -@@ -702,6 +703,7 @@ static INLINE void rpc_call15_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id - #define RPC_CALL13_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, out) rpc_call13_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, out) - #define RPC_CALL14_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, out) rpc_call14_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, out) - #define RPC_CALL15_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, out) rpc_call15_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, out) -+#define RPC_CALL16_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, out) rpc_call16_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, out) - - # if !defined(__SYMBIAN32__) //use functions defined in khrpc.cpp - static INLINE uint32_t rpc_call1_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, void *out) { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id); res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; } -diff --git a/interface/khronos/common/khrn_int_ids.h b/interface/khronos/common/khrn_int_ids.h -index 8378f4a..ec961e0 100644 ---- a/interface/khronos/common/khrn_int_ids.h -+++ b/interface/khronos/common/khrn_int_ids.h -@@ -367,6 +367,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - #define EGLINTCREATESURFACE_ID 0x4000 -+#define EGLINTCREATESURFACE_ID_V2 0x4100 - #define EGLINTCREATEGLES11_ID 0x4001 - #define EGLINTCREATEGLES20_ID 0x4002 - #define EGLINTCREATEVG_ID 0x4003 -@@ -377,6 +378,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #define EGLINTMAKECURRENT_ID 0x4008 - #define EGLINTFLUSHANDWAIT_ID 0x4009 - #define EGLINTSWAPBUFFERS_ID 0x400a -+#define EGLINTSWAPBUFFERS_ID_V2 0x410a - #define EGLINTSELECTMIPMAP_ID 0x400b - #define EGLINTFLUSH_ID 0x400c - #define EGLINTGETCOLORDATA_ID 0x400d -diff --git a/interface/khronos/egl/egl_client.c b/interface/khronos/egl/egl_client.c -index 9d617c8..b8bb374 100644 ---- a/interface/khronos/egl/egl_client.c -+++ b/interface/khronos/egl/egl_client.c -@@ -162,6 +162,17 @@ 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?) -@@ -644,7 +655,8 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig c - false, - EGL_NO_TEXTURE, - EGL_NO_TEXTURE, -- 0, 0); -+ 0, 0, -+ next_resource_handle); - - if (surface) { - if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) { -@@ -889,7 +901,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)) { -@@ -1031,7 +1043,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); -+ pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle, 0); - - if (surface) { - if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) { -@@ -2303,6 +2315,18 @@ 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 - RPC_CALL6(eglIntSwapBuffers_impl, - thread, - EGLINTSWAPBUFFERS_ID, -diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c -index 6846dfa..128325e 100644 ---- a/interface/khronos/egl/egl_client_surface.c -+++ b/interface/khronos/egl/egl_client_surface.c -@@ -314,7 +314,8 @@ EGL_SURFACE_T *egl_surface_create( - EGLenum texture_format, - EGLenum texture_target, - EGLNativePixmapType pixmap, -- const uint32_t *pixmap_server_handle) -+ const uint32_t *pixmap_server_handle, -+ DISPMANX_RESOURCE_HANDLE_T next_resource_handle) - { - KHRN_IMAGE_FORMAT_T color; - KHRN_IMAGE_FORMAT_T depth; -@@ -473,6 +474,27 @@ EGL_SURFACE_T *egl_surface_create( - #endif - uint32_t results[3]; - -+ if (next_resource_handle) -+ RPC_CALL16_OUT_CTRL(eglIntCreateSurface_impl, -+ thread, -+ EGLINTCREATESURFACE_ID_V2, -+ RPC_UINT(serverwin), -+ RPC_UINT(buffers), -+ RPC_UINT(width), -+ RPC_UINT(height), -+ RPC_UINT(color), -+ RPC_UINT(depth), -+ RPC_UINT(mask), -+ RPC_UINT(multi), -+ RPC_UINT(largest_pbuffer), -+ RPC_UINT(mipmap_texture), -+ RPC_UINT(config_depth_bits), -+ RPC_UINT(config_stencil_bits), -+ RPC_UINT(sem_name), -+ RPC_UINT(type), -+ RPC_INT(next_resource_handle), -+ results); -+ else - RPC_CALL15_OUT_CTRL(eglIntCreateSurface_impl, - thread, - EGLINTCREATESURFACE_ID, -diff --git a/interface/khronos/egl/egl_client_surface.h b/interface/khronos/egl/egl_client_surface.h -index c99d44c..b5bf70a 100644 ---- a/interface/khronos/egl/egl_client_surface.h -+++ b/interface/khronos/egl/egl_client_surface.h -@@ -322,7 +322,8 @@ extern EGL_SURFACE_T *egl_surface_create( - EGLenum texture_format, - EGLenum texture_target, - EGLNativePixmapType pixmap, -- const uint32_t *pixmap_server_handle); -+ const uint32_t *pixmap_server_handle, -+ DISPMANX_RESOURCE_HANDLE_T next_resource_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 8a5734c..51b3580 100644 ---- a/interface/khronos/egl/egl_int_impl.h -+++ b/interface/khronos/egl/egl_int_impl.h -@@ -56,7 +56,8 @@ FN(int, eglIntCreateSurface_impl, ( - uint32_t config_stencil_bits, - uint32_t sem, - uint32_t type, -- uint32_t *results)) -+ uint32_t *results, -+ DISPMANX_RESOURCE_HANDLE_T next_resource_handle)) - - FN(int, eglIntCreatePbufferFromVGImage_impl, ( - VGImage vg_handle, -@@ -110,7 +111,7 @@ FN(void, eglIntMakeCurrent_impl, (uint32_t pid_0, uint32_t pid_1, uint32_t glver - FN(int, eglIntFlushAndWait_impl, (uint32_t flushgl, uint32_t flushvg)) - FN(void, eglIntFlush_impl, (uint32_t flushgl, uint32_t flushvg)) - --FN(void, eglIntSwapBuffers_impl, (EGL_SURFACE_ID_T s, uint32_t width, uint32_t height, uint32_t handle, uint32_t preserve, uint32_t position)) -+FN(void, eglIntSwapBuffers_impl, (EGL_SURFACE_ID_T s, uint32_t width, uint32_t height, uint32_t handle, uint32_t preserve, uint32_t position, DISPMANX_RESOURCE_HANDLE_T new_back_buffer)) - FN(void, eglIntSelectMipmap_impl, (EGL_SURFACE_ID_T s, int level)) - - FN(void, eglIntGetColorData_impl, (EGL_SURFACE_ID_T s, KHRN_IMAGE_FORMAT_T format, uint32_t width, uint32_t height, int32_t stride, uint32_t y_offset, void *data)) --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0002-wayland-Add-support-for-the-Wayland-winsys.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0002-wayland-Add-support-for-the-Wayland-winsys.patch deleted file mode 100644 index 461350407..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0002-wayland-Add-support-for-the-Wayland-winsys.patch +++ /dev/null @@ -1,1861 +0,0 @@ -From 5608ec8002be8370e78c9dbb1e07cee4cfb18b58 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/16] 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 ---- - .gitignore | 1 + - CMakeLists.txt | 11 + - README.md | 4 + - buildme | 10 +- - .../linux/apps/raspicam/CMakeLists.txt | 2 +- - interface/khronos/CMakeLists.txt | 53 ++++- - interface/khronos/common/khrn_client.c | 15 ++ - interface/khronos/common/khrn_client.h | 10 + - interface/khronos/common/khrn_client_mangle.h | 3 + - interface/khronos/common/khrn_client_platform.h | 8 + - interface/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 ++ - interface/khronos/wayland-egl/wayland-egl-priv.h | 53 +++++ - interface/khronos/wayland-egl/wayland-egl.c | 59 +++++ - interface/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(+), 98 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 - -Index: git/.gitignore -=================================================================== ---- git.orig/.gitignore -+++ git/.gitignore -@@ -30,3 +30,4 @@ build/ - *.pts - *.ppm - *.mkv -+*~ -Index: git/CMakeLists.txt -=================================================================== ---- git.orig/CMakeLists.txt -+++ git/CMakeLists.txt -@@ -24,6 +24,17 @@ include(makefiles/cmake/global_settings. - 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 -Index: git/README.md -=================================================================== ---- git.orig/README.md -+++ git/README.md -@@ -6,3 +6,7 @@ Use buildme to build. It requires cmake - https://github.com/raspberrypi/tools/tree/master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian - - Note that this repository does not contain the source for the edid_parser 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. -Index: git/buildme -=================================================================== ---- git.orig/buildme -+++ git/buildme -@@ -8,6 +8,10 @@ fi - - BUILDSUBDIR=`echo $BUILDTYPE | tr '[A-Z]' '[a-z]'`; - -+if [ -n "$BUILD_WAYLAND" ]; then -+ WAYLAND_VARS="-DBUILD_WAYLAND=TRUE" -+fi -+ - if [ "armv6l" = `arch` ] || [ "armv7l" = `arch` ]; then - # Native compile on the Raspberry Pi - mkdir -p build/raspberry/$BUILDSUBDIR -@@ -32,9 +36,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=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=$BUILDTYPE ../../.. -+ cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=$BUILDTYPE $WAYLAND_VARS ../../.. - make -j `nproc` - - if [ "$1" != "" ]; then -Index: git/host_applications/linux/apps/raspicam/CMakeLists.txt -=================================================================== ---- git.orig/host_applications/linux/apps/raspicam/CMakeLists.txt -+++ git/host_applications/linux/apps/raspicam/CMakeLists.txt -@@ -28,7 +28,7 @@ add_executable(raspividyuv ${COMMON_SOU - - set (MMAL_LIBS mmal_core mmal_util mmal_vc_client) - --target_link_libraries(raspistill ${MMAL_LIBS} vcos bcm_host brcmGLESv2 brcmEGL m) -+target_link_libraries(raspistill ${MMAL_LIBS} vcos bcm_host brcmGLESv2 brcmEGL m ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_CLIENT_LIBRARIES}) - target_link_libraries(raspiyuv ${MMAL_LIBS} vcos bcm_host) - target_link_libraries(raspivid ${MMAL_LIBS} vcos bcm_host) - target_link_libraries(raspividyuv ${MMAL_LIBS} vcos bcm_host) -Index: git/interface/khronos/CMakeLists.txt -=================================================================== ---- git.orig/interface/khronos/CMakeLists.txt -+++ git/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_applicat - 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_ - 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) -Index: git/interface/khronos/common/khrn_client.c -=================================================================== ---- git.orig/interface/khronos/common/khrn_client.c -+++ git/interface/khronos/common/khrn_client.c -@@ -54,6 +54,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - #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_PRO - 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_PR - } - #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; - } - -Index: git/interface/khronos/common/khrn_client.h -=================================================================== ---- git.orig/interface/khronos/common/khrn_client.h -+++ git/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); -Index: git/interface/khronos/common/khrn_client_mangle.h -=================================================================== ---- git.orig/interface/khronos/common/khrn_client_mangle.h -+++ git/interface/khronos/common/khrn_client_mangle.h -@@ -83,6 +83,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - #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 */ - -Index: git/interface/khronos/common/khrn_client_platform.h -=================================================================== ---- git.orig/interface/khronos/common/khrn_client_platform.h -+++ git/interface/khronos/common/khrn_client_platform.h -@@ -48,6 +48,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - #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 -Index: git/interface/khronos/common/khrn_client_unmangle.h -=================================================================== ---- git.orig/interface/khronos/common/khrn_client_unmangle.h -+++ git/interface/khronos/common/khrn_client_unmangle.h -@@ -83,6 +83,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - #undef eglReleaseGlobalImageBRCM - #undef eglInitGlobalImageBRCM - #undef eglTermGlobalImageBRCM -+#undef eglBindWaylandDisplayWL -+#undef eglUnbindWaylandDisplayWL -+#undef eglQueryWaylandBufferWL - - /* OpenGL ES 1.1 and 2.0 functions */ - -Index: git/interface/khronos/common/linux/khrn_client_platform_linux.c -=================================================================== ---- git.orig/interface/khronos/common/linux/khrn_client_platform_linux.c -+++ git/interface/khronos/common/linux/khrn_client_platform_linux.c -@@ -37,6 +37,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - #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,14 +469,37 @@ EGLDisplay khrn_platform_set_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 - static void dump_hierarchy(Window w, Window thisw, Window look, int level) -@@ -805,22 +833,81 @@ static EGL_DISPMANX_WINDOW_T *check_defa - 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 -Index: git/interface/khronos/common/linux/khrn_wayland.c -=================================================================== ---- /dev/null -+++ git/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; -+} -Index: git/interface/vmcs_host/vc_vchi_dispmanx.h -=================================================================== ---- git.orig/interface/vmcs_host/vc_vchi_dispmanx.h -+++ git/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 -Index: git/interface/khronos/common/linux/khrn_wayland.h -=================================================================== ---- /dev/null -+++ git/interface/khronos/common/linux/khrn_wayland.h -@@ -0,0 +1,33 @@ -+/* -+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.h" -+ -+int init_process_wayland(CLIENT_PROCESS_STATE_T *process); -+int do_wl_roundtrip(); -+ -+struct wl_dispmanx_client_buffer *allocate_wl_buffer(struct wl_egl_window *window, KHRN_IMAGE_FORMAT_T color); -Index: git/interface/khronos/egl/egl_client.c -=================================================================== ---- git.orig/interface/khronos/egl/egl_client.c -+++ git/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_P - 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?) -@@ -451,6 +444,9 @@ EGLAPI const char EGLAPIENTRY * eglQuery - "EGL_KHR_fence_sync " - #endif - #endif -+#if EGL_WL_bind_wayland_display -+ "EGL_WL_bind_wayland_display " -+#endif - ; - break; - case EGL_VENDOR: -@@ -655,8 +651,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateW - 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 eglCreateP - 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 eglCreateP - 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 eglSwapBuf - 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 eglSwapBuf - - 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, -Index: git/interface/khronos/egl/egl_client_get_proc.c -=================================================================== ---- git.orig/interface/khronos/egl/egl_client_get_proc.c -+++ git/interface/khronos/egl/egl_client_get_proc.c -@@ -254,6 +254,17 @@ EGLAPI void EGLAPIENTRY (* eglGetProcAdd - 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; - } - -Index: git/interface/khronos/egl/egl_client_surface.c -=================================================================== ---- git.orig/interface/khronos/egl/egl_client_surface.c -+++ git/interface/khronos/egl/egl_client_surface.c -@@ -46,6 +46,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - #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 *sur - 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 -Index: git/interface/khronos/egl/egl_client_surface.h -=================================================================== ---- git.orig/interface/khronos/egl/egl_client_surface.h -+++ git/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, -Index: git/interface/khronos/egl/egl_int_impl.h -=================================================================== ---- git.orig/interface/khronos/egl/egl_int_impl.h -+++ git/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, -Index: git/interface/khronos/ext/egl_wayland.c -=================================================================== ---- /dev/null -+++ git/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; -+} -Index: git/interface/khronos/include/EGL/eglext.h -=================================================================== ---- git.orig/interface/khronos/include/EGL/eglext.h -+++ git/interface/khronos/include/EGL/eglext.h -@@ -191,6 +191,29 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLG - #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 -Index: git/interface/khronos/wayland-egl/wayland-egl-priv.h -=================================================================== ---- /dev/null -+++ git/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 -Index: git/interface/khronos/wayland-egl/wayland-egl.c -=================================================================== ---- /dev/null -+++ git/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; -+} -Index: git/interface/khronos/wayland-egl/wayland-egl.pc.in -=================================================================== ---- /dev/null -+++ git/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} -Index: git/interface/vmcs_host/CMakeLists.txt -=================================================================== ---- git.orig/interface/vmcs_host/CMakeLists.txt -+++ git/interface/vmcs_host/CMakeLists.txt -@@ -9,13 +9,24 @@ add_definitions(-fno-strict-aliasing) - - include_directories(${VMCS_TARGET}/vcfiled) - --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 ) - - # OpenMAX/IL component service -Index: git/interface/vmcs_host/vc_dispmanx.h -=================================================================== ---- git.orig/interface/vmcs_host/vc_dispmanx.h -+++ git/interface/vmcs_host/vc_dispmanx.h -@@ -39,6 +39,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - #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_resourc - // 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 -Index: git/interface/vmcs_host/vc_vchi_dispmanx.c -=================================================================== ---- git.orig/interface/vmcs_host/vc_vchi_dispmanx.c -+++ git/interface/vmcs_host/vc_vchi_dispmanx.c -@@ -1319,3 +1319,45 @@ static void *dispmanx_notify_func( void - } - 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 -Index: git/interface/wayland/dispmanx.xml -=================================================================== ---- /dev/null -+++ git/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> -Index: git/makefiles/cmake/Wayland.cmake -=================================================================== ---- /dev/null -+++ git/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() diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0003-wayland-Add-Wayland-example.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0003-wayland-Add-Wayland-example.patch deleted file mode 100644 index e3a0cf277..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0003-wayland-Add-Wayland-example.patch +++ /dev/null @@ -1,866 +0,0 @@ -From 20ac7c6af4e826b5c536b6a7c8b2d1d266ced81e 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 03/16] wayland: Add Wayland example - ---- - .../linux/apps/hello_pi/CMakeLists.txt | 1 + - .../apps/hello_pi/hello_wayland/CMakeLists.txt | 8 + - .../apps/hello_pi/hello_wayland/Djenne_128_128.raw | 3 + - .../linux/apps/hello_pi/hello_wayland/Makefile | 5 + - .../hello_wayland/cube_texture_and_coords.h | 100 ++++ - .../linux/apps/hello_pi/hello_wayland/triangle.c | 666 +++++++++++++++++++++ - host_applications/linux/apps/hello_pi/rebuild.sh | 3 +- - 7 files changed, 785 insertions(+), 1 deletion(-) - create mode 100644 host_applications/linux/apps/hello_pi/hello_wayland/CMakeLists.txt - create mode 100644 host_applications/linux/apps/hello_pi/hello_wayland/Djenne_128_128.raw - create mode 100644 host_applications/linux/apps/hello_pi/hello_wayland/Makefile - create mode 100644 host_applications/linux/apps/hello_pi/hello_wayland/cube_texture_and_coords.h - create mode 100644 host_applications/linux/apps/hello_pi/hello_wayland/triangle.c - -diff --git a/host_applications/linux/apps/hello_pi/CMakeLists.txt b/host_applications/linux/apps/hello_pi/CMakeLists.txt -index f2c6aef..0df78f7 100644 ---- a/host_applications/linux/apps/hello_pi/CMakeLists.txt -+++ b/host_applications/linux/apps/hello_pi/CMakeLists.txt -@@ -21,6 +21,7 @@ add_subdirectory(hello_encode) - add_subdirectory(hello_jpeg) - add_subdirectory(hello_videocube) - add_subdirectory(hello_teapot) -+add_subdirectory(hello_wayland) - - if(BUILD_FONT) - set(VGFONT_SRCS libs/vgfont/font.c libs/vgfont/vgft.c libs/vgfont/graphics.c) -diff --git a/host_applications/linux/apps/hello_pi/hello_wayland/CMakeLists.txt b/host_applications/linux/apps/hello_pi/hello_wayland/CMakeLists.txt -new file mode 100644 -index 0000000..9a2f75c ---- /dev/null -+++ b/host_applications/linux/apps/hello_pi/hello_wayland/CMakeLists.txt -@@ -0,0 +1,8 @@ -+set(EXEC hello_wayland.bin) -+set(SRCS triangle.c) -+ -+add_executable(${EXEC} ${SRCS}) -+target_link_libraries(${EXEC} ${HELLO_PI_LIBS} -lwayland-client -lwayland-egl) -+ -+install(TARGETS ${EXEC} -+ RUNTIME DESTINATION bin) -diff --git a/host_applications/linux/apps/hello_pi/hello_wayland/Djenne_128_128.raw b/host_applications/linux/apps/hello_pi/hello_wayland/Djenne_128_128.raw -new file mode 100644 -index 0000000..de9173c ---- /dev/null -+++ b/host_applications/linux/apps/hello_pi/hello_wayland/Djenne_128_128.raw -@@ -0,0 +1,3 @@ -+öÖż÷×Ŕ÷×ŔřŘÁúÚĂúÚĂúÚĂúÚĂůŮÂůŮÂůŮÂůŮÂůŮÂůŮÂůŮÂůŮÂűŮÂűŮÂűŮÂűŮÂúŘÁúŘÁúŘÁúŘÁřÖżů×Ŕů×ŔúŘÁúŘÁúŘÁúŘÁúŘÁů×Ŕů×Ŕů×Ŕů×Ŕ÷ŐľřÖżů×Ŕů×Ŕ÷Őľ÷Őľ÷Őľ÷Őľ÷Őľ÷Őľ÷Őľ÷Őľ÷Őľ÷ŐľöÔ˝öÔ˝÷Őľ÷Őľ÷Őľ÷ŐľőÓĽöÔ˝öÔ˝őÓĽôŇ»ôŇ»ôŇ»ôŇ»őĐşőĐşőĐşőĐşőĐşőĐşőĐşőĐşôиőŃąôиôиňζóĎ·óĎ·őŃąń͵óĎ·óĎ·ń͵ňζń͵ń͵ń͵ń͵ń͵đĚ´đĚ´đĚ´ďËłďËłďËłî˱î˱î˱î˱î˱î˱î˱íĘ°ďĘ°ďĘ°îÉŻîÉŻíČ®ěÇěÇěÇëƬëƬëƬęĹ«ęĹ«ęĹ«ëƬëƬčĂ©éÄŞéÄŞčĂ©čĂ©čĂ©čĂ©ç¨ůŮÂúÚĂúÚĂűŰÄüÜĹüÜĹüÜĹüÜĹűŰÄűŰÄűŰÄűŰÄűŰÄűŰÄűŰÄűŰÄýŰÄýŰÄýŰÄýŰÄýŰÄýŰÄýŰÄýŰÄüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂűŮÂűŮÂűŮÂűŮÂúŘÁúŘÁúŘÁúŘÁů×Ŕů×Ŕů×Ŕů×ŔúŘÁů×Ŕů×Ŕů×ŔřÖżřÖżřÖżřÖżřÖżřÖżřÖż÷Őľ÷Őľ÷Őľ÷Őľ÷ŐľřÓ˝řÓ˝řÓ˝řÓ˝÷ŇĽ÷ŇĽ÷ŇĽ÷ŇĽöÓş÷Ó»÷Ó»÷Ó»őŃąöŇşöŇşöŇşôиőŃąőŃąôиôиôиôиóĎ·ôиóĎ·óĎ·óĎ·óĎ·ňζňζňζńδńδńδńδńδńδđÍłđÍłňÍłń̲ń̲ń̲đ˱ďĘ°ďĘ°ďĘ°îÉŻîÉŻîÉŻíČ®îÉŻíČ®íČ®ěÇěÇíČ®íČ®ěÇëƬëƬęĹ«ęĹ«űŰÄűŰÄűŰÄűŰÄüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹűŰÄűŰÄűŰÄűŰÄýŰÄýŰÄüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂűŮÂúŘÁűŮÂűŮÂűŮÂűŮÂúŘÁúŘÁúŘÁúŘÁúŘÁúŘÁů×Ŕů×ŔřÖżřÖżřÖżřÖżřÖżů×ŔřÖż÷Őľ÷Őľ÷Őľ÷Őľ÷ŐľřÓ˝řÓ˝řÓ˝řÓ˝÷ŇĽ÷ŇĽ÷ŇĽ÷ŇĽöÓş÷Ó»÷Ó»öŇşöŇşöŇşöŇşöŇşőŃąőŃąőŃąőŃąőŃąőŃąôиôиôиôиôиóĎ·óĎ·óĎ·ňζňζńδńδńδńδńδńδđÍłđÍłňÍłń̲ń̲ń̲đ˱đ˱ďĘ°ďĘ°ďĘ°îÉŻîÉŻîÉŻďĘ°îÉŻíČ®ěÇěÇěÇěÇëƬěÇëƬëƬëƬüÜĹüÜĹüÜĹüÜĹýÝĆýÝĆýÝĆýÝĆüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹűŰÄűŰÄűŰÄűŰÄüÚĂýŰÄýŰÄýŰÄüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂüÚĂűŮÂűŮÂűŮÂűŮÂűŮÂűŮÂűŮÂűŮÂúŘÁúŘÁúŘÁúŘÁúŘÁúŘÁů×Ŕů×Ŕů×Ŕů×Ŕů×Ŕů×ŔřÖżů×ŔřÖż÷Őľ÷Őľ÷Őľ÷Őľ÷ŐľřÓ˝řÓ˝řÓ˝řÓ˝÷ŇĽ÷ŇĽ÷ŇĽ÷ŇĽöÓş÷Ó»÷Ó»öŇş÷Ó»÷Ó»öŇşöŇşőŃąôиőŃąöŇşőŃąőŃąôиôиőŃąôиôиôиóĎ·óĎ·óĎ·ňζňϵňϵňϵňϵńδńδđÍłđÍłňÍłń̲ń̲ń̲đ˱đ˱đ˱ďĘ°ďĘ°ďĘ°îÉŻîÉŻîÉŻîÉŻîÉŻîÉŻíČ®îÉŻîÉŻíČ®ěÇěÇëƬëƬűÜĹüÝĆýŢÇüÝĆüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűŰÄűŰÄűŰÄűŰÄüÜĹüÜĹüÜĹüÜĹűŰÄűŰÄűŰÄűŰÄúÚĂűŰÄűŰÄűŰÄýŰĂýŰĂýŰĂýŰĂüÚÂüÚÂüÚÂüÚÂüÚĂüÚĂüÚĂüÚĂűŮÂűŮÂűŮÂűŮÂúŘŔúŘŔúŘŔů׿÷Ő˝úŘŔúŘŔů׿řÖżřÖżřÖż÷Őľ÷Őľů×Ŕů×ŔöÔľřÔĽřÔĽůŐ˝úÖľőŃąřÔĽůŐ˝ůŐ˝÷Ó»÷Ó»÷Ó»÷Ó»öŇşöŇşöŇşöŇşőŃąőŃąőŃąőŃąőŃąőŃąőŃąőŃąőŃąőŃąőŃąőŃąôиôиóĎ·óĎ·óжňϵňϵňϵńδńδđÍłđÍłń̲ń̲ń̲ń̲ń̲ń̲đ˱đ˱đ˱đ˱đ˱ďĘ°ďĘ°îÉŻîÉŻîÉŻďĘ°îÉŻîÉŻîÉŻěÇěÇěÇëƬűÜĹüÝĆýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹűŰÄűŰÄüÜĹűŰÄýŰĂýŰĂýŰĂýŰĂýŰĂýŰĂýŰĂýŰĂýŰÄýŰÄýŰÄýŰÄüÚĂüÚĂüÚĂüÚĂüÚÂüÚÂüÚÂűŮÁúŘŔúŘŔúŘŔů׿ů×Ŕů×Ŕů×ŔřÖżů×Ŕů×Ŕů×Ŕ÷ŐżúÖľúÖľű׿ű׿řÔĽůŐ˝ůŐ˝řÔĽůŐ˝ůŐ˝ůŐ˝ůŐ˝řÔĽřÔĽřÔĽřÔĽ÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»őŃąőŃąőŃąőŃąőŃąôиôиôиóжóжóжňϵóжóжňϵňϵóδóδóδóδňÍłń̲ń̲ń̲ń̲ń̲đ˱đ˱đ˱ďĘ°ďĘ°ďĘ°ďĘ°ďĘ°îÉŻîÉŻîÉŻîÉŻîÉŻíČ®üÝĆýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹýÝĆýÝĆýÝĆýÝĆűŰÄüÜĹüÜĹüÜĹţÜÄţÜÄţÜÄţÜÄýŰĂýŰĂýŰĂýŰĂýŰÄýŰÄýŰÄýŰÄýŰÄýŰÄýŰÄýŰÄüÚÂüÚÂüÚÂűŮÁüÚÂűŮÁűŮÁúŘŔűŮÂűŮÂúŘÁúŘÁúŘÁúŘÁů×Ŕů×Ŕű׿ű׿ű׿ű׿ű׿úÖľůŐ˝ůŐ˝ůŐ˝ůŐ˝ůŐ˝ůŐ˝řÔĽřÔĽřÔĽřÔĽřÔĽřÔĽřÔĽřÔĽ÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»öŇşöŇşőŃąőŃąőҸôŃ·ôŃ·ôŃ·óжóжňϵňϵőжôϵôϵôϵóδóδňÍłňÍłňÍłňÍłňÍłń̲ń̲ń̲đ˱đ˱đ˱đ˱đ˱ďĘ°ďĘ°ďĘ°îÉŻíČ®üÝĆýŢÇţßČýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆýÝĆýÝĆýÝĆýÝĆüÜĹýÝĆýÝĆüÜĹ˙ÝĹ˙ÝĹ˙ÝĹ˙ÝĹţÜÄţÜÄţÜÄţÜÄţÜĹţÜĹţÜĹţÜĹýŰÄýŰÄýŰÄýŰÄţÜÄýŰĂýŰĂýŰĂüÚÂűŮÁűŮÁýŰĂüÚĂüÚĂüÚĂűŮÂüÚĂűŮÂúŘÁűŮÂýŮŔüŘŔüŘŔű׿üŘŔúÖľúÖľű׿úÖľúÖľúÖľúÖľůŐ˝ůŐ˝ůŐ˝ůŐ˝ůŐ˝ůŐ˝ůŐ˝ůŐ˝řÔĽřÔĽřÔĽřÔĽřÔĽřÔĽřÔĽřÔĽ÷Ó»÷Ó»öŇşöŇşöÓąőҸőҸőҸôŃ·ôŃ·ôŃ·óжőжőжôϵóδôϵôϵóδóδóδóδóδňÍłňÍłňÍłňÍłń̲ń̲ń̲ń̲đ˱đ˱ń̲đ˱ďĘ°ýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆýŢÇýŢÇýŢÇýŢÇüÝĆýŢÇýŢÇýŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆýÝĆýÝĆýÝĆýÝĆüÜĹüÜĹüÜĹüÜĹűÜÂüÝÄüÝÄűÜĂűÜĂűÜĂűÜĂűÜĂýÜÂýÜÂýÜÂýÜÂýÜÂýÜÂýÜÂýÜÂüÚÂüÚÂüÚÂüÚÂüÚÂüÚÂüÚÂüÚÂúŮżúŮżúŮżúŮżúŮżúŮżúŮżůŘľúŘÁúŘÁúŘÁúŘÁřÖżřÖżřÖżřÖżřÖľ÷Ő˝÷Ő˝÷Ő˝÷Ő˝÷Ő˝÷Ő˝÷Ő˝öÔĽ÷Ő˝öÔĽőÓ»őÓ»őÓ»őÓ»ôŇşóŃąôŇşóŃąňиóŃąňиňиňиôиóĎ·óĎ·óĎ·ôиôиôиôиńĎ·ńĎ·ńĎ·đζđζđζď͵ď͵đÍłđÍłđÍłď̲ď̲ď̲î˱î˱ţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČýŢÇýŢÇţßČýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýÝĆýÝĆýÝĆýÝĆüÜĹüÜĹüÜĹüÜĹűÜĂüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄţÝĂţÝĂţÝĂţÝĂýÜÂýÜÂýÜÂýÜÂýŰĂýŰĂýŰĂýŰĂýŰĂýŰĂýŰĂýŰĂüŰÁüŰÁüŰÁüŰÁýÜÂýÜÂüŰÁüÜÁúŘÁúŘÁúŘÁúŘÁúŘÁúŘÁúŘÁúŘÁúŘŔúŘŔů׿ů׿řÖľřÖľřÖľřÖľ÷Ő˝řÖľ÷Ő˝öÔĽřÖľ÷Ő˝÷Ő˝öÔĽöÔĽöÔĽőÓ»ôŇşőÓ»őÓ»ôŇşôŇşöŇşőŃąőŃąőŃąóĎ·óĎ·óĎ·óĎ·ńĎ·ńĎ·đζđζńĎ·đζđζđζňϵňϵňϵńδńδńδđÍłđÍłţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČ˙ŕÉţßČýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆţŢÇţŢÇţŢÇţŢÇýÝĆýÝĆýÝĆýÝĆüÝÄýŢĹýŢĹüÝÄýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹüÝÄüÝÄüÝÄüÝÄűÜĂűÜĂűÜĂűÜĂűÜĂűÜĂűÜĂűÜĂűÜĂűÜĂűÜĂűÜĂűÜĂűÜĂűÜĂűÜĂúÚĂúÚĂúÚĂúÚĂůŮÂůŮÂůŮÂůŮÂřÚŔřŮŔřŮŔřŮŔ÷Řż÷Řż÷Řż÷Řżů׿ů׿řÖľřÖľřÖľřÖľ÷Ő˝÷Ő˝÷Ő˝÷Ő˝öÔĽőÓ»őÓ»őÓ»őÓ»őÓ»öŇşöŇşőŃąőŃąôиôиôиôиňиňиńĎ·ńĎ·ňиňиńĎ·ńĎ·ňϵňϵňϵńδńδńδđÍłđÍłüŕČüŕČüŕČüŕČýáÉýáÉýáÉýáÉüŕČüŕČüŕČüŕČüŕČýáÉýáÉýáÉţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČýŢÇýŢÇýŢÇýŢÇ˙ßČ˙ßČ˙ßČ˙ßČţŢÇţŢÇţŢÇţŢÇýŢĹýŢĹţßĆýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄűÜĂűÜĂüÝÄüÝÄűŰÄűŰÄűŰÄűŰÄúÚĂúÚĂúÚĂúÚĂúŰÂúŰÂúŰÂůÚÁůÚÁůÚÁůÚÁůÚÁúŘŔúŘŔúŘŔů׿úŘŔů׿ů׿ů׿ů׿ů׿řÖľ÷Ő˝÷Ő˝÷Ő˝öÔĽöÔĽöÔĽőÓ»őÓ»őÓ»ôŇşôŇşôŇşôŇşôŇşôŇşóŃąóŃąóŃąóŃąňиňиňŃ·ńжńжńжđϵđϵđϵďδüŕČüŕČýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉţßČţßČţßČţßČţßČţßČţßČţßČýŢÇţßČţßČýŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄýŢĹýŢĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹýÜĆůÚÁůÚÁůÚÁůÚÁůÚÁůÚÁůÚÁůÚÁůŮÂůŮÂůŮÂůŮÂůŮÂůŮÂůŮÂůŮÂ÷Řż÷Řż÷Řż÷Řżö׾ö׾ö׾őÖ˝řÖľ÷Ő˝÷Ő˝÷Ő˝öÔĽöÔĽöÔĽ÷ÔĽňÓşňÓşňÓşňÓşňÓşňÓşńŇąńŇąňиňиńĎ·ńĎ·ńĎ·ńĎ·ńĎ·đζüŕČýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉţßČţßČţßČţßČţßČţßČţßČţßČýŢÇţßČţßČýŢÇţßČţßČţßČţßČ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉýŢÇýŢÇýŢÇýŢÇýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹýŢĹüÝÄýŢĹýŢĹýŢĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÝÄüÝÄüÝÄüÝÄűÜĂűÜĂűÜĂűÜĂűŰÄűŰÄűŰÄűŰÄúÚĂúÚĂúÚĂúÚĂůÚÁůÚÁřŮŔřŮŔůÚÁřŮŔřŮŔřŮŔů׿řÖľřÖľřÖľ÷Ő˝÷Ő˝÷Ő˝öÔĽôŐĽôŐĽôŐĽôŐĽóÔ»óÔ»óÔ»ňÓşôŇşóŃąóŃąóŃąňиňиńĎ·ńĎ·űáÉűáÉűáÉüâĘűáÉűáÉűáÉűáÉűáÉűáÉűáÉűáÉűáÉűáÉűáÉűáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉýŢÇţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýßĆýßĆýßĆýßĆüŢĹüŢĹüŢĹüŢĹüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÝÄűÝÄűÝÄűÝÄűÝÄűÝÄűÝÄűÝÄüÜĹüÜĹüÜĹüÜĹűŰÄűŰÄűŰÄűŰÄűÜĂúŰÂúŰÂúŰÂůÚÁůÚÁřŮŔřŮŔúŘŔúŘŔů׿ů׿ů׿ů׿řÖľřÖľö׾ö׾ö׾őÖ˝őÖ˝őÖ˝ôŐĽôŐĽőÓ»őÓ»ôŇşôŇşóŃąóŃąóŃąňиűáÉűáÉüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉţßČ˙ŕÉ˙ŕÉţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČýßĆýßĆýßĆýßĆüŢĹüŢĹüŢĹüŢĹüÝĆüÝĆüÝĆüÝĆýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆűÝÄűÝÄűÝÄűÝÄűÝÄűÝÄűÝÄűÝÄüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹüÜĹűÜĂúŰÂúŰÂúŰÂűÜĂúŰÂúŰÂúŰÂúŰÂůÚÁůÚÁůÚÁřŮŔřŮŔřŮŔ÷Řż÷Řż÷Řżö׾őÖ˝őÖ˝őÖ˝ôŐĽôŐĽóÔ»óÔ»óÔ»ňÓşňÓşňÓşňÓşńŇąůâČůâČůáÉůáÉüáĚüáĚüáÍüáÍűáÉűáÉűáÉűáÉüâĘüâĘüâĘüâĘüâĘüâĘüâĘţâĘýáÉýáÉýáÉ˙ŕÉýăČýâČýâČýâČýâČýâČýâČýâČ˙áČ˙áČ˙áČ˙áČ˙áČ˙áČ˙áČ˙áČţáŔúŕĆřŢĘţŢÇ˙ăÄ˙âĂűÝĂöÚĆúŢĹ˙ăČúÝÂ÷äĘůÝÎ˙ŰÎ˙ŢČńĺĂ˙ŢÉ˙ßČ˙ßČ˙ßČţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇţŢÇýÝĆýÝĆýÝĆýÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰĹřŮÂ÷ŘÁ÷ŘÁ÷ŘÁ÷Řż÷Řż÷Řżö׾őÖ˝ö׾őÖ˝ôŐĽôŐĽôŐĽôŐĽóÔ»óÔ»óÔ»ňÓşňÓşůăĘúâĘúâĘúâĚüáĚüáĚüáÍüáÍüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙âÄýâČűŕĚ˙ŕÉ˙ŢĹ˙ćČúÜĂöŕÍţéÖ˙ăÉűÝÁůćĘúßË˙ŰÎ˙ŢČőäĂ˙ŢÉţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄřŮÂřŮÂ÷ŘÁ÷ŘÁřŮŔřŮŔ÷Řż÷Řżö׾ö׾őÖ˝őÖ˝őÖ˝ôŐĽôŐĽôŐĽóÔ»óÔ»óÔ»óÔ»úäËúäËűăÍűăÍűăÍýâÍýâÎýâÎýăËýăËýăËýăËüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉţâĂůŕČúßĘţßČţŕĆ˙ăÇ÷ßĚěÜŃóăŇ˙ăĎ˙áĹřâČűŕÍ˙ŢĚ˙ŕÉöäÇ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉţßČţßČţßČţßČ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹúŰÄúŰÄúŰÄúŰÄůÚĂůÚĂřŮÂřŮÂůÚÁřŮŔřŮŔřŮŔ÷Řżö׾ö׾ö׾ö׾őÖ˝őÖ˝őÖ˝ôŐĽôŐĽôŐĽóÔ»úăÍúăÍúăÍűăÍüäÎüäÎţăĎţăĎűăÍűăÍűăÍűăÍűăÍűăÍűăÍűăÍűăÍűăÍýâÍýâÍüáĚţáĚţáĚţáĚţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘýâÇűáÉűŕĚ˙ŕÉ˙ĺÉřÝĹúíŢnhcňëŢřÜË˙äĘřŕĹúßË˙ŢĚ˙ßËřäĆ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČţßČýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹúŰÄůÚĂůÚĂůÚĂůÚÁůÚÁůÚÁřŮŔřŮŔö׾ö׾÷Řżö׾ö׾őÖ˝őÖ˝őÖ˝őÖ˝ôŐĽôŐĽúâÎúâÎúâÎúâÎúáÍüăĎüäÎűăÍüäÎüäÎüäÎüäÎűăÍűăÍűăÍűăÍűăÍűăÍűăÍýâÍýâÍýâÍýâÍ˙âÍüâĘüâĘüâĘüâĘűáÉüâĘýăËűâĘýáÉýáÉţâĘ˙ăËţâĘţâĘţâĘţâĘţâĘüáÍüáĚ˙ăÉýŕÄńÝÇÚÖĚ]eg•ŽňŰĚ˙ÜÄ˙ćĘřáÉ˙ŕË˙ßËúâČ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉţßČţßČţßČţßČýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇţßČţßČţßČţßČýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇţßČţßČýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄůÚĂůÚĂůÚÁůÚÁřŮŔřŮŔřŮŔřŮŔ÷Řż÷Řżö׾ö׾őÖ˝őÖ˝ôŐĽôŐĽôŐĽôŐĽüćÔűĺÓüäĐúâÎűăĎüăĎýĺĎüäÎüäÎüäÎüäÎüäÎűăÍűăÍűăÍűăÍűăÍűăÍűăÍűăÍýâÍýâÍýâÍýâÍýâÍýâÍýâÍýâÍýâÍţăÎţăÎýâÍţáĚţáĚţáĚţáĚţáĚţáĚţáĚţáĚűáĚüáĚüáĚ˙âÉůŕĹôćÓ¬«UdlYhe˙ěá˙äĐţáĹůäÉţáÍ˙ŕĚţâĘýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉţâĘţâĘţâĘţâĘýáÉýáÉýáÉýáÉüŕČüŕČüŕČüŕČüŕČüŕČüŕČűŕČţßČţßČţßČţßČţßČţßČýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄúŰÄůÚĂúŰÂúŰÂúŰÂůÚÁřŮŔřŮŔřŮŔřŮŔ÷Řżö׾ö׾ö׾ö׾őÖ˝őÖ˝ôŐĽůăŃůăŃůăŃűăĎűăĎűăĎűăÍűăÍüăĎüăĎüăĎüăĎüăĎüăĎüăĎüăĎűăĎűăĎüăĎüăĎüăĎţăĎţăĎţăĎýâÍýâÍýâÍýâÍýâÍýâÍýâÍýâÍýâÍýâÍüáĚüáĚüáĚüáĚüáĚüáĚüáĚüáĚüâĘţăÉ˙čÍîâĐŠŠ@Vg:PM˙őî˙ŢÉ˙äĆůĺČüáÍ˙áĚ˙áÍýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉüŕČüŕČüŕČüŕČýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉ˙ŕÉţßČýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹúŰÄúŰÄúŰÄűÜĂűÜĂúŰÂúŰÂůÚÁůÚÁůÚÁřŮŔ÷Řż÷Řż÷Řżö׾řŮŔ÷Řżö׾őÖ˝ţç×ţç×ţčÖ˙çÖ˙çÓýĺŃűäÎýĺĎüäĐüäĐüäĐüäĐűăĎűăĎűăĎűăĎűăĎűăĎüăĎüăĎüăĎţăĎţăĎţăĎýâÍýâÍýâÍýâÍţăÎýâÍýâÍţăÎüáĚýâÍýâÍýâÍýâÍýâÍýâÍýâÍýâÎýâÎýăË˙äÉřŕĆäÚÉlyzB[n>VWIJ¬˙ŢÉ˙ĺĆřäČůâĘ˙ßÎ˙áĚţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉţáÉýáÉýáÉýáÉţßČţßČţßČţßČţßČţßČ˙ŕÉ˙ŕÉţßČţßČţßČţßČýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹúŰÄúŰÄúŰÂúŰÂúŰÂúŰÂúŰÂúŰÂůÚÁůÚÁřŮŔřŮŔ÷Řż÷Řżö׾ö׾ö׾ö׾úęŇýëÚţëÜůçÖőĺÎřçĎűĺÓüá×řăÎůäĎůĺĐůĺĎüäĐüäĐüäĐüäĐüäÎüäÎýĺĎýĺĎüäÎüäÎüäÎüäÎüăĎüăĎüăĎüăĎüăĎüăĎüăĎüăĎüĺÎüäÎüäÎüäÎűăÍűăÍűăÍúăÍ˙áČőâÎöâÍ˙ĺĂ˙čĎA;=?LWI]`AU[Ž’“ôăŰúÝÍ˙ăČüăÉűâÉţßÎýăÇýâČýâČýâČýăČţăÉ˙äĘ˙äĘţăÉţăÉţăÉţăÉýâČýâČýâČýâÇřßËďćÉ˙ŕÂ˙äËŮáČřăŇ˙ŘÉđčČýŕČüŕČüŕČüŕČüŕČüŕČüŕČüŕČűßÇűßÇűßÇűßÇűßÇűßÇűßÇúßÇýŢÇýŢÇýŢÇýŢÇűÜĹüÝĆýŢÇýŢÇüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹúŰÄúŰÄůÚĂůÚĂůÚĂůÚĂůÚĂřŮÂůŮÂřŘÁřŘÁřŘÁ÷×Ŕ÷×Ŕ÷×ŔöÖżůéŮ÷ç×öĺŘřč×řęÔűęŐýéŘýçŰ˙ńŰ˙îŮ˙ëÖýčÓűăĎűăĎűăĎűăĎüäÎüäÎüäÎüäÎüäÎüäÎüäÎüäÎýäĐýäĐýäĐýäĐüăĎüăĎüăĎüăĎüäÎüäÎüäÎüäÎűăÍűăÍűăÍűăÍ˙äČ÷ăĎ÷ăÍ˙ćĆüĺĎÉÇĹGV`=QV@TY.23D2+óŘĆ˙ăËüăÉüâĘţßÎ˙ăË˙ăË˙ăË˙ăË˙ăË˙ăËţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘţßČőçËţŰÄüâŃÝç×îÚĎ˙ßĚőĺÄüßČüŕČüŕČüŕČüŕČüŕČüŕČüŕČüŕČüŕČüŕČüŕČűßÇűßÇűßÇűßÇýŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹűÜĹűÜĹúŰÄúŰÄúŰÄůÚĂúŰÄůÚĂůÚĂůÚĂřŮÂřŮÂ÷ŘÁ÷ŘÁ÷ŘÁ÷ŘÁö×Ŕö×Ŕúîâůîâůíß÷ëŮřęŘúęŮůéÚřčŰúĺĎůäĎůäĎúĺĐüäĐüäĐüäĐüäĐýĺĎýĺĎüäÎüäÎüäÎüäÎüäÎüäÎüăĎüăĎüăĎüăĎüăĎüăĎüăĎüăĎüäÎüäÎüäÎüäÎüäÎüäÎüäÎüäÎ˙äČúâŃúâÎ˙äČĂ°š¶¸»_pzGV]@T\MRSˇ“Š÷ŢËýâĘüäÉüáÍüáÎüâÉüâĘüâĘűâĘýăËýăËüâĘűáÉţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâĘ˙áĹůáČýâŇęÝŮhwvńäŕ˙ÝĚůăÁýáĘýáÉýáÉýáÉýáÉýáÉýáÉýáÉüŕČüŕČüŕČüŕČűßÇűßÇűßÇűßÇýŢÇýŢÇýŢÇýŢÇýŢÇýŢÇüÝĆüÝĆýŢÇüÝĆüÝĆüÝĆűÜĹűÜĹűÜĹűÜĹűÜĹúŰÄúŰÄúŰÄúŰÄúŰÄůÚĂůÚĂůÚĂůÚĂřŮÂřŮÂřŮÂ÷ŘÁ÷ŘÁ÷ŘÁőíéůđćúňáýńß˙đŕţîáűëßůęÚüçŇúĺĐůäĎűćŃ˙čÔ˙čÔ˙čÔ˙čÔ˙çŃ˙çŃţćĐýĺĎýĺĎýĺĎýĺĎýĺĎüăĎüăĎüăĎüăĎýäĐýäĐýäĐýäĐüäÎüäÎüäÎüäÎüäÎüäÎüäÎüäÎ˙ĺČůâŃűáŃ˙ĺÉěßÍ›ť\m|M[d:T\LSV˙ńëöÝÍüäĘűăËűăÍýâÎýăËýăËýăËýăËüâĘüâĘýăËýăËţâĘţâĘţâĘţâĘţâĘţâĘţâĘţâË˙ăĹ˙ŕĘöâÚ¦ŻłViuŻ©ŻýŢĐţĺżýáĘýáÉýáÉýáÉýáÉýáÉýáÉýáÉüŕČüŕČüŕČüŕČüŕČüŕČüŕČüŕČüŕČüŕČüŕČüŕČúßÇűßÇűßÇűßÇűßÇűßÇúŢĆúŢĆúŢĆúŢĆúŢĆúŢĆůÝĹůÝĹřÜÄřÜÄřÜÄřÜÄřÜÄ÷ŰĂúŰÄůÚĂůÚĂůÚĂřŮÂřŮÂřŮÂ÷ŘÁőěďôěĺřńŢůîÚřéŮúčŢůęÝřę×ţčÓ˙ëÖ˙ě×ţéÔýäĐýĺŃýĺŃýĺŃűăĐüäĐüäĐüäĐüäĐüäĐüäĐüäĐýäĐýäĐýäĐýäĐüăĎüăĎüăĎüăĎüăĎüăĎüăĎüăĎüăĎüăĎüăĎüăĐőâÄűäÓţăŐţáˢšŚ /5G\nJS_<ZgFOWËÁ˝ş¤”˙îŘűćĚüäÎúâÎýăËýăËýăËýăËýăËýăËýăËýăËüâĘüâĘüâĘüâĘüâĘüâĘüâĘüâËýăÂűŮĹóć↛ĄK`tSS_üęŕ˙ĺĹúáÉűáÉűáÉűáÉűáÉűáÉűáÉűáÉúáÉüâĘűáÉůßÇúŕČúŕČúŕČúŕČűßÇűßÇűßÇűßÇűßÇűßÇűßÇűßÇúŢĆúŢĆúŢĆúŢĆůÝĹůÝĹůÝĹůÝĹůÝĹůÝĹůÝĹůÝĹřÜÄřÜÄřÜÄřÜÄúŰÄúŰÄúŰÄúŰÄůÚĂůÚĂřŮÂřŮÂŃĆŃöěĺří×ůëÔüć×úăÜ÷äŐőčĐúĺĐűćŃűćŃúĺĐýĺŃýĺŃýĺŃýĺŃüäĐüäĐüäĐüäĐüäĐüäĐüäĐüäĐýäĐýäĐýäĐýäĐýäĐýäĐýäĐýäĐýäĐýäĐýäĐýäĐüăĎüăĎüăĎüăĐůĺÇřŕĎ˙áŐőçŃÓÎÁvŹ–1EYPVd;ZiGQYogc˙îáůŕĚűĺËűäÎüăĎűăÍűăÍűăÍűăÍűăÍűăÍűăÍűăÎýâÍýâÍýâÍýâÍüáĚüáĚüáĚýáÎőăĹ˙ÚÍßÖÓ|žĄ?RePUbâáŘúŕÇűáÉűáÉűáÉűáÉűáÉűáÉűáÉűáÉűáÉűáÉűáÉúŕČúŕČúŕČúŕČúŕČüŕČüŕČüŕČüŕČűßÇűßÇűßÇűßÇúŢĆúŢĆúŢĆúŢĆúŢĆúŢĆúŢĆúŢĆůÝĹůÝĹůÝĹůÝĹřÜÄřÜÄřÜÄřÜÄřÜÄřÜÄřÜÄřÜÄ÷ŰĂ÷ŰĂ÷ŰĂöÚÂŚ|‹éÝ×óčĚýěĐţăÖýŕÚúăŇůéËűćŃűćŃüçŇűćŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃţĺŃţĺŃţĺŃţĺŃýäĐýäĐýäĐýäĐýäĐýäĐýäĐýäĐüăĎüăĎüăĎýăĐřéÇţĺŐ÷ŐÉ˙íŢĚÍĂ|ź@ZnKM\=_nJU`C<;˙˙ňůäÎřäÎüäÎüăĎüäÎüäÎüäÎüäÎüäÎüäÎüäÎüäÎýâÍýâÍýâÍýâÍüáĚüáĚüáĚţáĚéŕĘ˙ßÓł§9=APbTYf–ŁśęÔĂýâĘüâĘüâĘüâĘűáÉűáÉűáÉűáÉüâĘűáÉűáÉűáÉűáÉűáÉűáÉűáÉúŕČúŕČúŕČúŕČůßÇůßÇůßÇůßÇůßÇůßÇůßÇůßÇřŢĆřŢĆřŢĆřŢĆ÷ÝĹ÷ÝĹ÷ÝĹ÷ÝĹ÷ÝĹ÷ÝĹ÷ÝĹ÷ÝĹřÜÄřÜÄřÜÄřÜÄřÜÄřÜÄ÷ŰĂ÷ŰĂjWiďŕÚřęÍ˙îŃ˙äŐ˙âÜ˙ć×üęĘűćŇűćŃűćŃűćŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃţĺŃţĺŃţĺŃţĺŃýäĐýäĐýäĐýäĐýäĐýäĐýäĐýäĐýäĐýäĐýäĐţäĐ÷ęĆţăŐţŘĐ˙çŐĎŃĆwˇ]v‰`bsChx[irŽ†„úćÚűĺÍúäÎúĺĎýäŃüäÎüäÎüäÎüäÎüäÎüäÎüäÎüäÎýâÍýâÍýâÍýâÍýâÍýâÍýâÍ˙âÍęčŇ纲ľąłbŚŽ;JXZbn°Á»îßĎýâÉüâĘüâĘüâĘüâĘüâĘüâĘüâĘýâĘűáÉűáÉüâĘűáÉűáÉűáÉűáÉúŕČúŕČúŕČúŕČúŕČúŕČúŕČúŕČůßÇůßÇůßÇůßÇřŢĆřŢĆřŢĆřŢĆřŢĆřŢĆřŢĆřŢĆ÷ÝĹ÷ÝĹ÷ÝĹ÷ÝĹůÝĹůÝĹůÝĹůÝĹůÝĹřÜÄřÜÄřÜÄCHVčÚÔ˙ćÔ÷ăÓöĺÔýçÎýçÍôä×öćŃöćŃöćŃůćŃ÷ĺĐřćŃűćŃüçŇýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýĺŃýćĐýćĐýćĐýćĐüĺĎýćĐýćĐ˙çŃňęĚţęČűçÎóäÚřáŇ˙äĆüŕËóčăĐăÚĚßÚĽŐŐ®ËÔŚŞĽ±Ä‡žµ–łk…†;W^Nir/GQ¤¶»ŇŮÖîíßçßÍůĺĘűĺĚűĺËűäÎűăĎüăĎüăĎüáÓüéĹüĺËúćËűăĐůâÎűâÎűăÍţăĘóáĘďçࡹĂj™UT_MZ[xŹ†ôÜÜúăĚúâĚůáÎüáÍüáÍüáÎúâĚúâÍřăĘůăĘúâĘúâĘűáÉűáÉţáÉţáÉůáĚůáËůáËůáĚřŕĘřŕĘřŕĘřŕË÷ŕĆ÷ŕĆ÷ŕĆ÷ŕĆőßĹ÷ŕĆ÷ŕĆřáÇößĹößĹößĹößĹößĹößĹößĹößĹ÷ŢÄ÷ŢÄ÷ŢÄ÷ŢÄőÜÂ÷ŢÄöÝĂőÜÂJM[÷éăýĺŃ÷ăŇ÷ĺÔýćĐýçÎőĺŐúćŃúćŃůćŃůćŃýçŇüçŇűćŃűćŃűćŃűćŃűćŃűćŃűćŃűćŃűćŃűćŃűćĐűćĐűćĐűćĐüçŃüçŃúćĐűćĐöćÔ˙ćÍ˙ĺŇöäŘúćŐúăÉäŰËĄ¦”¤±‘Ł°Ť˘´}©‰Ą¶y©z©x™§\mx<R^8M]K\iJVaV[^onjîéĺţčĚúćÍýĺĐüĺĎüäĐýäĐýäĐýăÓüĺĘüäĚűäÎüăĎýäĐýäŃ˙ĺĚ˙äÍ˙čËüçŢm"?PSXiN^`F]YĺÎĚúäÉűăÎţâÍţăÍüáĚüáĚúâĚúâĚůăĘůăĘúâĘúâĘűáÉűáÉűáÉţáÉůáËůáËůáËůáËřŕĘřŕĘřŕĘřŕĘřŕČřŕČřŕČřŕČ÷ßČ÷ßÇ÷ßÇ÷ßÇ÷ßÇ÷ßÇ÷ßÇ÷ßÇöŢĆöŢĆöŢĆöŢĆ÷ÝĹ÷ÝĹ÷ÝĹ÷ÝĹ÷ÝĹ÷ÝĆ÷ÝĹ÷ÝĹNQ_öéăţéŐüč×řćŐţçŃţčĎöćÖúçŇúçŇüçŇüçŇýčÓţćŇţćŇýĺŃüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇýčÓüçŇüçŇűćŃöáÝ˙äÓ˙äŃűäÖôăŇöęÔ´ľ´v—Ą‰ťż‚·{•°{›µs’¨ˇ°~ˇ]„ŠR_q>M_BSg=L`KXhFO]OU]»ÁÉţĺĚúĺĎůĺĎüĺĎüäĐüäĐýäĐýäĐűäÎűäÎýăĎüăĎţăĎţăÎ˙äĚ˙ĺËţéÄΰźŞ˝Ăs‘§KRhL]h#>:˙ôôűçĚűĺĚüäË˙ăĎüáĚýáĚúâĚůáÎůăĘůăĘúâĘúâĘůâĘüâĘüâĘüâĘůáËůáËůáËůáËůáËůáËůáËůáĚřŕČřŕČřŕČřŕČřŕČřŕČ÷ßÇöŢĆöŢĆöŢĆöŢĆöŢĆ÷ßÇ÷ßÇ÷ßÇ÷ßÇ÷ÝĹ÷ÝĹ÷ÝĹ÷ÝĹ÷ÝĹöÜÄöÜÄ÷ÜÄJM[çŮÓ˙ńÝřäÓřćŐţçŃţčĎöćÖýćÔýćÔüćÔüćÔţćÔţćÔţćÔ˙çÖüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇţčÓôäÝ˙ćŃ˙čÎ˙ćŇţęŐřęÓ ¨Ąv–«}™µy•Żx“®|°sĄˇ˛…Ł^‡^gv@Q]>N^<L^<M]TaoMZd’ťţäËúĺĐúĺĐůĺĐüäĐüäĐüäĐüäĐúäÓůäŇüäŇýäĐ˙äĐ˙äĎ˙äĐ˙äÍ˙óĚýŰĚĽÄmŠ¤gn`w„.OJđćĺôâĚőäĚúăÎýăĘýăĘýâÍűăÍúâÎűăÍűăÍűăÍűăÍúâĚúâĚúâĚúâĚúâĚúâĚúâĚúâĚůáËůáËůáËůáËřŕČřŕČřŕČřŕČ÷ßÇřŕČřŕČůáÉ÷ßÇ÷ßÇ÷ßÇ÷ßÇ÷ßÇ÷ßÇ÷ßÇ÷ßÇöŢĆöŢĆöŢĆöŢĆöŢĆôÝĹőŢĆ÷ßÇ,/=ztnZţíÜřćŐţçŃţčĎöćÖöâĐôŕÎ˙ěÚýčÖüćÔţćÔţćÔţćÔüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇüçŇýçŇéĺÔ˙ěŃ˙čË˙çŇúăĚţčŇŞ§¤q‡ś†¦®Ť§µ^w†m„–^s…CXkCZj|“ŁObf<MVBV\BU\@TZGXaCW]r†Ź˙çŇ÷äŇ÷ăÍýčÓúćŃţĺŃýĺŃţĺŃ÷äŇüćÔţćÔýäĐýâÎůŕĚűĺŃüčÔ˙ĺÇóßŐm‚Ť:Zt‰Ź©Mfs.QRQINÓĚşßÔĂňăÍ÷ŕĘţăËţâÍúăÍ÷ăÎűăÍűăÍűăÍűăÍúăÍúăÍůâĚůâĚůâĚůâĚůâĚůâĚřáËřáËřáËřáËřâÉřâÉřâÉřăÉöŕÇöŕÇöŕÇöŕÇ÷áČ÷áČ÷áČ÷áČöŕÇöŕÇ÷áČ÷âČ÷ßÇ÷ßÇöŢĆöŢĆőÝĹőÝĹöŢĆöŢĆ?BPůëĺűŕĚďÚÉřćŐţçŃţčĎöćÖöĺŇ˙đÝńÝËţé×úćÔüćÔüćÔüćÔúçŇúçŇúçŇúçŇúçŇúçŇúçŇúçŇúćŐúćÔúćÔúćÔúćÔúćÔúćÔúćÔďéÔúéÍ˙ëĎřç×ôßŃůéŘ––…—°Yxy%*=Q\-?M<N_yŠ›Yj{CTfTglATZAT[AT[@RY!59@PUu‰˙čÓýíÚôßÍýęŮüçŃúćŃýĺŃţĺŃřĺÓűĺÓýĺĐţĺŃüäĎůĺÓ÷č×íŕŃđéÜ®¦¨ŞČÖPp…Ł§ŔK`k*PS|}˘¤›MJ@ýđáúčŇűăÎűăĘüăÍúâĎűăÍűăÍűăÍúäÍůâĚűăÍřăÍňŢČůâĚůâĚůâĚůâĚřáËřáËřáËřáËřáËřáËřáËřáË÷ŕË÷ŕË÷ŕË÷ŕË÷ŕĘ÷ŕĘ÷ŕĘ÷ŕĘößĘößĘ÷ŕĘ÷ŕĘ÷ßĘ÷ßÉ÷ßÉöŢÉöŢČöŢČöŢČöŢČDGUóĺßüăĎţęŮřćŐţçŃţčĎöćÖůë×ôĺŇ÷čŐěŰČ÷ćÓ÷çÔúćÔúćÔúçŇúçŇúçŇúçŇúçŇúçŇúçŇúçŇúćÔúćÔúćÔúćÔúćÔúćÔúćÔúćÔűęÔ˙éĎôâÓëáŕďěëäáÝŤś u˛…ź¬¦ľĎś˛Ä©˝Ď¶ĹŮj~ŹJape€‹o‰“VlxF\cGW`2@J6CK-6A$ì—ôßĎ˙îÝ÷ăŃűĺÔűćŃúćŃţĺŃůçŃűćŃýćĐýĺŃýçŐđŕĐňęŢĺÝĐ°ĹĘŻ¸ČłÇx™¬wy‹RhlCkmś¨O\]Z`\ČÄşńâŃüäÎüäĚüäÎűäÎüăĎüăĎüăĎűăĐűâĎűćŇöŕĚńÜÇúăÍůâĚůâĚůâĚůâĚůâĚůâĚůâĚřáËřáËřáËřáËřáËřáËřáËřáËřáËřáËřáËřáË÷ŕĘ÷ŕĘ÷ŕĘ÷ŕĘřŕĘ÷ßÉ÷ßÉ÷ßÉ÷ßÉöŢČöŢČőÝÇGIWóăÝţĺĐ˙ěŰůçÖ˙čŇ˙éĐ÷ç×÷é×÷čŐŃż˙óŕ÷çÖřćŐ÷ćÖ÷ćŐúçÓűçŃüčŃúçŇúçÓúçŇúçŇúçŇűćŐűćÔűćÔúćÔúćŐúćÔúćÔúćŐ˙äŐ˙âŇűčăŇĐŮźĄ°žž‚ˇ«m˘Ľz’°„›ş€•±~‘¬‚—7R_3T[6]]<RiAYjBTe>N\<GS">BPEJ]˙˙˙óßÍýéŘůĺŇüćÔüçŇüçŇüçŇűçŇűćĎýćĐ˙čŃôĺŃöéÚđëঠ“‰¨ĽŚ¤ąy˘şSu…qm|]pt:dfNU`^mvZcdĹĂ»ćŮÉúĺÎţĺËýäĚúäÎüăĎüăĎüăĎűâĎűçŇńÜÇüčŇéŐżýäÍűăÍúăÍúăÍůâĚůâĚůâĚůâĚůâĚůâĚůâĚúâĚřáËřáËřáËřŕËřáËřáËřáËřáËřáËřŕĘ÷ŕĘ÷ŕĘ÷ŕĘ÷ŕĘößÉößÉößÉößÉőŢČôÝÇ?TXĂÎÍçĺÝůë×˙čŃüčÓőç×ńč×çŢË˝ÇÄZp~XdrîßŢţŕŃ˙ßË˙íÝúëĽęăâäâí÷čÔ˙ćÇüŕŇúäÚýěËîęÍęč×ďęÖ˙íĎýçČůčÓůęŃűéÁűćÉ˙éŘčçänŽ•{˘µś¶Źś¶—ŞuŚˇsŠźxŚˇn„•e|Ś7N]>R^=Q_8MR@U\@V]@S[9MU/6;MV<NWw–ŘăĺďćĺűăŮ˙ćŃ˙çÎ˙ćŇ˙ă×čäÝôĺÖ÷äÖöä×ţçĐ˙ëĘďčŢ{”¬…¨ÁŤ¬Á®Â]j~CTdYhwSak<NXSkd^fuµş´áĺĐŇÎÚĺÚÚňçĹ˙äŇöăŃöăŇřäĎýäĚţĺÉőćŃŕŢÚU`kŮŢŘäŕĎűćĐýäËűáÍ÷áĐ÷âÎ÷ĺČőăĚőăĚőăĚőäĚóâËőăĚőăĚöĺÎőŕĘöáË÷âĚ÷âĚöáËöáËöáËöáË÷ŕĘ÷ŕĘ÷ŕĘ÷ŕĘößÉřŕĘ÷ŕĘöŢČBTZJSWöóëôăÓ˙çÓ˙čŇůčÓöčÖóę܇Ś‹PdlEU^ďęé˙îÝüéÔöęÓóéĆĽş¸\\cöěŢýčÎüâÓ÷ĺŘýîŇÚŮÍŰŘÖěăÚüăĎţëŐîâŐęâÖüđŢ˙ňŐíÚĘĺăŕŚ¦°…¨ą‹žµ„”©š¬wŚˇk€•|’Łf}ŤThw>U`@Vc:P\AT[@SZ@RZEX`?OYGXaBS\DT^9WRHX[”‘’˙ńéýçŃ˙čÎůçŇőć×ňćÖűçŃýçŃřćÖůăÍ˙éËâŕÔ“§¸…©˝oŚ˘—°Ĺh|ŤDTdfv‚DU^9ITIa[HQb˘¨ŁÚŕŃF>HôéčöęĘ˙äÔřäŇřäŇ÷ĺĐüćÍüčËőĺĐĆÂĽfpzĽŔ·ďéŰěÚĹţäËűâÎřâĐőăÎřäËöäÍöäÍöäÍöäÍőăĚőăĚőăĚőăĚ÷âĚ÷âĚöáËöáËöáËöáËöáËöáËőŕĘőŕĘőŕĘőŕĘőŕĘőáËöáËőŕĘ9JX<FMuppíßÓýçŐ˙čŇţčŇůéŃĺăÜpz~>T\@S[†ĺßŇďęÖčćÍćéÔ}‡U\i‰‰‚ňçŃřäÓöĺŮíçÓŚZ]höďńüĺŐüć×îé鲶ąÓŐÖńäÍöęßÍÎІ¤«¦ą}‘¦o”uŽźxŤŁuŚť|Ź au„e|‡8KV@S_F[bFV_>OXIZcFW`GU^GV_ET]ES\7Y^G[c@FJ˙üőőçŐőęÎőčŇďčÖřćĐ˙çĚţçÍôäÔöéÖőĺŃĐÎÇ•¨¸~ž´{šž¸ÉLdt=P]_q|?RY;NWCZYWarśšŇÝĎ_^lĎËÍőęĐýäŐ÷äŇřäŇ÷ĺĐüćĚţéĎîáͧ¨¦Ubl•š–űöęýíŘüčŇúáÍöâĐöăÎřäĘöăÎöăÎöăÎöăÎöăÎöăÎőâÍőâÍřăÍ÷âĚ÷áËöáËöáËöáËöáËöáËöáËöáËöáËöáËőŕĘôßÉôßÉőŕĘ4DTGQ[IHMňçä÷ćŮűçŐűčÓúéŇÂĚÎ`ruBZbAT\]adîĺÝđâŃöëÔŔÔËdpxKXeZcgöńćůĺÓńĺ×ŃŇÄlz‹O[k§Ą©ůčŮóâѧ¬®XjvAS\ěčŰęăßźĄ©Š§µžŻ^o… 1C!<K[n€-=;O`6KZ*<I@T_>SZ1FN-:)5=JW!.;1?LJUaFR^NXd:XbBUaBDMđčćôçÖöëŇöęŃóč×őçŐ˙ęÍűčĐęćÜëčĺŮÚÓĹÎĐ•ŻĆťĽĚŚ¨ą™©Lcr9P[OdoI\c<OX.-'2IQ`]˛ÂąLReĹĹĘęĺË˙âÖűćĎřäÓřĺĐúäĎńŢĆéŢËĽ˝ĽQapRYZś™ŹŢĐ˝úäÎůäÎôăĐôăŃöĺÍ÷ăÎöăÎ÷ăÎ÷ăÎ÷ăÎöăÎőâÍőâÍőăĚőăĚőăĚöĺÍőăĚőăĚőăĚőäĚöáËöáËöáËöáËöáĘôßÉôßÉőŕĘ.?%347?ćáăčÝÚřěŕňč×íäφť¤Sls:RX<LVFFNüěîüăŰ˙ęŮ°łTdl>KZCU^çëĺöäŇóéŰŹťTjx>R__eg˙řćăßĎ~ŤŽD`lA^eglfäĺ獗ˇ“Żľ ˛’Ą·kz‹x”ˇTj|y‘ ‚•¦BWfG^i?R]@U\9NV0?L7GS0>J#1=6DP#/%1"-9"6F2<K74?˙úűřč×öćÎýě×řĺÔńĺŮűčĐňĺŇÜă䣱ľ¦˛˝‰š§~šµw‘ † °c}‹H`l?UaAW^BR[>PWDWX;F\)8;¨˝·GRgŚ—íčŇüäÖůäĎ÷ăŇôäĎřćĎöĺĚ˙öč©°Ug{T]]ŰÚÔíßËţčŇ÷äĎőäŃőäŃřäĎóăÎôäĎôăÎôăÎóâÍóâÍóâÍóâÍőâÍőâÍőâÍőâÍôáĚőâÍőâÍóŕËöáĚöáĚöáĚöáĚőŕËőŕËőŕËőŕË,9G!,:7=H #,/.3›ššą»˛ŔÁ¸a|Jbh?UZ>MTEDS¬ ŞýćäüáŇj™HV^;IU:P`mtsúçÔďâ×r‡ŚUnt4OYGVXááŐÓŘĚgz~>[e9TZ7EIÝäîx’8I8IŽ˘}Śťv“ˇ µz’¤cz‰q—Qit<R]@Va6NU<KW<LX3CO1AM/<H:HT;IU(6B(:G*2A'%0F85áŃż˙óŰúäĎţčŘěćŰüčÓňę׾ËĐu‘¨…ź˛—©†ˇĽxŽścy‰Uny=VbCVbG[b?NWDPYHZZEPe@QSPhbP_tZbjóî×üŕÔűćĎůćĐöĺŃöćÎ÷éŃđčÜ{†Uk€\hnŰÜ×čßÎôäĚőäĎóäŃňăŇőäŃôăĐőäŃőäŇôăĐôăĐôăĐôăĐôăŃőâÍőâÍőâÍőâÍôáĚőâÍőâÍôáĚôáĚôáĚôáĚôáĚôáĚôáĚôáĚôáĚ?KT.:F0:H1;JCMW?JQ>LPCRP8KY:NR>RR=PW?M\BIVôôöřóčeŤ™IRULU_/J]Wae˙îÚěŕÓx“ŁI_c@[h8LXqxw¦®®q„‘LdtIZ`2LTHQ`’ˇ˛‘ŻŔNj{.?Pet„^|†rŠ n‡śx˘o`{‰8P\=Ua<V`AQ^?P^9JW6GT7GT6FS8HV8HU7LW8DQ;=EéáŢôćÖňĺĚýíÚüčŮňćÚ˙îŃőčŃąĹĘRp‡/@*<K2@;KWdw„&9D9OZ@V]-7%2:AKTL\[CLaGXZF`[FVmIPX˙üá˙äÖűćĐůćŃ÷ćŃ÷ćŃëŰÇŔ˝˛˘®ł=TlWclvxu»° đăĚöäĎóăŇóăŇőäŃőäŃőäŃőäŃôăĐôăĐôăĐôăĐôăĐóâÍóâÍóâÍóâÍóâÍóâÍóâÍóăÎôáĚôáĚôáĚôáĚőâÍőâÍőâÍőâÍ@JR?IS/:I%3C(8J&9G-BI7OU;FU@MR;IJ5HO1JZ2L[-CEL`O/TdMRSKPY4OeGRV˙÷áéŰĐOm‚gz}:TfCWjPXb‹“ťl}“G[nCQV1N[CPaŚ›s‘˘sˇŹ lz‰]{„tŹ¦n…ś€™®o‰šQk|4O]:U`9T`<O\;O\1ER*:G=N[<MZ?O\BQ_5SW-@G9CGáâŰůňßëŕÉűîÚřčß÷çÔ˙čĹţďеÂŔo‹žz’˘w„ŠNW\FVd5GQVkuAU`GZa8GP5?G?FQ*75ILeK\^Hc\@PgAIQ˙űŕţâÔýćĎůĺĐ÷ćĐůćĎúčŃäŢĐ•ť¤E_xWbj¨«ŞďćÔôĺÍóćÎňäŇóăŇőâÓőäŃöĺŇőäŃőäŃőăĐőäŃőăĐőăŃôăÎôăÎôăÎôăÎôăÎňáĚóâÍôăÎőâÍőâÍőâÍőâÍôáĚôáĚôáĚôáĚ9JP4BH1<C/8A-5>'%,;1;J6FN2DN3FR2ES1DP8IS7HR1?L?P];P_5KX@P\>P^J`rq…•ft€BX`9MW=P]7K[Ž˘˛Zr|Kbk4MT7PZ.KV…ˇ˛wŹ¤n‰źkžh…™f‚”uťa}ŠB]jXs€d{Š@Tc?P`=P_8CQ*7+<I@Sa8LY2BO(6"+:ALS6=G7:>’“îçäřîŕ÷čĐ˙ëĚęëŮőäŐňäÜŁ«©yŚ›v†˘s†Ąs”Żi}Ť^s…as;N\I[f@QZ;NU6JP;M\@RV>HQ,3@-7@CEJ¶±¬ůéÔŢáÖüęŘöß×ÎŃÝĄÄŐˇÄĎ’®˝“«Í†˘´lŚ·żÄçâŰňâÔóĺÎóĺÎńĺÎóäŃóäŃóäŃóäŃńâĎńâĎňăĐňăĐńâĐńâĐńâĐńâĐđâĎńâĎńâĎďáÎóâÍóâÍóâÍóâÍňáĚňáĚňáĚňáĚ4DK)9BEOY2;D4=G"0)2?1=I6EN:IQ5EQ7GT8IV9IU5CL(.?L5ER6GT<MZ7GT3CP@P];KX4JQ3GS=P]>Qa:M\H[h6JU6KR2IQ2JV`wd}Źd|z“§a|ŚqŚťhŽ<SbAYh;O^AVe/DS=P_=P`<IU5EQ2DO9NY8JU-<I+9EEP\:KW)8D(2y}‡¸»ŔŰŮŐĺäÚëčŮÍŃĹřěâüňꢰŻt‹›Ž¦—®m‰k‚–§h{ŠBUbEWbCT]BT[<NUI]dK\cLY^9DLLU_/38ëĺÜúęÖďćŐúćÎ˙ňć‚„ŹwŹŁ‚ź©g~ŚuŚ¨a}‹Seo]bdľ¸˛ńäÔôĺÓôćĐóćĐóäŃóäŃóäŃóäŃôĺŇóäŃóäŃóäŃňăĐňăĐňăĐňăĐňăĐńâĎńâĎńâĎóâÍóâÍóâÍóâÍňáĚňáĚňáĚňáĚ-=J+9E#/)2?-6@2=F0:D2=G3?I<GT6DP/@M5ER1?K9DQ#/9'7E4DQ;KX9IV@L[9FT)+8F4JQ4HS8KX8K[3FU8KX1EP8MU<QY6IU!4A)<K^rgz‹{Ž vŽť9IUK\iAQ^FZf?R_?Q^;N[<S_BS[5FO:MU;NU9MT:KT7FO=HQ4IW8IV1CQŠś©et^luëř˙ ¬˛N^[ČÄÄőö󑤦–Żżn~’|ŚśxŹ™h|Ťs‡_rDWdEWbK\eM_fGY`HYc@NTfqt^gn=GQEKOřôěřéŘúëĎýćÎóćŰ‘Łt’¬~™©~”žh|’Wn~HZdfoputkđčÚôćÔőĺÓôçĐňäÓňäÓňäÓňäÓňäŇńäŇńăŃđâĐńăĐńăĐńăĐńăĐńăĐńăĐđâĎđâĎóâÍóâÍóâÍóâÍňáĚňáĚňáĚňáĚ)9F)72=K*3@%/9=GQ0>E6CK8BL6BN4AP5AO5BP:GUDP\8BK1BO5ER8ES8ES2?M8BP)7.8F0EP6HR;KYCS`%6C$5B2BM5EQ7JR=MV&6C+;F/<]lyM^k9IV-8C<GS@NZ(3EP8LW8LW<S^CS\:KT?OY@QZFXaFU^?NW<GQ;LX8HU7IVN_lSgw?Sc¦ĽĚe{ŤF_d\dlńőúVns$2-?P3>Mn‚”Thy0?9LYEWb$4=)0&8?*9B2=C*.sJW^CKPňńéőçŮţëÎúćĚçŕŮ|¦Kh‰j‚•\mw`t†[n{@R\OY^_^[îčŢďćÔóĺŃôĺŇóĺÓóĺÓóĺÓóĺÓňäŇóĺÓóĺÓóĺÓńăĐńăĐńăĐňäĐńăĐńăĐńăĐđâĎńâĎńâĎńâĎńâĎńâĎńâĎńâĎńâĎ3BS3@P5?M.7D/8F7AJ6BL(9?-6D)5A3@N1=N2>O#0>'/7E7HU8HU6BQ7DRAN\5?M9DR>HV.?L2BP3FP:LW0?L)9E-:H/<J5GO8GP".8&0&/,%1,:"+.7AFQ[:IQ5FNAT[?U\6OV&6?(1,>G#$-(1(1-=F9AGO\`?KSAPY7ITBUbXp€Tk|1N^@MZ˛şÄq‹•g†•j{Ť7DP\qsK_q,@R`r9LYEWb:KT8JPCV\BP]?JR4?C +.1@G2<?®ŻŞÚŃĹüéŇúě×ŇÖŇ‘«Á†¤ĆuŠśŹž©|•Ło€ŽWfoLX]DGFŮŘÎęáÔóçŐöçÔóĺÓóĺÓóĺÓóĺÓńăŃňäŇňäŇňäŇńăŃńăŃńăŃńăŃńăŃńăŃńăŃńăŃđâĎđâĎđâĎđâĎđâĎđâĎđâĎđâĎ3DQ6GS2@N1<J2;H5BN-9E%2+7(63@N/>O7FV)6C0:H?LW;KX:JW3DQ1AN0<J&4&.;I3CT4ER1CNCS\>MU1?L1;I,6H4GS;IU5?H'0:#'3 )3#0<,:&31>J:ERDQ^DS`@R^?S^9MY1DK6GP+9B +5&2<&1;0@H)207=$(.$17'-:MT?R_J_n,L[CS_z„~™¨g‡{ŤŁ‰—¨by|[n“§¸M`o7KX?Q\>OX<NU:MS@M\BNYEPSARX:MU:GNŕăâóîĺëâŮŇĘŔ““ź¸w°‰–©‰¤|ŞO_kSblVcgAHGăăŢăŢÔóćÖóăŇóĺÓóĺÓóĺÓóĺÓóĺÓňäŇńăŃńăŃňăŃňăŃňăŃňăŃňăŃňăŃňăŃňăŇńăĐńăĐńăĐńăĐđâĎđâĎđâĎđâĎ3EP6FS2@L.:F.:H6AO0>L%2@%3?.:I1AQ/?O1AQ/>N0<J8GS7HU5FS5FS4ER2CO,9?P\=MZ5EU0BN4CO3DM%.%108F29J8IZ8HU&.;%*5(.9'1:,4B"/= /:3AM:HT?O[:MX@R]=OZ<Q[6GS0@L9GT%)1>0=I8FS$0&.=.6C;GQ:KQ;MT3FM<MXAS`-IZBM\~‰”š§Yz‘uŠ Xey[r|ThzOcu{ŽťDWdI[fEV_ASY@SX;I]?MYBSYDW[=S[<PXŞłłíéăŮŮⶼşYlpv“§z‘‘˘„ h‹˘UbnSclP\cOZZEJFęćŰíăÖőĺÓńäÔńäÔńäÔńäÔňĺŐńäÔđăÓďâŇđäŇđäŇđäŇđäŇđäŇđäŇđäŇđäŇďäĐďäĐďäĐďäĐîäĎîäĎîäĎîäĎ4HO1BK7FR*7C-8G09K-:J-8K.=H+<I/?O';J*>M.>N,<I4BN5IV3FS4HU4ER/@M(9F)9E5FR.>O2DP3CO2@H)4=8DO5=K4;M(<M)7H -',6-0:).9/8F1>O&7C->K8HU8IV>O\GWe;LY6FT3CQ8HU+4C#18@O?FUCQ_%3'0G6DX6GS1AN<PW;MX7KX>Qa3P^@JUEKX6Qb'J_‰žĽdt‰ &2Pcu/A1@AUbEWb>OX'9@L^c?NdGXf@PWDX^8P]H]fS\`ŐÔΖš^fm…śž]{Źfw“}€ŤšŞeŽ©U^jNYdAPVWehU]XöőěîäÖúéŘńăŐńäÓňĺÓóäÓňăÓňäÓńäÔńäŐđäŇđäŇđäŇđäŇđäŇđäŇđäŇńäŇđăŇđăŇđăŇđăŇďăŃďăŃďăŃďăŃ0=I0>J(13<F.8A2>J0=K1>M*8D,=I'8E+>M.BN2DN3EM3CI1@M/?K1AN4DQ6EV,;K+9L/<O/@J0AO,@P0CU+>P/?Q)9I*7E-<M);G!3@#1?#.="2>*8D+<G*;H-?L2CP5IV2ER9Q\:Q]8Q],CM 7B"7B:MX9JV6GS&2,8.EN5HR=MY>KW4?K4?KCP\<IU;JW8ETAMY:CO2<IDTbuždy’9IT0AM1CM2DOCVa*;D<LV$.")'4<E*4<DPWKW_YfoGY`€–Ą@Uew‰šPaoQbrt‡K^o<K\LdiEX_HX^@EK=<>ŤŠ‚ěä×íć×ďëĆňčÝěçěÝăŰŕçŘćäÚîä×öćÍěĺÔíĺÔíĺÔíĺÔëăŇëăŇëăŇëăŇěăŇěăŇěăŇíăŇěâŃěâŃěâŃěâŃ,<I+7-9E-9C*6.9G*7G-;M3AM0=K-=J.>N0AN5EQ3BK1BH3CP4DP->I7GT6FS2AR1@P0@P0@L0@L1BO7FW6EV+:K+8F*6B,>K/?L'4B#.<)1>#/;'3?)7C/;J0@M1AN4ER6JW;N[.EQ/EQ/EP-@K+@K8JU<LX5EQ1?K9GS8NY2EO%1)58DP3?K/=I-:F,<I5APBNZ'4=)5 #%5F(9M0@L5ER3BO:JVFVc!2;6GP=OX"*3DLU9EL>HP)15BJ,4<MRjzDXeat€zŤťViwCUfi{Śx‰śH[bNahFU[V_cLQRŘ×ÓćáŘęâÖćéĐĎĚČŠ†ŠäćÝććÓęä×ěä×ňćŇíĺÔíĺÔíĺÔíĺÔěäÓěäÓěäÓěäÓîäÓîäÓîäÓîäÓîăŇîăŇîăŇîăŇ2BR3CP1=L)7C-;I-:J-;N/>Q4@K7BP0<M-<L3BS7DR9EN8CN8GP1@I2@L9GS1?K1?J.;I,9G5DL/>G->J3CP:JW2?K-8B09C0AN2>L)4B(0?)1>%-;)1?*6B/9H0=K2?M3CP:JW=N[8HV7JX7KV5JU7HS7IT:JV1AM6DP;IU5GR4DQ3AM=IU8DP.:FFT`6GR3BS3@N@LX"+5.8B'09*6B0;F2?M0=L2AL8EQES`7FOCR[APY<FNFQY<GOGQY&4<:GOGT\EQYWiq6GOI[fSdpzŤśl€‘l’i}’I]aIYa4@EALT>BFŠŹçčçŢÜ×âň妪°XW]ęéŰęçŇěĺÖěăÚěĺÖíĺÔíĺÔíĺÔíĺÔíĺÔíĺÔíĺÔíĺÔěäÓěäÓěäÓěäÓëäÓëäÓëäÓëäÓ5GX-=M9IV)6E*7E*9I)9J(;-"0.;K2?N3@P-:H!.$-7".8%0:$09*6@=IR.9F%1=5AM8EL0<F1?L7DPDR^2=G3=E,6=.;J4?M,5C%-:)/<'0=-6?/9C1:H4?M9DR;HV?KY<LY<MZ7HU;MW9JU5HS<KX8HT3DP9FR:HT3DM1CL9HQ?JT'0/:D2BJ%7?'7H7DR@KW:DM7?H*5;8?F3;@4=L@HV3;H9EQFR^NYcJV`DOZHV]DQYES[AOWCPXFS[IV^@MUDTZBQXEV_br~x‰–t‡–fx‰H]pIV\R`fLX^JS[U_b†ŚowzĄ¨¬Ś¤¦•ž[]iÜŘĘîéÎîćÔęâŮäăŰěĺÖěĺÖěĺÖěĺ×ëäŐëäŐëäŐëäŐëăŇëăŇëăŇëăŇëăŇëăŇëăŇëăŇ(:K.>N/?L&3A,9G2BR-=N!3F08F0:K9GV5@S.;J/<J'3?7AJ*6(4%1=*6?-8B+4$.)3%()55DP&2;)0)0"*-$/>7?L)1>',9#)6 &0)2<+3=-6E.7E'2@*4B<IW8HU:JW@P]<LX5EQ9IU9IU9IU7DP6DP@NZ<KS>MV>IT@IS1>H7BL6EN2CL=IX8ES&5@&1>2=D$+2"'4;<(/?$409F7@M?LX7CM&1<&6?1BI8IOMYaGT\VckN[cMZb;IQFQW;JOHU]CS[DR^4DRgx„6GYJT\R^dCOU>JPEOWIS[blt‘<Y_}ŤˇOQ^ÚÚĚďęĐîćÔěăÝćĺÜëäŐëäŐëäŐëäŐëäŐëäŐëäŐęäŐëăŇëăŇëăŇęâŃęâŃęâŃęâŃęâŃ.>N;KX<IW+:F1>L7DT+9K)8K,7E.7I/:M0?Q/=P6CS/;F/;G+8F&3A,:F)7C/=I,:F+;C$3< ,6(4@&5A-:F*6$+$$(+8)5A)'5*#"-)3%+9)7"08DR;LY:KX6GT!1=&2/;(4)7C*9E.<H$1>&6>/;E.8B5?I+4>9EO.=F3DM:HT3@N0=L.<H-9C"*4(*/67&-=")8)2?;CPCO[AQY7GO;IR*9@/>E,2/5(5=,9A2?G9FNIS\?JRGRZ;FM0:D7AK%/9\foEPWQ\dGSZ>IMYdh+6:ISZhoyOin…“¤\`nĐŇÉçäÎęâŇęăÚçăŮëäŐëäŐëäŐëäŐęăÔęăÔęăÔęăÔęăŇęăŇéâŃéâŃéâŃéâŃéâŃéâŃ"2?!.:'3*6@*6B9DR4AQ-;M.;K2?O1?Q1AR4DU4DS/<J0>J.=N)9I+:J%6B*;H0@L&6C*:G.8G&3A*6D'8E/=I'2=(-"-0&4A+7C/7D(1%.#-".5$.6"-<%0>$2@,8F1BN9JW:KX:KX*7C1>J0=I,9E1?K-;G9JV%6B/:E(2<+5@(2<(1;9EO.@I6HQ5AJ0<H5AP.?L(4C'3=&/9(06,2C)3@)1>4@LAO\AR[<LV;OW1CJ=OV8JQ<KR?PWJW_<IQ'4<6@J09CCLU3:C:@F29@;=EHJR@KUV^hNY\GTU1=?HUVMY\SYbCVSR[hgj{ą˝ąáäĐçăŮčßÖîçŘëăÖëăÖëăÖëăÖęâŐęâŐęâŐęâŐęăŇéâŃéâŃéâŃéâŃéâŃéâŃéâŃ0<H*7B7BK'1(2.:F4AO1>N,9J)8H*:K*=N-?P2BR,=J0?K-;O+8K(7G)8I5EQ2CP%5A*:F&3A.;K&6F0?O1AN(7?!.6%16+<H-;G0<H )3'1(2&19%3:"/?%2A)5D,<J.?M;LY7KX2ER7CO1>K6DP4BN3AM3@L2BN3CP7BI7@H;EMELU6AH3@G+?E3GM19C1>J5AP,<M(8I%2B(3<,5=,6E.6E,8D/=IANZ>OX7KS<OW=PW@SZ<OVEV\DU\>KS<JRBPW@HW?HRDIU@EN9;D*(/<=@HDF>JTV^h?IM9EGQZY6>APY]KSYR`VJR]EJ[^fdÖÝÍŢÝÔňčŕńĺŃéăÖéăÖéăÖéăÖçáÔçâÔçâÔçâÔéâŃéâŃéâŃčáĐéâŃéâŃéâŃéâŃ$@Q$<M+?N&7D)6E2>J7?L/;D,=H/@M3CT0=T-<O5DT3>J7AI+:B/=H,8F,9I1>O3?M.<H+:B-:I+<I)8I0AQ,;K.:I*7$-7(9K6FS+9E#.5+2*2%08$0;$4<&5=':B,=E*=H6HS8MW<O\7LV8MX0EP5GR2DO0CN3CO4DP3MT/HP8NV?T\"1: *&0!(2'4)50=I%.7)2<%.8-2>29B'-63;E2>J-;G@P\<LY7EO0AH9@IGNX5@G(2;KV\JT[MT[DHO>IQ>KP>IO:EL3<C5<@:@F=DIAIOMW^NZ`HTXNZ_HTYBOPIPT3GGL\YFPKQUOéçŢäâ×ăäÓâĺŐćâ×ćâ×ćâ×éâ×čâ×ëá×ëá×ěáŘëăĎëăĐęăĎęăŃéáŇçâÓćŕÓĺßŇ+BR*@O4DT)6D+6D.9G+7C,7C5EQ'9E.>O-:Q0?R5DT3AM/<D1AJ3AN5AP.;K6CS4AO0>J-<D/:G(5D(9F/>N3DP(6B(1;!-4*:L.?K'5A!,3)1!,4%08'3=%0;,8B%4=1>K5ER6HS5ES8KX3EP8JU+=H0CM9IU.>J7GS3CO2IP5HP6IQAR\0@H,8B*4>6?I.=I'3?2>J(2<%/9 )"..6>#,!++7C3@L<MYEVb(7@"39(1;",61=G8EM&.#+"(*28ALTCPV?IPDLS5=D>DI.49?BG<DKISZHTZAMQJVZT`dIVXFNRN][HUUNVSab^ďěĺĺăŘćĺ×ęęŮŕăÖăă×ăă×âă×ăá×ăâ×ćâ×ćâ×äáÓäáÓááÓâŕŐâŕŐâŕŐâŕŐáßŐ0BM1AL7ER)4B.9G-7H(5E.-8-=,<M,;N*9M,;K*6$.'0 ,-%2B5BR)6D!/;.6+3=!.:&5@5BP7EQ+7A$,5'18*;L6FS-;G!,3)1!,4(3;$0:-6@'0: ,9#/+8D7HU1AN9JW2AM(8D/?K(9E1>J>LX1?K@NZ5CL;JS=MUEPZ?KU/;E1:D9BL/>J,7C6BO+5>%/9"+5(-9+2;*1:(1;(4@0>J:JV:KW>MV5EL:FR8DP8FS<KT5DM@LWAMT,4>,8@&07)3:,4;"*2-380386:?DLSHRYAMT6BF.:>+7;5BC=FIANNX``LQQPQMĎŃÇŕŕÖčĺŰáßŃÝâÖÝâÖÝâÖÝâÖŕâÖŕâÖßâÖŕâÖÜŕ×ŢŕŘßŕŘßŕ×ÝßŐÝßŐŕßŐáŕ×5DM6AM=FS,5C/7E-7I/:L"0C&2@,<L*;L*:K+;L3AQ-9/>F(7@-9-9H'3D.;K&2@"/;%.&-!+5&2>3?J ,!+"+$*(9J*;G%1 *2$,'/$0;"'5&/<'3%2A:FT7GT'7C!-%5A#/-9#1=$0*6B!- +5 * *#-+5.:D,9C5AK4CO)5A6BN4=G&0:$-7(.9*1:.4=*3=(4@0>J5EQ@P\@OX=NT:GV@NZ;KW9IU9IV>NWFR\8CM:CL;EL4?F8@G-2:3:?8<A<?D<DKISZMZ`HTXEQUEQU>KMBKN@GJ?DEHMLTXWăăÝáŢÖćäŰääŘŕâÖŕâÖŕâÖŕâÖŕâÖßâÖŕâÖßâŐÜßÚßŕŘŢŕ×ßŕ×ááŐŢßÓáŕŇâáÓ2>H'2>&/<+4B2;I6@Q.<O*:K,:J.;K-;M-=N,<L4DT-=J-:F,=F-=I*;H(7G5DT6FS'7C&8A*5<&/9#/;/;G.:F)3<$-")/&7I*;G!/;&-!)&.(3;,6"*8(1>'0<)3B%3@7DR<LX4CT.>J0@L2?K-;G0?K2>J1=I6BN4@J.:D7BM8DN6BL($.1=G&5A)4@6BN7@J%/9#,6-3>+2;-4=/7A(4@/=I7HT?O\IXaCTZ?KZAR^<KWAT_8GTFU^COZ>HS;CM<GN>EL=FM06><?D7;@CEJ9AHKU\MY_NZ^LX\MY]KWYHQTUZ]PUVKPOOTRĎÓÎŕâÜĺĺÜáâŘéçŰäâ×ßÜŃăáÖŕŕÔääŘááŐÝÜĐŕŢÔŕŢŇçäŮáŕŃŕßŃÝÚĘáŢËćäŃ"0< .9.9F*5C!,:+9I/>O.>N3<N1>N.>M-=M+;K2CO+;H.>K4EM.>K3CP,;L2AQ9IV*:F,=F4=G*7C&4@4AO7EQ-8B#+4",3+<M)9F(6B *2!,4)1(3;$0:,4A)1>%0?+8F,8F5FR<K\8HX7GS7GS4DP5FR7EQ6DP7DP<IV8GO:IR9HQ?IT9EO*4",6+4>!-$0+7C"+ *4&0)/:+2;.5>.7@(4@-;G:KWDTa(7@"28)5+77GTEV_+=F+:C:GO)4<'0:)18.6=.4;#*126:,/41389AHCMT:FL0<@-9=.:>3@B*46;>B:?@=ACIRQŘßÜŘŢŮŰßŮÜßÖćâÚßÜÔŕÝŐăŕŘÖŇĘĺćÝÝŢŐăäŰäâÖßÜŃâßÔáŢÓŰÚËććקĄ—ąĽ¬3CS+;K/?O&3A/<J2?M1AL/AL3=O3?Q1@P-=M/@L4ER,=J2BN0AJ-=I1AN*9I4CS:KW.>J->F/:G.;J'8E0?P8IU+9E%.8)1+<M/?L5CO*1 +3)1$/7#/:'3?)4C'4B)5C&7C2BS9IY1ET7IS;MX8JU4FQ8HT8HT6FR>NZ1GN;MU8LS=NX;JS0;F&/9;EN)7D&2>:GS0:C%/(!&2(/8(.71:D/;G*8D>NZBR_?MV<MTBLW;KSAPYGZa8IO5AJ>JP7BH8?H:BI:BI8>E(+326;/271386>EHRYKW]JVZ@LPAMRJVX>HKIKOHLM?IINYW»ĆĂľČÂĐ×ŇŐÝÖ×ŰŐâćŕÓÚÓŢĺŢ×Ţ׻¼×ßŘŐÝÖŰÜÓßßŮÝßŮŐŮÓäëäÚáܬ¶°€Š2EW4EW8GX&6C)5D.=H0AM,>F37M4=P1@P/AM0AM8IV,=J.=N,>F.>K.>K(7H6FV5FS-=J&8@+8G):G$3D/@Q6EV+8F'4@'2*<M1AN3AN)0'/)1%08'4>#1A$1@$6C'8E):K1AR3GV5GW9NY:OZ6KV:MX5HS5HS1AM:JW5OV3LT4JR7KS;JT1=G%0:4=G6ER*5B6BN2<F)3(2(-9$+4%$-7+7C*8D:JVBR_HV_DT[GS[FRZ?PW@PW>NTBPVKV\?IO;AK;CJ7<C@FM.1:15:58=79>4<CBLSERXHTXHTXFRVJVXFOSNSULSV=GGANLw‡‚z‰…ž§ˇĽŔ»´ľąÇŃĚ“ť——Ąźy†€o€xt…~ŻÄ˝ČÉČľÂŔĹĘÉŃÚÚv‚‚v…‡‡š›dx|*KS2QY0GR-?J.<H.:F7?L3;H1AI6FN7GT3BS/?Q3BR4@Q1>L-<D/>F4BN)6D0<J;IT1@H,:C4?I/;E+9E4BM8FR2>G+6=&06,9F7DQ:DK$.4#*1%,3*3<)2<06>/8@-7@*6?.<H2BM8IV8LY<JRAOX>LU=GR<GQ@KU@LVCLVEOWDMU:DK:DL2=D.4=04=?>H5BL%2;5AK5?I&/8"+4&-5%,5$-6,5?,4A-9E@MYBR^EV_9MTBRYGW^=MTAQX>NU>OVEV]:LS5?F=GN3<CGLT,3758=26;:=A6;BHOWJUXHTXJVZFTUDPR/=>=@E9@B;CGFQRizwaupn‡~b{rl^ui‡d}|[rp[ljcqk}Š}m|cvw^uv”«°t‹‘Šˇ§wŽ’|•.JT1JT2FQ/?K1@K4@L -8*"+,9/?L,<L4DT7FV&3C)7.7!09#1=,:9FT4BN'6>-6"-&0%4@5CN'5A)"*!(#4B0>J#,6'0%+$.%.7#,6'2(0:*3&3$2>6FR3DQ)=K,4!* /8$-!,6*5)3'1%/",&0$/+7B%/#03> )&02>H*3>'/$-6%+4&,5"+4(1;*3@/;G3AM@Q]CT]6JQ&6=-4,<CHX_2BI-=D3CJ1BI'1)3:%-419A!&*.3$(-,059?FGOV2;C+7;/;?/;@;GI9FHJPT?DI>IMIVXCQSbwt\sp_tsUthpŠ`|rczucvt[libpn}Š‡y…Ž‹›ˇ«¶„—¤ŠťŞzŤš{Ťn€‹4JV8KX<LY1>L+6D5?M(4C!-<,<D*:F2CP/>N-<M1AQ"3?"/=,4$1'5@$1?1>L,;F(5$3<(3=-;H"0<.?L1>J*5?(/ &&7E-;G%/"+
$(1&0)*4=&.<"-,9E:JV2CP(8F$5==NW$5>3AJ/>G.>G2=G'2<3CL-<E2CL3DM9HP/;E#,6;?J$4A#,/<E(2$.$(1"(1$!*4(1>'3?1?K=MZ8HQ(;B7FM?OVGW^BRYBRY=MT/?F0AH4=F@IR5=D@HO(-5.59,/41498=DFNUFPX?KN>NPAMQBNR<IJBJQ<FM<GM;IOy‰Ž~‘|Ź–xŽ•]tpvŤ^wlUja\nfdvr_jnt‡`m{s€‘x†w†šfwŠ[j~m}Ź^l.>K.>K5BP/9G/:H0=K.?L(9E.;H1AM3DP,@O+>M7GW/?L+9D1@H)7C+7F"/=1=K7DR2@L-<D,8A+9E"3@2BO9IV1?K(1;(/,=K9FR7CM)1 *$-(1;!,5(1?*2@(5@)8C,=H3CO:KX9JW2EL5EN6GP5FP5CLN\eKZcN]f?PY7JR7IQ7JR7HR0?H&2<5?I4BO"/+7C;GQ!+#.!*3&/#,5'0:*3@&2>2@LAQ^EV_BU\BRY@PW?OVAQX@PWAQXCSZCT[2>EAJS+5>DLS05<+1947<48<1:@@JQEQWESZFVXBRUAMQ<GK?IPAMR1>F>MVv†’w‡•l€Ťr…–cvz^qnXkbRdV\nay‡„cqxw“cp~z†—v„—{‰ť}‹źfwhwdq‚(7D*71>K1<J"/=3@N4DQ,=J2BN3BP1@Q+>M(;J7GT8HT)9F.>J-=I.>K&5E4CS7GT3DO,<I0>K/=I(8E4DP8HU8FR(4>(0(:G3DQ7CL&18"+ )1%0:'0>'2@+6D*8F0<J,=J<KY:LW>P[8KS8KS9LT9LT6GP5FO:KT>LU5IQ9LT8NU9NV7KR5FO+53<E5CO!/;+:F8DQ",!+6"+5$-7'08&/9'0=(4@-;G?O[CT]>RYJY`GW^=MTAQX?OVHX_AQXGW^/:BDOW6>H@IR-6<16=/6=45>/6??HQIU[GU[DRXBRTEQU=IM=JP=IN6BJ<KT`p}eu†N]nQdw:JPWfiVf^M^Q`ndhts„Žir…Wfobt|Xht\mzOancrJYbJW_-@O1@P5DT-<L.;K1@Q1AR-AP0@M3EQ*=L)<K)<K4GT9KV,=F3CP4DQ4DQ)8H7EV8HT2BO.>J3@L->K$4A-=M<MY7EQ*6@!,3,=N4DQ6DP%/9'.",6)3<*2?)7H+8I,9F->K0@M9IV<NY;MX;QX6LT:MU=OW:NU;LU=NW<MV;MY<MY;OZ<Q\:LW4EQ*6/7E/@M!.:+9E7CO(5",6!,6"+5)2;&/9&/<'3?*8DAQ^BS\-AH$4;(/ 07AQX<LS&6=(8?$5<+4?BLV2;CBLT28B-5<06=4:A39B>GPLV_ESXCTZCQWCQX?JN=JP9EK6CK;FP;IVUfs[kxSbtcv}kz}bnn†ŽŚ‹“‘{‚…qw‹–_otv‰Źarzp„‹bs|ex~lz€brt2IX0ET6IX-<M,;K1AQ3CS+>M.>K8HX2ET+>M)<K2ER9KV+<E3CO6FS6EU)8H3BR8GW3CP2BN6DP1BO)8I2BR6EU6BP-9B"+5/@Q4DQ9GS)2<$.#-7'0>'4?)9I+:J,;K/?K,<I4DQ7JU:LW5JR9NV<QY9OW<NVAT\EX`?RZ;JW9KV9KV;MX9LW8FR!.94<I1BO$5B/<H7EQ(5!+4#-7",6)1:&/8%.;%1<.<HCS_AQZ&9@5EL:JQ?OVBRYEU\<LS@PWCTZ3<FEOY1;EDNW07@18A39?27>1:C=FOHU]BSZFV\CSYESY@LR>GOBKS3?ELW_ERZ>ITM]fZirŚ ĄaqwĄ°·†‰‘xz‚{~‚‰Ś{„‡^mv€‘™FVb• n~Šx‡{ŠŹDPV0M[0LZ7M]1EU0AQ2BR4DT.AO0?L4CT2ET*>P+AP4HT;OU,=E3CO3CP5CT+:J2AQ:IY2CO/?K8FR3CP(8I1AQ9IY7HT2>J)3/@Q1AN:HT(4>$.%.8(0>(5@(5J+9L-<L0?O6FR9IV5DP;LX5MU9MU:PX:OW@V^AS[AT\?RYBQ^=LY:LX<NY9HU6DQ"*82:G3DQ&7D.:I2AM"/;"+9#-7 *5(19*3<*3A%2>(7C?O\HYb:NUBRYEU\CRY;KRFV]IX_:JQGW^1=H>HR.8CAIS09C.5>04>49@/8A>IQER[FW^DTZBRXDRX?JQ@KN=HK<FM7CI:FLAOVSagVbir‰ŤK^epy„ccstp~lhrvyx„Š‚cn~w†—z‰šs”q€‚Žťgoz~?O\?NZ7FR1?K1>K2AQ/?P.?S/CO.AN3FU.>O*:K5EU9JX0@M2BO4DQ4DQ-=J2BO8IU5ER0@N4BN0@M"2?1AR8HT6DP.:C",6+<I:JV4EM(7@%/%2<'/=.6E*:A+9E,<I/>N.=N:JW8KV9MT7JR;NV<OWCU]>QYBU]<OWAT\=QXBU];NU;NV=QX3BJ(2/8A.<I+9E0<H8DN&0:$/8&/9&.7$0;)2<+5?.8A+4>=LUDU^>RZ>PWDV]CV]@RYEX_FX_ASZEY`9EK<HN2<C?IP.6=6;B06=4:A7;D;BILX^KX^EU[?SVARU6HJ?HS:EN7AIGPTCLOGSTT`dQac7JRJ[bS_e[gjo{~Ź›˘Ł°Ľ|‰™Xqvt†Žr}ŠŚśl€Źm„Zovo|„/>O8IV<LY0>J8ES4CS/?P.?R3FR2ER6IX0@Q,<M4DT8IV-=J2BO3CP4DQ-=J0@M5ER0@M.>K/=I2BO 0=1AR?O\7DP0<E"+5+<J9IU3EM+:C%/#/9&.<,5C,<D,:F*:G,:K/>N9IU;MX>RY:MU9LT8KS7JR@S[@S[>QYCV^=PX>QY=PX:MU:MU2AJ ,61;D;JV*8D6BN8DN*4>",6%.8&/8%1;)2<+5?,6@7@JAPYGXa-@H7GM2AH+;B1AHCSZ#3:$4;%5<)/4AG09@@KQ08?.7>27>39@9>G:BIIU[ESYCSZCSVBSV9JM<IQ;GM:EI?HL:ED?HKNZ\OZ^5HO8FM[gk_kmZeikv}t‚Ťx‡—_u{n~†‹”˘r}‹t„‘u‡•ct}x†Ť':H%5E$1!2=$1,;K1AR0AU1DQ3FS4GV.>O.>O7GW9KW.>K4DQ6FS7GT0@M/?L9IV6FS-=J1?K-=J#3@/?P7GT8FR0;E!+50AN9IU5FO0?H&0!.7&/<,5C+;C,:F):G-;L,;K3CP7IT:MU8KS9LT=PX?RZ9LT=PX@S[CV^AT\?RZ=PX8KS<PX4CL$0:09C4CO-;G/;G:FP,6@!+5%.8$-6%1<)3=*4>,6@3<F>NW>OX!5=)9@%5<-=DAQXAQX4DK>NU?OV9DJBNT2?DBLS29@/8?27>5;B3:D6=DHTZESY@QW@QTCQT6EHETZ<HL6CEAIIbjj^gfV\_NVY?MTT`d\ijJVXFRUix€’˘i|ŹŠťĄŤšU\i}–o~‹u‰”_o|PZd,?Q*=K5FS,<I-=J.>J3CS3EV3FS6IV3FU.>O,<M5EU9JW.=J1AN4DQ6FS.>K4DQ8HU4DQ/?L2@L3CQ%5B1ARIYf/=I3>H!*42CP6FR0AJ-<E)3#/9&/<.6E'7?*8D*:G0?O2AQ5ER:LW:MT<OW;NV@S[=PX9LT@S[EX`?RZ>QYBU]=PX?RZ:NU4CL&2<1;D4BO/=I2=J7DM/8B$.8)2<$-6*6@+5?-7A-7A5>H<LUCT];OWAQX<LSAQX:JQGW^AQXEU\DT[6DJ<JP2>DBKR+5<19@*3:4:A29B0:AFRX@NTFSZDTVBRT8CGFVXBMR2?A=FEMQRBGG:AD9>CCOSP\^forIUWKV\‡–Ł§»ĚłĚá®ŔËy…fm|t|Št{Ťšlz…\er4K[1FT:NZ.?L.>K3CO1AQ4CU/BO3FS6IX/?P*:K4DT6HT1AN1AN3CP7GT0@M0@M8HU7GT/?L2@L4ER3CP+;L3CP4BN3?I)3=->K<LX7HP,;D ,6+5)2?.6E-=E-:G+<H,;K0?O8HT9KV<OV9LT<OW<OWBU]<OW?RZ;NVBU];NVAT\<OW;NV>QY4CL*6@09C6EQ3BN+7C<HR3=G#-7)1<&/8#/:-7A.8B-7A09D<LTGXaAU]DU[DT[@QX<MSBRYFW^P`gFW^;IO1@F3>DFRX-8?,3:.6=-6<3:C.8?EQV@OU>MSCNRFRV6@E@PSIVX0<>>FECLKGMP',1/7>?JNEQRNWZ?KM>KR\mx]t„[t‰_t@O_LVgw„”x‹šr‡–‚’˘Ž—¨2J]4L\>P`/@M5EQ5ER2BS5EU2ER3FS1DS-=N)9J5EU7IU2AN3CP2BO4DQ.>K3CP9IV7GT.>K=KW.?L"2?3CS1AN1?K3?H,5?,=K9IU6GP-<E'1!-73;I(1?"2:9FS*:G,;K.=M5ER:LW<OV8KS<OW>QY?RZ=PX=PX<OWDW_?RZ>QY:MU?RZ:MU6EN-9C,6?4CO2@L*6B?KU7AK!+5*3=)1:)5@.8B-7A.8B3<F7FOEV_=QYKW_ANV4AI#081>F>KS(0 )&4:0>D7EK:FL/9@&18+3:/7>18A.8?COU>JP>MS@LP>JN4<@AMQIUY1>?:BF<EH>ILhtzx‚Š>IPDPTN[\?KM8GJ4GNp‡–n‰šh€”“¦Ž ”Ł´“ŞşŽ§¶“§ą‰–¬0HZ4JZ<Q`2CP4DP4DQ1BO5DU5HU5HU3FU/?P'7H5EU:KX5DQ4DQ3CP6FS/?L4DQ9IV;KX/?L3@L/?MYiv6FV8HT5CN5AJ,6@+<J6FR6GP-<E%1;'4='/=19HP`h(6B0AN1@P.=N6FS=P[<OW8KS:MU<OW=PX8KS=PX>QY>QY:MU<OW=PX>QY>RY6DM0<F09C6DQ5CO)4A<HR8AK!+5&/9&/8(4>-7A,6@-7A/8B4CL;LUBV^$19$19.;C1>F8EM@MU5BJ;HP8IO:HN.<B<HN4AG-7>*5<+3:07@,6=BNT?KQDPVALP:BF5>A;HMGQY1<@=HL;GKCOWGXa2DP9IPCQXIUY=JLFUX;LS|’ť}ĄrŽ¦_vŚhzj‘^zŠ]{Ž]uŠ\p‰2M_+FV8M]/AN/AL4DO4ER:JW3ES3FS4GW0?Q*:L8HX:KX3BO/@M2BO7GT.?K0@L6GS;KX-=J8EP9IVŻľËDSd7ES6CO5AJ/9B.?M6FR8IR/>G#/8&3<3:GmsSbkAN[*:H0?O-<M3CP:MX5HP>QY9LT>QY?RZ=PX<OW>QY=PXARZ;NV:NU:NV:NU:GP5?J-5?4BO7ER)5B:FO>GQ*4>&/9)1:%1</9C-9B+7@/8B.<E<MV=RZCNX<HQDQYAMU:GN8EM&3<=ISCRX>NU7EK;FL;GM;EL:DK6>D6<F+4<?KQ=IPCPW?KO4>A9?C>GQ?IPHRYMV]KY_<PV@S_(AN4FP<MTHSZS^bFUWBU[OcoPitBcKe‚Tl„Pj€Gj~Lp…Li…Tj‰4EP6EQ4DP/<J/<0AM8KW.DP2JV)?K9LX1BN(9F6GT7JW.AN/;J6CQ4DQ*9J1@P3AS0@Q1AR0CTMbqť¨B^g2LU/AL:AO03C.=H9KV7JR0?H)/='-="2C«ÄŐMejH]e/AL.<M1>N7DR>LX?PY9MU>QY?RZ>QY:MU?RZ?RZ>PX3SW>RZBN[BNZ7IWsŠ•*AH"1:6BJ;HP.;C7GP5FN2>H1;E.7B$5>,5>43B12A0<H$6A/ALHSa=TT>RW>PWAS\*:C(6<>HMJWT>RW9MR6FL5FL8GM:GL?IP=GN9HK7FI;GK>IM@HLINS:@E=?D4AG?KQANTFPXCMT=GNBIP@FM7BH?JPGV\FTZJV_HX_JZ`P`fN]hO^jM\hO^jM\hL[gM\hN^j*<I 3@%6C.>K.>J3CS6JX=Ra*BNG]i5HU<LY):G6GT5IV.AN0<J4AO2BO+:K0?O1>Q8IZ2AS/CUtŚś€›¦;V`9R\4EP6BN07F0?K8JV7JR2@I.4B2;IBRc‰¤´OfkEYaEWb1AN5AO;GV<MY=NW;NV=PX?RZ>QY:MU>QY>QY>PX3SW9NVAMYAP^‰ź«TnwEYd!3;5AH;HP4AI7GP7CM4AK8BL8AK-AH1<D58C38B(6B‹ž«j~Š?N\>RW:OSASZ?PY?MW@PV:LOERT@TY<OT9IO9JP<JP=IO>HO=FN<KN8HK:FK:EI9DH9CF39>;@E@LP=IMDOS>IMBMQ>JM<GK7BF:FJ;GKCQWGU\JX^GW\EU\GW^EU^FV_EU^HW`HXaHW`HXaIYb4LX,BN8KZ/?O-=M4DT5GX5IZ~—˘Lbn?Q^6GT*;H6GT7JW1DQ1=K4AO1BO-=J,:K4CS/@O/?O*>P§ľÍ{–¤8S]?U`7IT4?K27G5CO6JQ7JR4BK09F5=KScsqŚśLglH_fCT_+;I1=L8FQ;LU:KT<PW9LT9LT>QY;NV>QY=PX=PX7RX<QY>MZ*:G¨ÁĚl‡“I`j>MZ1?H:IR8GP5@J8DN7CM;GRAIT0FJ:HN>GP<EO
*µÍÜu‰šASeAUY?PXBU[@PZDV]=PU@SVCVX=QVAUZ?OU=KQ>MS@LR=JPBJR=LN8HJ8CG4AD0;>+7:6?B=FJ6<ABGL/9<ENR=HL3=A?KO;FJ>JNAMQGVYFUWIW]JZ`HX^HX^P[cR]eS^fVahU`hWbjYdkYdl:T`5K[4JY1CT5GX<M`8H[;Pa…ť©H^j>Q^/@M%6D3DQ6IV2ER1=K3@N1AN-=J.>K9IV7GW/?P,AW¦ľĐ˘°Tlx<R\:LW5CO8@M4FN5IP4IR1BK;BO7AOŠź°}š¬WpyI_jEYd>MY(8D4CP;LU;LU;NV<OW=PX;NV=PX=PX;NV<OW9U[>PX2AMFXh±ĚÚy•˘CXgL[h6JP5FO9HQ;GQ8EO=GO>KS?KT6ML:LNBLTAOWJcn°ĘÚi–DWnDU[ASZ?QW>QX@SZ@TY?TY@UZHX^EU[?PUGU[APU@LQ7CI7CI?MS=KQ?NS@KQ:FL.:@8AI#.58<@>BF9>CAJMDOS;GJ@OR@OQFRVEPUJY[JY\HV\BRXIY^Ufl_hq`ir^gp`hqajsbjt`hr^gp0KWKdp1GV-AO1CT0AT1DZGZosŚ•Rgr7KV6HS+=H1CN5IT/CN.:I5BP4DQ2BO1AO8HU3DQ3DQ1I`›łÇ†źŻNfq=S^:LW.;H9DP,=F6HQ2IN7HQ?JV,8IŻÇÖUt…F]hG]hDXc9KW*;C3DM=NW6IQ8KS<OW;NV<OW;NV=PX<OW>QY8QW>PX>N\Ym|¶Ät‘ H_oETdH\g1CO:HQ:EP>IQ>IQ<IR>KQ9PP;MOBMU=NYi‚‘°Áq‰ť@UnCV]BU]BS\FX^BT[CV]>PWI]cEV]HY`IV^IV^ANVCPXGT]KX`NZcVckUbjTbjWdlCPXLW_S_g\]fX^dPX_XbiS_eP^dP]cL\cQ]aUadTchYgmWejXhoXio\mt_jq`ksbmtcnualtbmt`ks^iqźµÁ3GS4ER1AQ4DU7H[3I[|‘¦śĄLbm>R]<NY4FQ3EP5IT4HS)5C1>L1AN2BO6FR>NZ6HS3EPOh‚°Ćq‰›Net?S]BT_7GS8FR5HN4KQ2HN4GO7DQO^n’«˝o‘¤IaqAXgEXcDW_(9B5EN:MU;NV<OW=PX<OWAT\;NV<OW;NV?RZ7NS<OV>N[źŻŻŔmźOgyt€•_z‚:NY:JW@KUALT?IR=LQ?OU?SUAQW<LR7JU‡ĄłŹ±Áe€•BVn>OY@R^EV_BT\FW]CPY-4IV`=JRCPXERZFS[KX`MZbR_gUbjScjRbiPagT`hUbjZgnZgoWdl\enYaj]enWaiZgoZfnWgnVfm\go\goXemYgn\gq\ks\ks]mubmw`lv]irZeo]isalv]hrVak_qx0?HDR_8IV0@P.BS6L^łË݆ź©Ndo=P[8JU5GR6HS7KV2FQ0<M5BP0AN3CP3CO=LY8KS8KS·Ó싢¸wŹ BYhK]jI[eCR_.>J:LR2IN.GM5GO)9Feu…‘ľe›]u…D[jGZeGZb/BH:MT6IQ9LT;NV=PX<OW=PX;NV<OW;NV>QY;PX=NZ(;Gľ×ç~ ŻmŽˇHavŻľŃp‹—>T_5ER>GQDMVBNSCQWFV\ARWERZCMW6JUŁŔΑłÁrŤ˘BWm:MZ?Q\8IRARXHUZXaj -+bepSaiYfnYfn[hpWdlZgo\iq]iqYhrWfoYhq[ktUdm[jsZir[js[jr]ktZjrZirZir[js[js]lu\fo^hr]ir_kw^jv\kv\iwYftWgsQamO_kRbnM]iM]iM]iN^jgsy=IQDOY:HT6FS4IX/HXˇşĚ…ž¨BWc6JU8JU:LW7IT6KV4IS0<M8DR0@M7FS8HT(9ANahŤ §tŤ¬Ws‰OhzNdsL`lrŚ†– “Ł¬ŚśˇzŹ”{“—“¦Ş·Â·ĹŐŠĄµk‘¦[q„AXhF\fO`gI[a@RX%7>&;B(9A)<C-@G5HO7JP?QX@RYBRZ<QX1@Ks„“ź¸ÇłĆkŽ Tl€ĆÓę‘®·5NZ<LX@ITAISALR>KR9LM@MVAITHQ^1CO˛ĐÝ‘´Â`}ŽBWj@QaNbmYjsYhm]gmbjr€‹41@gu|gt|cpxanvcpxamvZkqSdkZhpWfn[irZhq]ktXiqWhq[ltZlxYlvaq}`p|^o{ao{_ny^lxem{fm{amxbl{_hv\huZeuR]nL_lL_lL_lL_lJ^kI\iG[hFYgOjp2IN;LU8FR6FS3HW/JZŚ¬»vŤ’>V\8MU3HP7IT4ER1AN1AN18;MX]ozey„k€Šj}‹h~ŠPfsE]iG\gJ[eO_l^n~š¬‚žł¤ąŚŞ»ťŻ…¤µź˝Ń–µÉ“®ĂžłrŚ˘wŚ–OfvI`pG^n{’˘©Ž¨¶”®ş•˛»¨µ†›Ş ˛ś®ŽĄµ€š«¦˛‡ˇ°¦ÄŇ°ÎßšşĐ€ź´žłUr‡¸Óçv›¨Gam>LT?HPESXAQWHV[HSY[ggO^cZp{d~Ź¬Ë޲ÇdŹ@Yi7R^FakXkr`pyvŠ,1>kp~3YhpWgo\gr_ls]jqanu_ltbntWkyWkx[o{Xmx[ny^p{]oz\nz[nx^nz`p|aq}dqdqer€er€crz^nz[jvVgsPcrL`rKcsNfvOeqNepRerWguVfrUeqZgtWfoPjp;PV5HO;KW@P]2ET±ÁśşÉYqw:PU6KS4IQ:LW5FSN^kbr~t‡’\nyRdoL`kM`mK^k>T`>T`4LX=S_\lyZkx>Raax‚žłt“©ˇ±Ž¬Ŕ¦ą®Á§ş…ź´w’¦w’§h~Ś\s‚Yq~–§›‚ť’«»«ą\t€€¤Ś˘˛¨ş™°Á“˝“¬˝•łÂš¸Ć¦ÁŇ–´ĆŹ®Â†ĄĽt”«y–ާÁצ˛<VbCR^ET\K[d>SZFXcQ]jK\aN`jXq€Ľ×뜺ό¨Ľi“CZi=Vb9P[Ymt`kuYclX`mt{Š06Ebs€_o|_o{_o{`nz^lxao{_lx[kxUfsTenTenSdmTfoTfoZirZjv]mxYiuScpScpYiuZhxVduTfpXhtUhuSfuSftRgxThyThzRhtPcpPdqSepXhuZjv\ktXgp\v|=T[3EP5DQ8HUL`l—®ľp‹™G]b7LT5JR6GS9KV8IV8HU:IY7JT9KV>P[<P[ATb5HU9P[8OZ7M]9OZľŃŢRboBVe9QaRl}€ź˛sŽŁy”§„źł‡˘¶‚ť±¤µ›¬y”Ąn†–n†Wp„tŤˇy’¦š®‰Ą¶†¤˛9JWl„“‹Ą¶‚ ł”´É’®Äž˛ť´ČšµÉ•˛ÇŹ®Ĺ¦ż‰§Ŕs‘ŞŚ§Ŕś·Ë…¨¶<Vd>MZ\myyŹš›¨‹¤łž°Âť¸ĹŞĹÖĄĂÖ°Đ虵Μ°^t†DYh=T`9MXWhqbnxCLWHS\DMZ%,;as€^o|]n{Zkx_p}YjwQboYjx]jq]jr^ksbowiv~dqybowhu|ev‚jz‡jz‡fw`o€[m|TixPetPfuOfuQetNbsOctRduPbsM_qOcnPdoUfr_q}XiqRclRakQ`i^wCYd/DN6HR8IV6GTlŤH^j>QY9LT5IP6IT5FS8IU8HY:JZ7JT;MW8JU9LY6IV7JV7L[7L[4N]:Q`®ÂŇ@S`BUb=Ra7QasŤžxŹ¦|oŠź… ´x“§‚ž®}śk‰šy’Łd}‘h„™[v‹|–«t’§Š¨»Ś«ĽDP`AUf‚ź°„¦ş¤»|ťł†ź·”ŞŔ¶Ę”´ËŹĆ†¤Ŕ{™µz±Š§ľ‹¤˝u–ŁB\l?Q`Pdu–°Á’±Ă–˛Ë—¬Ç‰¬żžľÖ«Ěă¦ĆÝš¸ÍtŤˇ]q‚GVg<P]GYdTcl\iq`ksLU`8DNco|_itdoygr|hs}lt‚eq~huivlu|nx~jt{ku}r}…v‰r|„oyap€[jzSbrM`oK_pKbrIbrHaqGbrF_oGaqKcsMasPctTduTdvPbmYkvfz\mvPajL_fIZ`EU\VnzDZf=P]<MZ:LW4FQ>P[9KV7HQ6GP7GS2BN7HU7GW9IX5EU8JT:KX8IV3FS6IV;M]5JY4IX3K]E^n•«şRhs7MY6K[<Sc<Scay‘x‘Ą{”©›Żś°{–ŞpŹźf„•~›«a}‘f–j„ťy–®t‘¦—µČmŚťUaq2FXs‘˘zť±¤Ľw—°€›µˇ·Ď„¤»•˛Ë‚ »{™´y—˛ ą©Á—±Ë|š¨AXh:K])=N”°Á} ´’±Ę—®Ë‡§ŔžżÖ‡¦ľv”©l†šUl~M`oK\iCVcDUc?NWeszgrzZem1=Gkx‚‡{„x~u{x€‡z‚w~‡oxt~†s~…s}„o{…lwit}anz[hsTctN`qM^oI\mI_pI`rGbrF`pD_oIasJ`rOcuQds]m~aq~dt‚\mvZjtVgqN`gL_fIY`FV]BRX]t@Wf8NY7JW9KV5ER7FO7FO<KS7EQ5FR7GU5EQ,<L2BR5EW5FS5FS3DQ3GS3FV5GV2HV5JY+DX=Ug•®ľPfv@Va6LX:LY7JZ8PcMex„ś®€y•©z•©k‰žqŹ¤o‰™i–]yŽh„z•ŞpŽŁ©ČŰ ±O_lAVf3I\^wŽšłšµĐ‚ ąˇ¸ŹŻĆŠ¨Á€ˇĽw˛ť¸nŚĄ©ĂÜ ·Îk…”AVgGVe8K]tˇv—ŞŤŞÂ‹ź»y”pŚˇGauB[n>VfCYhBTbFWaBWg>Q^>OXiv~v‚‡}‰Ź$/7S_h…‰‹„‡Šz€‚{€„v}w‡x€‰xn}…mz†iy„]lxWgsN`oObpM^oNasJ_rI_qG_pG_sHbuJcwFbvPfxNdwShy[o~`q~euYiu]luK\eJ]dHZaEX_FV\AQWAPWBRXI`pNeu9N^=P]<NY?NW=JR<FN2@M1?K2@L0AN#2B#3C-=N4DU7HU6GT4ER6IX7JY3FU/DU/CT3Kbź¸Ě‡ ŻD_l=Ua5LX2ER;LY7N^7M]Ibr{•¦w’¦n‰žqŤĄn‰¤x’ˇq‹śh€•f}”y”©oŠź¶Ňㆣ˛Zr|>T`?QbQ^u‚”«…ťµ~ź¶‡Â„Łşˇą}ź·x›łx—°}ť´®ČÝŤ¦»c{‹IXgETd8KZUp~ˇŻe}’L^tCXjEYl=OaG[h@R]DUa=RZAV]8O`8N[=QY[gox„Šjt|":CMclsgsxis{lw€iw‚`o{[kwZjvUhwQcrQftLcrG^pG_sG`sG^uF`pFaqHauIbvIcvKcyMe|Nf}Xi}[n~aq‚ZkxXhu[luN`gK[bL\cFV]M\dGV\CSYDTZ=PS;NQLctAXh=Ra9KXCT^DQYEQXIRZDO[6CO-:F,9G$+;-<M1@R5ER6FS3DQ2FU4GV1DS1DU*=N.E\˛Ëß›¬Zu<T`FYd9JU@O\0JV;S_=VgB]nwŹ¦sŤ¦p‹Ąu¬y‘ l–d~Źh•~—«©ą«ÇמUtyLbm@N^NTiz…ť—©Ă†§ľ¬Á|ťł†¨ľ} ·y›ł ¶’±Ć–°Ä~¨Shw@OaBM[?P]*FQ2O]9Qa<K\AP`>M^BM\ANZ<MU?RY=RZ<QW6Ra9R^@RYCRXq{tyqv|gkoVdoTdpTdoK]kM`qJ`rI]sD\qI`oF`oE]nF^rE`tD`y=]tFeDcuHcwJexKg{TlUm„Un…Vo‡lw‹]i}_nWguM^hEW^GW]DUWDS[HX_>NTCTYCSYASU;OR@SVf‹D_h6P\6P\5O[>YgB]kHcqTjtATaq‚Ź‘ˇo~ŽyŚš•¤t‹šr‡‘—˘Š›¦ś‘žxŤť†ˇ®‘¬şŁĹÚĄĂÖ™©Vm|BXdATa?Rb8KZ>TXBZcF\i?ZjF`tk‡śpŤ¦m‰Łw’žsźj†–g‚–}——µČ‰¨Ľ—ˇ7MY=P_.BSxŤŁ¬Á„¤»¤»ŁÂ‚Ł˝y—ł{šł‚ž·”±Çž˛d€–FX^>QY@R]=OZ7HU=NZ9IY;K[;J[<MZ9JW:KX=N[<NY;MX<MX4IY3K[5M`/J[Gcx>ZoA]rB^q9Xr>Yt>XqBZsF^tBZqC[qF`sM_tK_tG_rB_tFcwFbzMgSiNk„Yt‰Lg}^yŠWqWo~WlxLanHfkQjoEX_IY`IU]GW^ASZBT[=VV?TV>NTDOWEPXDOUCQT>OR_x„Piu7Q]4N\5O]:TbE^nOhx¦Ť¤˛…©Šž®€“Ą“©ş„ś®ś¶Ć€š§‡ ®‡ť¬“ˇ‹žŻ”«ş ąÉ™łĂźÁŐ•˛Ĺ…ž®Vm|F\gI[h@Rb;N]DXXCV[K^fNaoVi|F`pvŽˇ}—¨|™§z—Ąo‰žqŚˇv“¨´Ń杻ΕłÇXpxC[g@Ud9M^tŠ›’ŞÁx•®„¤»‹©Ă…ĄĽ€ť¶{–¬d€•Up€F]q?YjBT[BU]>P\:LW;LZ8JV:JZ9IZ4EQ6GT8IV<LZ8JU;MX=OZ:LW;LV<MU9LZ3HWJaqD[nC]mD]qA\qC^sD_tH_uBYpIbuJbuA]pKbzLe}Kf~MlHg~Kk‚Vp]tŤ[wŚ`xŽIcwp›Ť¤´jŽKamNbnG`fI`eFX_GW^CPXAQW@SY=PW=STAUY>NUBMUFPXAMS?NQ=OPl†”Sm{6P^2K[5O^:ScC[mLdul…š®™vŽ˘š°~–«~™®m‹źqĄlŠť}—«{“§‡ ´‹ĄµŚ¨ąŤ©ąąÎ–¶Év‘˘k…’?Sb@Ud@Ud=PbKZ^N]dTemZlvK^kYo{UmywŹ~ś«z–¦{–ŞšŻˇżÓźĽŃ™·É„˘¶_{…?Ye>Tc.EUwŤź…š°‡źµ™°`yŽk†–;Sf@Wg>Vf0EU<S^5HV<NY;MX<NY=OZ8HV:KX3DQ5FS:KX8IV9JW8IV9KV6HS;LX:LY@KN@NT>NT9KUThwLcuGbuKfzMgzLezHeyEauLh{Kf~Hg}Gf|IfKl†NoSuŤKk‚Po‡Sp…Ok€j—Ś ¶yŹˇ}‘Łp†–atI]hN_kCV^CT^BQZ@OX?NW?NW>OX:MU9MS@QZ>NV@LVAMW=KQ?MP=OPz’ŁXq5N^6N`1I[;SeAYmH`ti†žz–®„ťµXsuŽ§g‚śWuŽqŹŞ‚ˇş{šł|›˛r‘¨}±Ś©ľ‹¨˝‘®ÂĄĆÚ›»Î‘¬˝n‡—<RaE[j=Tc@WhL_hSeqXm{`s„Ź¦µ† ‡ «Š¦Ż‰¦·Şż‘«Ŕ”˛Ć°Ě塽җ·Ę€ˇ±c€Ť>Xf5Q^9Rb>Uem€’?TfBUl:P^>Td?R_BVc9KU>P[5GR:IV<NY7IT4FQ+=H$28IV1BO8IV7IV5FS9JW6HS9KV9KW>QY8LT?MN@OU;MS7JUE^mJg{Mj„JhPm…PrXz“Vz“Tx”JoŠVzlŤ«zžĽŁÂ‡©ÇŽ±ÉŽŻĆ–¶Ě•°ÄĄą{Žˇ]q‚UgyPdsL]jHYf=OZBU`AR[DU^>LV?MVAPY?PZ;KU<MV>MVAQY;IU>IVBNXAOUBSV@RSr‹›_wŠ5M_/GY1I[7OcC[oNfzrŹ«v”w“«b”Ie~=\u6Tp=^{Xwc‚›l‹ĄkŠŁ}ž´§ľžµ‰¤ĽžżÖšąÎ|¨pŠšC]k;Uc:Sc<Ud>WkE]qC^r‡ˇą„ ¸}š® ˛†¨¶€šŻ€ź±‹¨˝§ĂۨÄÜ”łČ‘±Ä}ž®VsB`o<Vf6O_4L\AUg<K\6FX9LV<NY9KV;KW=MY8IQ6GO6HP@P^3CP4DQ(5,89IU7GS4DP6FS9IT8HT9IU8HU:KT;LU:KT7IQ=OW6JT5LZ]xŚ ˝{ Â{˘É¨Ę§É}¦Ć~©É{¨Ę‚¬Đ«Î’¸ÜŽ´Đ“¶ÔšĽ×jŠ˘`}“h…–c~ŽJduRetI\lHYfDTbCT`CUa?RZ>OX>OV>PX4GNASZ7JQ:LSASZ>QXCQY;GQ7FOBQZ@NX@PV?PS=OPšŞd}Ť>Wg0HZ2J\7OaBZoNfzn‰¤uŹŞmťXs‡9Ti5Qj$A]"@]">RJh}s’¨q‘©u–w—®„ˇ»‡ĄľźŔÖ‰¨˝‚ łVpIcs<Vf6O`4Pa9Yo@`wIg€mŠ¦r‘¬ ą{ś˛x›˛y•Ş‘®Â’®Ç›¶Î©Čß‘°Ĺ’±Äu—¦[t„@Zj6P`4N^3IX9KZ4DT:IZ9IT;KW:JV8HT7FR7GS7GS7GS5ER5EQp€Ť+!1=7GS1AM1@M2BN9IU9IU:JW9JR;LU<MV<LU2IU7NY5KV2IX9Tiź˝t™˝r™Ĺt™ży Çz¤Ęy§ÉŻŇŤ¶Ű•»Ý•şß¨ŔZz’Tp†LdzQiyF[kAWc=TaCTaCT`BT_?Q]?RY<OW>PY>PX:RW5MR5MQ6OS4JO;OT9LR;LR<HMBQT>MT9KS=OV<OTASU>OS|–¤k„”D]m3L\4M]7OaBZlOgyn˘x”©sŤť\u…Ict-H\,Gb4S4GX,CS™łÄ‹©˝z®€ ·}›´…ŁĽžľŐ¦» łc~ŹJdt;Ue6Sb3O`7Ug@_rIf|Lh‡˘Ľ˘»˘şv–«‚ź´…ˇş“ŻÇŹÇťĽÓ‰¨˝‰Ş˝q”ŁWn€>Vh<Wf2L\2M[6LX8HU8HU7HU7IU:JW9JV4ER5FS6GT6GS7FV8GWJZgRbo1AM:JW=NV3EM;KW9IU;KW6GP=NW;KU8JQ7IP6IQ7KR9LS;NV-BQHdxIe†DhŠDd‰GkŤCjŚBi‹Fo‹Fh‚Hd€Ka~E`pLdtNetPanJZhHXeDW_BU]?RZ>RY<OW>PX:OW8MU=SY9NTEdcDdc8WV+JI1MM2KK=OP:ILCQMDRP9KL@SV=QV>RV>NT=LO{•˘sŤš=We7O_6O_7P`B[kPhzq z‘Ąi‚‘Xn}=Wd0IZ,G_8T7EO/AN{–ŁŚ¨¸Š«ľz±„ˇ»…ŁĽźż×ŻÄ‰§şu‘ˇ[y‡9Vd7Tc2Pa;V`A[iLeuTm‚šŻ‹Ł¸z“¦uŽ pŚĄ€›ł|–°‘ŻČŹ®Ĺ‡¦»‹¬żyť¬h|Ź<Qc=Wf4O_0KY1GS9KU<KW<MZ4CT3GV2ET4GW2FU3EW4GY2AR8GX0@M5ER5EQ8HU6GP3DM6ER4CP9HU<MV:JT8IS7JQ6IQ>PP:IK=KHBNO=MR6J[2Kd3Qq8Sx8Vw4Uu2Vo9\uMj[p]l~QhtJ\gQ_kJV_T\fO\cDSZ=OU=PX:MU2IP;QX7NT7MT9MT#5>UuuCgfMqpRrsPmnF[].15>CMXPLYUburF[\DY^ATZ?NUN[bs‘¤e–7Sd0JZ3L\6Pa@YmMh|xŻ}šŻ}–Ş\wŚ7Wj3Sf.F\'5O;R[7M_r‹¦†¤ľ„Ąą€˘±˘·Ś¦Á™ĽËŚ˝~śŻk…š^yŹ<Wl5Sh3Rg3Wd<^mFbsQj~kśuŚ¦|ł{—¶{›®~žµś¶›ąŇŤ«Äx—®s’¦x¬e€Ť=Wg<Ue6M]1EV3DV5EV7EZ3HR5JT5JT4GU5FS6GT/@M5FT6GO6GP6GP4EN:IR>MV6EN8GP7KS5HO9LS5IM6JO9JL<MP<JM:KN<MO=MS;LS4CKES_M[gKVd<P]CVcOcnWht_pxUfoYioRbhK]iGYdGYdGYdDWb>P[?Q\9KV4HO-;G7CO4@L2BIAWZ40SyqDyk?uf:oaH|jF{iPpPqN€mL…sU{p.A>{‚ENQ0BA9SO4OKu“¦b€“?Yj1JZ4M];SeB[pKg{}žµtŽŁn‡›h„•4Ue3Sf+CY%3N5LU,BTr‹¦€ž·†¨»†¨¸‚ˇ¶Ť¨ĂźÂŃ‰ŞşqŽ˘h—Jcw?[o>Yn3Pe5Wf@]nHcwTk‚d|”i‚ťu«v“Żw–Şs’©ť¶’°É‡ĄżŚ«Âv•Şr“¦k„”Ics:Sc5L\8L]1CT6EV5DV3HR3GR3GR2ES2CP0AN2CP4DR3DM4EN8IR9KT>MV;JS:IR:HR6IP6HO9LS9IP<LR=MTAPS@OR:KM;JQ9HN9IP5DM?MYM[gFR`M_lZkyVhsSfpCR_UfnIYcXhqGYdDVa?Q[?Q\>PZ<NY9KV;MX1EL,:F5BN;CQUaj[mqXsq[{tI|oDvj;pcG|oCxiCxjEzlLrc|h…”Ćľ‰Ĺ˝Ćż„˝ąŠ°«›—pŽˇe€”>Xi5N^8Qa;SeB[oLeys•¨l‡śvŹŁUq‚<^m0Qd.DZ 0G/FP2H[ŚĄŔ ą†¨»}źŻ|›°†ˇĽ§ČÚŤŔ{™¬rŠž_xŚD]r:Sh7Sd7Vi@^qGbwOf}Wo…tŤ¦t¨t”«yw–†¤˝‰§Ŕ‰§ÁźµŠ©ľw—Şr‹›Rl|:Sc6M]7K\2CT3EV5DV4HR2FQ1FQ4FQ3EP5HS9IU8GT;MT4FM3FM<LS<LS9IP9IP:FN7GN8IO:JQ<IQ;IO>MR>MSCNT;OS;NS7IP9KRL]fJZfO_k`p|]mzTdq[kwUdpOalHYeGZb>RXBS`=N[AR_;LY7HU9JW:KX4FS1AM6EP6>L!+2;EBNRFXWf|xTwJunN|rM}tExnG|rHqKv?€pG†wC€ui®ĄqŔµuÂşrą®†Ä»~śŻf•B\m?Xh7P`?WiHauIbvt“¨rŤ˘o‡›[u†8Zj5Sf)?V!.EE\f?Ugš´Î…ŁĽ‚Ł·~ ŻqĄŠĄŔšżĐ‰Ş˝v”§w‘ˇŤĄ·Zq€>Wh4M]:UkC^sHcxNh}Xsw”©}šŻv“¨†Ąş~ť´‰§Ŕ‰§ŔŠ¨Á†ĄĽžł~ž±rŤžUn~<Vf5N^/FV2EW3EV4GV6IV3FT4FQ5GR6HS3CO2BN:KS;NT;MT=MT<LS=NTANV>KS<IQ:GO>KS>KSANV:GPALT<GO>HP2EK9KR:MSFW`N`hRbnP`lO_kP]kKWfJ[fGWcBT^?S^DYc<Q[<MZ;LY7HU6GT6HU:LY2CP8IW1BM2@L<FP"(1;CJHQV(21&&*CA
)&?]Z`‚}V~wS~wQ~wU„|J‘€DxEvM‹rş°oż¶}ÍÄ5‚zu¤m‰ťBZl?XhCYi@VhMeyc|v–«sŽ˘~•§\v‡<Zk2Pa&>R$1IAXb8NaŁ˝×‰§Ŕt•©Ł˛źµ‘«ĆťÁÔ¨»}›®Ť§¸Wn~L`o<R^=S_8PhBYpIdyPm‚^zŹw”¨w”¨z—«yt”«ˇ»Š¨ÁŚŞÄˇ·žł~ž±v‘˘\x‰;Uf6O^1HX3HW4GV2FU6FS6GT6HS6HT5FO5FO3EN4EO;KQAQX:JQ<LSBNV?LT9FN:HP<GO<GOAKS?LT<IP5AI/<D>KR;LUEV_^ow[ltO_kTdpQamO`lKXdIWbBR_@P]?O\>Q^:NZ;N[;KX7GT3DP1AN7GS9IV3CP5FR0=K.:F1;E")35;@JOR"'*"''46-/$"!=:Xurs‚~rŚ†ZŠ‚:€u^Ż¤o¸±M~zg„…y”¨ośNfx?VfAXhF\nf~’€¬t”©~—«q‰›f€=\k/M^(=R!.E1HRAWi©Â݉§Ŕ}ž˛Łłžł”®ÉśŔÓ„Ą¸ŹŔŠŁ˛^s‚3FS7IT3FM9RhE^rIdyPm‚ZyŽkŠˇ{–®{—Żˇµ‡¦ľˇş®Ç‡ĄľŠ©Ŕ{šŻ~ž±|–«f“?Yj2K[6M]3HW1FU4GS4ER6GT7IT6FR8IR1DK6FM;KR;KR=MT7HN?LT>KS<IQ=JS@KS?JR9FN9FN<IQ5AKCR[=LTCRZdt€]myu…‘Wfs^nzK[gAP]HXdGWcBQ]JZgAQ^:KX:KW8HX9IY:IY7FV8GW6EU2AQ5DT0?O0@P,7H%.='0;%,8>CEJM&)- #(-/527:48;7>A!!"1-&FAcŹ‡r™—sŤŽ‡•šsŽ˘uŽ˘^vRiyj‘p†y’¦š®{™¬ˇµŚ˘´x’˘:Zi0N_(=R!-C4>1GYś¶Đy±w™¬{ť¬†ĄşŹ©Ä›ÁÔ©˝«ÉÜn‡–ZlyJ\g:KT/AG5K_C[mFavKjSr‰j‡ˇr‘©uŹ«v–Ş˘ąˇş”˛ËŤ«Ä…¤»‰¨˝ ˛w•¨l†›<Xi4N]4M^1GV/EP.EQ9IV7HU<LW8GT5FO>NU9IN=MS<LR<LR9JP@NT=KQ>MS>JP:FL6CL8DM7HO<LSGU_7HQVfr[jwGZdj|‡CU`PbmDVaAS^GYdAS^7IT7IT9JW4ER6FR6EV9HX8GW5DT7FV3BR8GW5DT5DT2AQ0@P-5F$+:"+5%-+2527:69= #$(-25-25!$) "###$ )>;;<DG"47%9?qŚ ośj‚”uŚśwŠ›ezŚv‹ |”§k‰ť|–§–¨m†–:Zi6Rc&<N ,C3<EZmŹ¨ĂŤ¬Ĺw™¬€˘±Ś«Áť·ŇźĆŮŽŻĂ‘ŻŔc{‹Wiv?PX+=D*9?8M`6P`Nk|Gh{UuŚq©y–±{”´s“¦z™°‡Ąľ¶Ďź¸‡¦˝‡¦»€ˇł…ŁµsŤˇ=Yj1K[8Qa5L[4JU0GS8HU2BO9HU5FO&7A<LSBRX4DJ:IO;KQ=KQ>LR9GM9EJ/;A5AG7EJ=MT?OUAR[WgpZlwM_jXjuQaoM]kJ\gFXcAS^>P[:LW<MX;PZ6JU<P]2CO6EU8GW<GY4?Q5DT3BR6EU4CS2AQ2AQ1@P,=L+0D!'7(2$';EH!$$ #+-(* %&/12!%53,;=..7WLY† °l†—q‹›d}‘rŠžq‰źuĄw’§|š«z–§g‘j“G^m;P^1CP-@M0HXĄľÎť·Čť®¦ąŤŔŠ«ż”·Ë›ĽĎź˛„žłs‹ťPetAR^:KS:JQ3DR4GVRg|Nfgšz–®n‹ v•§{š´źµŚ¬Ă¦ĆÝ‘°Ç|›Ż†Ąşv•ŞqĄe…>\o=Wf7Q_;Q]6JU7HS1FQ4HT6KS9KS7IP6FM;IO>IO:PR7LM:MU3EM1AN%7@=KU;KQ?QX:LSWip[msQbkRclVgpPajCV^J]e@S[<OV=OZ@R]7IS:KW4DT;K[:JZ7GW5EU9IY8HX3CS4DT2BR1AQ9HX1@P.=M.>N.;K$/='4#,!&!%/45#"#(' .,,&!"+"O93D($gRQqgj~„rŁj…™rŚˇnťw’§mť~°v¨|›«€›¬i…–^xOhx@WgCWfMap‡ˇ˛›µĆ‰Ą¶›Ż™¸Ę’˛Ç•´É›˝Đ•¶É‚˘µ~š«azŠEZi6FSARZ8GP/BM/CRJ_u\tŤy•ŻsŹ§u”©w•§~ť·‚Łą°Ç¦Ćݧľ~ť˛~ť˛r‘¦†Ąş{śŻ:Xk5N^9Tb:O[9MW3GR4FQ7IT9LT9MU6IO9IP<JO;GM9IK<JP1>F:FP1>J@LX?KULWbSfm\nuQcjQcjL]fHYbK\eFW`GZb>QY:MT>P[7IT:LW6GT7HT6FV9IY8HX6FV7GW8HX7GW7GW3CS3CS1AQ3BR/>N,<L3@P,9I$/=%3!*#!"022###
$3';.(60-#'&|›´ž·z™˛‡Ąľ~ś´€š´{–°z•Ż‰§şu“¦[vŠrŚťNhy@Xj™˛Á›«‡Ą¸®Á’ŻÄŠ©ľ”łČ’±Č—¶Í¸ÎŚŔ‰©ĽŹ«Ľz“Ł6JY9KU4EM5DL6GS,<L8Oa‡ź¸›µ§ľ‚ˇ¶ˇ´{š´°Ç˘ÂŮ©Éŕ‹ŞÁx—¬‰¨˝x—¬€ź´a”:Xk=Wg:Sc;Qa4JU6HV3EP6IP7HQ8GP9HQ:GN;IQ<GO<FM6?H5>G19FAJWZbp\fpfnyNahFX_GY_@QZHYbEV_;LTFUbDW_:MT;MX5GR:LV3CQ3DQ4FR3CT5EU4DT3CS6FV6FV5EU4DT1BR/?O/>N.=M-<L0=M0=M*7H&1?$1%!&)
&((!##% "LFHQMI]]T$) #.'CSL)%‹°Ě†§Ä‰«Ç„Ąż…Łľ}šµ’°É®Ç”±Ĺ–łÇÂv”§g•–±ĹrŚ «ľ”¶ÍśľŐ‹ŞÁ“łÉ•´Ę•´Ë•ŻÉŤ¨ÂŠ«Â żÔ¬ĽtŽśVlwVhs7GS<JV2CL5FS3Eś´Ë‰Ąż‰§Ŕ§˝‹Şľ‡¦ŔśĽÓ¦ĆÝźŔ׏®Ĺ{šŻ|›°w–«~ž±a‚•YwŠ6RcA[k9P_:Q`5KW5HO7HQ8GP7CM@LV:EO:FP:EP2<C:FP6BNlv…Ą±Ŕ„‘ť™ˇWgqJ\cBT[HYb6GP?QY;KW;KW<KX9MT3EP>P[2DO6GT2CP6GT3EQ3CS3CS4DT7GW4DT5EU3CS->N2AQ.=M0?O.=M.;K+8H2?O#1A"0*& &6<=%%%ebdLNLAIB&!)"&¦Č‹±Ń€ŁÄv¶„¤ÁŚŞĹ…ŁĽ{–°m‰ˇsŹ§Ws‹s’©–µĚŤ¬ÂŻĆ‚ˇ¸¤ż„§Á…©ÂžżŮ“°Ëž»ÖŤ¬Äś¶‹«Â żÓŤ©ąl†”OdoDVa;KW8ER7FO/@N*>QuŽ¤‰¤ż‰§Ŕ†¦˝“´Č‡¦Ŕ›»ŇźżÖˇÁŘŹ®Ĺ†ĄşŽÂ†Ąş„Ą·mŠťRq„@[l=Vh9Rb:Qa6M]:MS9JS5DM:FP:DM4@L3AM:JV?U\-AL·Ęו§´ź¶ÂmŹRhsLdkCT]HYb?PY>PX:JW<LX=MY9IU3EP9KV2DN.>L3DQ4ER4ER3CS3CS2BR3CS1AQ4DT6FV4DT/?O1@P2AQ.=M1>N0=M-;K2<M#,>(6"/#-$$)* %!&XWY@ECCJE87.\RKgXRz˘Ĺj“´j°xśş€ ˝t’l‡ˇt¨{—Żf…śoŤ¦Ś«Ä‚ˇş‹¬Ćv—±yś¶ŁÁa…Ł†§Ä}źĽ‰©ĆŽ®ËŤŞĹŚŞĹ‘°É•´ÉŚ©·[t€Kak;MX9HT8ES4DJ2BO.CTBZq…ˇ»Ś«Ă’°ĘŚ®ĹŚ«Ä¤ĹŰ Ŕ׏ŻĆŽ¬ÄŚ«Ŕt“¨nŤ˘|ťŻv”§`~‘B]n=Wh:Te9Qa1K[4HO6IQ6DM2=J,8D0>JDVa9KX‘®ą”®ą›©LguwŤťNfr=Va<W^9IR@QZ7HP?O[7GS8HT8HT3CP3EP1CN5FS1BO.?L3DP3CS1AQ5EU3CS3CS1AQ3CS4DT3CS/?O2AQ1AQ0=M/<L0=M/9J+5F$.@!,:&4$. %!!&'
475GHF>3/ub]B)%bŚ±hłq—ąvš¸q‘®v”‚ś´v‘¦m‹¤pŽ§ ąĄż«Ĺ}źĽ~Łż{ Ľ¤Ĺ¦Çv—¸†¨Ć„¦Ä}źĽŽ°Í€˘żŹ®ÇŽÂ|§j…ŽE\d@RZ:JW6BS9FL/?L/AS0H^“®É†ĄľłË’´ĘŹ®ÇŹŻĆŁĂÚź¶‹ŞÁ…¤ąz™®s’§{™«w•¨g†™<Xh=Yj;Uf8Rc2L^7NU4IQ+<D8COAO[;JWxŽšš˛ľĄŻRm|l†”F]mYn}7JW9KV=QX>NX:KT9JS7GS2BN:JU6FS9HV2EO.?L5FS1BO0AM1AQ1AQ1AQ2BR2BR2BR2BR1AQ3CS4DT3CS2AQ0=M0=M/<L0:K1;L)3D(2C#.<)6$."'$), ! !#() -+!" &'%&$$/(%$OD=k•şyˇÄ‹±Ó€¤Â‰§Â’®Ć‘«Ŕ•¬Ă‹©Â‚ ąŹČŹ°ĘŤŻÍŤ˛Î{ˇż©Ç…¤Č{›ľr“´o“´„¨Ĺ„¨ĆgŚ¨|ˇ˝†ŁľŻĆśŞw’śE\dCV]7FT>K[9FM3CP*<M$<R–˛Ě€žąŚŻĆ‹Ĺ§Ŕ˘¸ˇ¸Ś¬Ă€ž¶{šŻ|›°s’§rŁm‹žk‰ś>Ym=Yj:Te8Rc6Pb1KQ/FO9IR>KX…“źśş}–˘^x†[vf}ŚOct:L]BQbAN\;GSDMW;MV5GO1AM5EQ5EQ5ER9IV3BO1BO/@M3DQ/@L3CS/?O0@P2BR0@P0@P2BR3CS0@P1AQ1AQ1AQ,9I0=M1>N'4D+5F1;L'1B'1C"-;!*7$.$*&+/&*+"'((,-".+%-,#"%$#!!,+'/+*=98%-& -\ No newline at end of file -diff --git a/host_applications/linux/apps/hello_pi/hello_wayland/Makefile b/host_applications/linux/apps/hello_pi/hello_wayland/Makefile -new file mode 100644 -index 0000000..c9ddf23 ---- /dev/null -+++ b/host_applications/linux/apps/hello_pi/hello_wayland/Makefile -@@ -0,0 +1,5 @@ -+OBJS=triangle.o -+BIN=hello_wayland.bin -+LDFLAGS+=-lwayland-client -lwayland-egl -+ -+include ../Makefile.include -diff --git a/host_applications/linux/apps/hello_pi/hello_wayland/cube_texture_and_coords.h b/host_applications/linux/apps/hello_pi/hello_wayland/cube_texture_and_coords.h -new file mode 100644 -index 0000000..663e23b ---- /dev/null -+++ b/host_applications/linux/apps/hello_pi/hello_wayland/cube_texture_and_coords.h -@@ -0,0 +1,100 @@ -+/* -+Copyright (c) 2012, Broadcom Europe Ltd -+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. -+*/ -+ -+// Spatial coordinates for the cube -+ -+static const GLbyte quadx[6*4*3] = { -+ /* FRONT */ -+ -10, -10, 10, -+ 10, -10, 10, -+ -10, 10, 10, -+ 10, 10, 10, -+ -+ /* BACK */ -+ -10, -10, -10, -+ -10, 10, -10, -+ 10, -10, -10, -+ 10, 10, -10, -+ -+ /* LEFT */ -+ -10, -10, 10, -+ -10, 10, 10, -+ -10, -10, -10, -+ -10, 10, -10, -+ -+ /* RIGHT */ -+ 10, -10, -10, -+ 10, 10, -10, -+ 10, -10, 10, -+ 10, 10, 10, -+ -+ /* TOP */ -+ -10, 10, 10, -+ 10, 10, 10, -+ -10, 10, -10, -+ 10, 10, -10, -+ -+ /* BOTTOM */ -+ -10, -10, 10, -+ -10, -10, -10, -+ 10, -10, 10, -+ 10, -10, -10, -+}; -+ -+/** Texture coordinates for the quad. */ -+static const GLfloat texCoords[6 * 4 * 2] = { -+ 0.f, 0.f, -+ 1.f, 0.f, -+ 0.f, 1.f, -+ 1.f, 1.f, -+ -+ 0.f, 0.f, -+ 1.f, 0.f, -+ 0.f, 1.f, -+ 1.f, 1.f, -+ -+ 0.f, 0.f, -+ 1.f, 0.f, -+ 0.f, 1.f, -+ 1.f, 1.f, -+ -+ 0.f, 0.f, -+ 1.f, 0.f, -+ 0.f, 1.f, -+ 1.f, 1.f, -+ -+ 0.f, 0.f, -+ 1.f, 0.f, -+ 0.f, 1.f, -+ 1.f, 1.f, -+ -+ 0.f, 0.f, -+ 1.f, 0.f, -+ 0.f, 1.f, -+ 1.f, 1.f, -+}; -+ -diff --git a/host_applications/linux/apps/hello_pi/hello_wayland/triangle.c b/host_applications/linux/apps/hello_pi/hello_wayland/triangle.c -new file mode 100644 -index 0000000..1a7bfc4 ---- /dev/null -+++ b/host_applications/linux/apps/hello_pi/hello_wayland/triangle.c -@@ -0,0 +1,666 @@ -+/* -+Copyright (c) 2012, Broadcom Europe Ltd -+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. -+*/ -+ -+// A rotating cube rendered with OpenGL|ES. Three images used as textures on the cube faces. -+ -+#define _GNU_SOURCE -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> -+#include <math.h> -+#include <assert.h> -+#include <unistd.h> -+#include <sys/socket.h> -+#include <sys/un.h> -+ -+#include <wayland-egl.h> -+#include <wayland-client.h> -+ -+#include "GLES/gl.h" -+#include "EGL/egl.h" -+#include "EGL/eglext.h" -+ -+#include "cube_texture_and_coords.h" -+ -+#define PATH "./" -+ -+#define IMAGE_SIZE 128 -+ -+#ifndef M_PI -+ #define M_PI 3.141592654 -+#endif -+ -+ -+typedef struct -+{ -+ uint32_t screen_width; -+ uint32_t screen_height; -+// OpenGL|ES objects -+ EGLDisplay display; -+ EGLSurface surface; -+ EGLContext context; -+ GLuint tex[6]; -+// model rotation vector and direction -+ GLfloat rot_angle_x_inc; -+ GLfloat rot_angle_y_inc; -+ GLfloat rot_angle_z_inc; -+// current model rotation angles -+ GLfloat rot_angle_x; -+ GLfloat rot_angle_y; -+ GLfloat rot_angle_z; -+// current distance from camera -+ GLfloat distance; -+ GLfloat distance_inc; -+// pointers to texture buffers -+ char *tex_buf1; -+ char *tex_buf2; -+ char *tex_buf3; -+ struct wl_display *wl_display; -+ struct wl_registry *wl_registry; -+ struct wl_shell *wl_shell; -+ struct wl_shell_surface *wl_shell_surface; -+ struct wl_compositor *wl_compositor; -+ struct wl_surface *wl_surface; -+ struct wl_callback *wl_callback; -+ struct wl_egl_window *wl_egl_window; -+ int needs_update; -+ int ellapsed_frames; -+ int kill_compositor; -+ int single_frame; -+ int terminate_abruptly; -+} CUBE_STATE_T; -+ -+static void init_ogl(CUBE_STATE_T *state); -+static void init_model_proj(CUBE_STATE_T *state); -+static void reset_model(CUBE_STATE_T *state); -+static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc); -+static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc); -+static void redraw_scene(CUBE_STATE_T *state); -+static void update_model(CUBE_STATE_T *state); -+static void init_textures(CUBE_STATE_T *state); -+static void load_tex_images(CUBE_STATE_T *state); -+static void exit_func(CUBE_STATE_T *state); -+ -+static void -+registry_handle_global(void *data, struct wl_registry *registry, -+ uint32_t name, const char *interface, uint32_t version) -+{ -+ CUBE_STATE_T *state = data; -+ -+ if (strcmp(interface, "wl_compositor") == 0) { -+ state->wl_compositor = -+ wl_registry_bind(registry, name, -+ &wl_compositor_interface, 1); -+ } else if (strcmp(interface, "wl_shell") == 0) { -+ state->wl_shell = wl_registry_bind(registry, name, -+ &wl_shell_interface, 1); -+ } -+} -+ -+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 -+}; -+ -+/*********************************************************** -+ * Name: init_ogl -+ * -+ * Arguments: -+ * CUBE_STATE_T *state - holds OGLES model info -+ * -+ * Description: Sets the display, OpenGL|ES context and screen stuff -+ * -+ * Returns: void -+ * -+ ***********************************************************/ -+static void init_ogl(CUBE_STATE_T *state) -+{ -+ EGLBoolean result; -+ EGLint num_config; -+ -+ static const EGLint attribute_list[] = -+ { -+ EGL_RED_SIZE, 8, -+ EGL_GREEN_SIZE, 8, -+ EGL_BLUE_SIZE, 8, -+ EGL_ALPHA_SIZE, 8, -+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT, -+ EGL_NONE -+ }; -+ -+ EGLConfig config; -+ -+ state->wl_display = wl_display_connect(NULL); -+ -+ state->wl_registry = wl_display_get_registry(state->wl_display); -+ wl_registry_add_listener(state->wl_registry, ®istry_listener, state); -+ -+ wl_display_dispatch(state->wl_display); -+ -+ // get an EGL display connection -+ state->display = eglGetDisplay(state->wl_display); -+ assert(state->display!=EGL_NO_DISPLAY); -+ -+ // initialize the EGL display connection -+ result = eglInitialize(state->display, NULL, NULL); -+ assert(EGL_FALSE != result); -+ -+ // get an appropriate EGL frame buffer configuration -+ result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config); -+ assert(EGL_FALSE != result); -+ -+ // create an EGL rendering context -+ state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, NULL); -+ assert(state->context!=EGL_NO_CONTEXT); -+ -+ // create an EGL window surface -+ state->screen_width = 1024; -+ state->screen_height = 860; -+ -+ state->wl_surface = wl_compositor_create_surface(state->wl_compositor); -+ state->wl_shell_surface = wl_shell_get_shell_surface(state->wl_shell, state->wl_surface); -+ -+ wl_shell_surface_set_toplevel(state->wl_shell_surface); -+ wl_shell_surface_set_title(state->wl_shell_surface, "triangle.c"); -+ -+ state->wl_egl_window = wl_egl_window_create(state->wl_surface, state->screen_width, state->screen_height); -+ -+ state->surface = eglCreateWindowSurface( state->display, config, state->wl_egl_window, NULL ); -+ assert(state->surface != EGL_NO_SURFACE); -+ -+ // connect the context to the surface -+ result = eglMakeCurrent(state->display, state->surface, state->surface, state->context); -+ assert(EGL_FALSE != result); -+ -+ // Set background color and clear buffers -+ glClearColor(0.15f, 0.25f, 0.35f, 1.0f); -+ -+ // Enable back face culling. -+ glEnable(GL_CULL_FACE); -+ -+ glMatrixMode(GL_MODELVIEW); -+} -+ -+/*********************************************************** -+ * Name: init_model_proj -+ * -+ * Arguments: -+ * CUBE_STATE_T *state - holds OGLES model info -+ * -+ * Description: Sets the OpenGL|ES model to default values -+ * -+ * Returns: void -+ * -+ ***********************************************************/ -+static void init_model_proj(CUBE_STATE_T *state) -+{ -+ float nearp = 1.0f; -+ float farp = 500.0f; -+ float hht; -+ float hwd; -+ -+ glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); -+ -+ glViewport(0, 0, (GLsizei)state->screen_width, (GLsizei)state->screen_height); -+ -+ glMatrixMode(GL_PROJECTION); -+ glLoadIdentity(); -+ -+ hht = nearp * (float)tan(45.0 / 2.0 / 180.0 * M_PI); -+ hwd = hht * (float)state->screen_width / (float)state->screen_height; -+ -+ glFrustumf(-hwd, hwd, -hht, hht, nearp, farp); -+ -+ glEnableClientState( GL_VERTEX_ARRAY ); -+ glVertexPointer( 3, GL_BYTE, 0, quadx ); -+ -+ reset_model(state); -+} -+ -+/*********************************************************** -+ * Name: reset_model -+ * -+ * Arguments: -+ * CUBE_STATE_T *state - holds OGLES model info -+ * -+ * Description: Resets the Model projection and rotation direction -+ * -+ * Returns: void -+ * -+ ***********************************************************/ -+static void reset_model(CUBE_STATE_T *state) -+{ -+ // reset model position -+ glMatrixMode(GL_MODELVIEW); -+ glLoadIdentity(); -+ glTranslatef(0.f, 0.f, -50.f); -+ -+ // reset model rotation -+ state->rot_angle_x = 45.f; state->rot_angle_y = 30.f; state->rot_angle_z = 0.f; -+ state->rot_angle_x_inc = 0.5f; state->rot_angle_y_inc = 0.5f; state->rot_angle_z_inc = 0.f; -+ state->distance = 40.f; -+} -+ -+/*********************************************************** -+ * Name: update_model -+ * -+ * Arguments: -+ * CUBE_STATE_T *state - holds OGLES model info -+ * -+ * Description: Updates model projection to current position/rotation -+ * -+ * Returns: void -+ * -+ ***********************************************************/ -+static void update_model(CUBE_STATE_T *state) -+{ -+ // update position -+ state->rot_angle_x = inc_and_wrap_angle(state->rot_angle_x, state->rot_angle_x_inc); -+ state->rot_angle_y = inc_and_wrap_angle(state->rot_angle_y, state->rot_angle_y_inc); -+ state->rot_angle_z = inc_and_wrap_angle(state->rot_angle_z, state->rot_angle_z_inc); -+ state->distance = inc_and_clip_distance(state->distance, state->distance_inc); -+ -+ glLoadIdentity(); -+ // move camera back to see the cube -+ glTranslatef(0.f, 0.f, -state->distance); -+ -+ // Rotate model to new position -+ glRotatef(state->rot_angle_x, 1.f, 0.f, 0.f); -+ glRotatef(state->rot_angle_y, 0.f, 1.f, 0.f); -+ glRotatef(state->rot_angle_z, 0.f, 0.f, 1.f); -+} -+ -+/*********************************************************** -+ * Name: inc_and_wrap_angle -+ * -+ * Arguments: -+ * GLfloat angle current angle -+ * GLfloat angle_inc angle increment -+ * -+ * Description: Increments or decrements angle by angle_inc degrees -+ * Wraps to 0 at 360 deg. -+ * -+ * Returns: new value of angle -+ * -+ ***********************************************************/ -+static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc) -+{ -+ angle += angle_inc; -+ -+ if (angle >= 360.0) -+ angle -= 360.f; -+ else if (angle <=0) -+ angle += 360.f; -+ -+ return angle; -+} -+ -+/*********************************************************** -+ * Name: inc_and_clip_distance -+ * -+ * Arguments: -+ * GLfloat distance current distance -+ * GLfloat distance_inc distance increment -+ * -+ * Description: Increments or decrements distance by distance_inc units -+ * Clips to range -+ * -+ * Returns: new value of angle -+ * -+ ***********************************************************/ -+static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc) -+{ -+ distance += distance_inc; -+ -+ if (distance >= 120.0f) -+ distance = 120.f; -+ else if (distance <= 40.0f) -+ distance = 40.0f; -+ -+ return distance; -+} -+ -+static pid_t get_server_pid(CUBE_STATE_T *state) -+{ -+ struct ucred ucred; -+ socklen_t len; -+ int fd; -+ -+ fd = wl_display_get_fd(state->wl_display); -+ len = sizeof ucred; -+ getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len); -+ -+ return ucred.pid; -+} -+ -+static void -+frame(void *data, struct wl_callback *callback, uint32_t time) -+{ -+ CUBE_STATE_T *state = (CUBE_STATE_T *) data; -+ -+ state->needs_update = 1; -+} -+ -+static const struct wl_callback_listener frame_listener = { -+ frame -+}; -+ -+static void -+update(CUBE_STATE_T *state) -+{ -+ if (!state->single_frame || state->ellapsed_frames == 0) { -+ update_model(state); -+ redraw_scene(state); -+ } -+ -+ state->wl_callback = wl_surface_frame(state->wl_surface); -+ wl_callback_add_listener(state->wl_callback, &frame_listener, state); -+ -+ if (state->ellapsed_frames == 100) { -+ if (state->kill_compositor) { -+ fprintf(stderr, "reached frame 100, killing compositor\n"); -+ pid_t pid = get_server_pid(state); -+ kill(pid, SIGTERM); -+ } else if (state->terminate_abruptly) { -+ fprintf(stderr, "reached frame 100, terminating right away\n"); -+ exit_func(state); -+ exit(0); -+ } -+ } -+ -+ if (!state->single_frame || state->ellapsed_frames == 0) -+ eglSwapBuffers(state->display, state->surface); -+ else { -+ wl_surface_damage(state->wl_surface, 0, 0, state->screen_width, -+ state->screen_height); -+ wl_surface_commit(state->wl_surface); -+ } -+ -+ state->ellapsed_frames++; -+} -+ -+/*********************************************************** -+ * Name: redraw_scene -+ * -+ * Arguments: -+ * CUBE_STATE_T *state - holds OGLES model info -+ * -+ * Description: Draws the model and calls eglSwapBuffers -+ * to render to screen -+ * -+ * Returns: void -+ * -+ ***********************************************************/ -+static void redraw_scene(CUBE_STATE_T *state) -+{ -+ // Start with a clear screen -+ glClear( GL_COLOR_BUFFER_BIT ); -+ -+ // Draw first (front) face: -+ // Bind texture surface to current vertices -+ glBindTexture(GL_TEXTURE_2D, state->tex[0]); -+ -+ // Need to rotate textures - do this by rotating each cube face -+ glRotatef(270.f, 0.f, 0.f, 1.f ); // front face normal along z axis -+ -+ // draw first 4 vertices -+ glDrawArrays( GL_TRIANGLE_STRIP, 0, 4); -+ -+ // same pattern for other 5 faces - rotation chosen to make image orientation 'nice' -+ glBindTexture(GL_TEXTURE_2D, state->tex[1]); -+ glRotatef(90.f, 0.f, 0.f, 1.f ); // back face normal along z axis -+ glDrawArrays( GL_TRIANGLE_STRIP, 4, 4); -+ -+ glBindTexture(GL_TEXTURE_2D, state->tex[2]); -+ glRotatef(90.f, 1.f, 0.f, 0.f ); // left face normal along x axis -+ glDrawArrays( GL_TRIANGLE_STRIP, 8, 4); -+ -+ glBindTexture(GL_TEXTURE_2D, state->tex[3]); -+ glRotatef(90.f, 1.f, 0.f, 0.f ); // right face normal along x axis -+ glDrawArrays( GL_TRIANGLE_STRIP, 12, 4); -+ -+ glBindTexture(GL_TEXTURE_2D, state->tex[4]); -+ glRotatef(270.f, 0.f, 1.f, 0.f ); // top face normal along y axis -+ glDrawArrays( GL_TRIANGLE_STRIP, 16, 4); -+ -+ glBindTexture(GL_TEXTURE_2D, state->tex[5]); -+ glRotatef(90.f, 0.f, 1.f, 0.f ); // bottom face normal along y axis -+ glDrawArrays( GL_TRIANGLE_STRIP, 20, 4); -+} -+ -+/*********************************************************** -+ * Name: init_textures -+ * -+ * Arguments: -+ * CUBE_STATE_T *state - holds OGLES model info -+ * -+ * Description: Initialise OGL|ES texture surfaces to use image -+ * buffers -+ * -+ * Returns: void -+ * -+ ***********************************************************/ -+static void init_textures(CUBE_STATE_T *state) -+{ -+ // load three texture buffers but use them on six OGL|ES texture surfaces -+ load_tex_images(state); -+ glGenTextures(6, &state->tex[0]); -+ -+ // setup first texture -+ glBindTexture(GL_TEXTURE_2D, state->tex[0]); -+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0, -+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST); -+ -+ // setup second texture - reuse first image -+ glBindTexture(GL_TEXTURE_2D, state->tex[1]); -+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0, -+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST); -+ -+ // third texture -+ glBindTexture(GL_TEXTURE_2D, state->tex[2]); -+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0, -+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST); -+ -+ // fourth texture - reuse second image -+ glBindTexture(GL_TEXTURE_2D, state->tex[3]); -+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0, -+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST); -+ -+ //fifth texture -+ glBindTexture(GL_TEXTURE_2D, state->tex[4]); -+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0, -+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST); -+ -+ // sixth texture - reuse third image -+ glBindTexture(GL_TEXTURE_2D, state->tex[5]); -+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0, -+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST); -+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST); -+ -+ // setup overall texture environment -+ glTexCoordPointer(2, GL_FLOAT, 0, texCoords); -+ glEnableClientState(GL_TEXTURE_COORD_ARRAY); -+ -+ glEnable(GL_TEXTURE_2D); -+} -+ -+/*********************************************************** -+ * Name: load_tex_images -+ * -+ * Arguments: -+ * void -+ * -+ * Description: Loads three raw images to use as textures on faces -+ * -+ * Returns: void -+ * -+ ***********************************************************/ -+static void load_tex_images(CUBE_STATE_T *state) -+{ -+ FILE *tex_file1 = NULL, *tex_file2=NULL, *tex_file3 = NULL; -+ int bytes_read, image_sz = IMAGE_SIZE*IMAGE_SIZE*3; -+ -+ state->tex_buf1 = malloc(image_sz); -+ state->tex_buf2 = malloc(image_sz); -+ state->tex_buf3 = malloc(image_sz); -+ -+ tex_file1 = fopen(PATH "Lucca_128_128.raw", "rb"); -+ if (tex_file1 && state->tex_buf1) -+ { -+ bytes_read=fread(state->tex_buf1, 1, image_sz, tex_file1); -+ assert(bytes_read == image_sz); // some problem with file? -+ fclose(tex_file1); -+ } -+ -+ tex_file2 = fopen(PATH "Djenne_128_128.raw", "rb"); -+ if (tex_file2 && state->tex_buf2) -+ { -+ bytes_read=fread(state->tex_buf2, 1, image_sz, tex_file2); -+ assert(bytes_read == image_sz); // some problem with file? -+ fclose(tex_file2); -+ } -+ -+ tex_file3 = fopen(PATH "Gaudi_128_128.raw", "rb"); -+ if (tex_file3 && state->tex_buf3) -+ { -+ bytes_read=fread(state->tex_buf3, 1, image_sz, tex_file3); -+ assert(bytes_read == image_sz); // some problem with file? -+ fclose(tex_file3); -+ } -+} -+ -+//------------------------------------------------------------------------------ -+ -+static void exit_func(CUBE_STATE_T *state) -+{ -+ // clear screen -+ glClear( GL_COLOR_BUFFER_BIT ); -+ eglSwapBuffers(state->display, state->surface); -+ -+ // Release OpenGL resources -+ eglMakeCurrent( state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); -+ -+ wl_egl_window_destroy(state->wl_egl_window); -+ wl_shell_surface_destroy(state->wl_shell_surface); -+ wl_surface_destroy(state->wl_surface); -+ -+ eglDestroySurface( state->display, state->surface ); -+ eglDestroyContext( state->display, state->context ); -+ eglTerminate( state->display ); -+ -+ wl_display_flush(state->wl_display); -+ -+ // release texture buffers -+ free(state->tex_buf1); -+ free(state->tex_buf2); -+ free(state->tex_buf3); -+ -+ printf("\ncube closed\n"); -+} // exit_func() -+ -+static int running = 1; -+ -+static void -+signal_int(int signum) -+{ -+ running = 0; -+} -+ -+//============================================================================== -+ -+int main (int argc, char *argv[]) -+{ -+ struct sigaction sigint; -+ CUBE_STATE_T state = {0,}; -+ int ret = 0; -+ int i; -+ -+ for (i = 0; i < argc; i++) { -+ if (strcmp(argv[i], "--kill-compositor") == 0) -+ state.kill_compositor = 1; -+ if (strcmp(argv[i], "--single-frame") == 0) -+ state.single_frame = 1; -+ if (strcmp(argv[i], "--terminate-abruptly") == 0) -+ state.terminate_abruptly = 1; -+ else if (strcmp(argv[i], "--help") == 0 || -+ strcmp(argv[i], "-h") == 0) { -+ printf("Usage: hello_wayland.bin [OPTION]\n\n"); -+ printf("\t--kill-compositor\tkill the Wayland compositor after 100 frames\n"); -+ printf("\t-h, --help\t\tshow this text\n"); -+ printf("\t--single-frame\t\tupdate the display only once\n"); -+ printf("\t--terminate-abruptly\texit right after rendering the 100th frame\n"); -+ return 0; -+ } -+ } -+ -+ // Start OGLES -+ init_ogl(&state); -+ -+ // Setup the model world -+ init_model_proj(&state); -+ -+ // initialise the OGLES texture(s) -+ init_textures(&state); -+ -+ sigint.sa_handler = signal_int; -+ sigemptyset(&sigint.sa_mask); -+ sigint.sa_flags = SA_RESETHAND; -+ sigaction(SIGINT, &sigint, NULL); -+ -+ state.needs_update = 1; -+ while (running && ret != -1) { -+ if (state.needs_update) { -+ update(&state); -+ state.needs_update = 0; -+ } -+ -+ ret = wl_display_dispatch(state.wl_display); -+ } -+ -+ exit_func(&state); -+ -+ return 0; -+} -+ -diff --git a/host_applications/linux/apps/hello_pi/rebuild.sh b/host_applications/linux/apps/hello_pi/rebuild.sh -index 8225dd5..0be6ce7 100755 ---- a/host_applications/linux/apps/hello_pi/rebuild.sh -+++ b/host_applications/linux/apps/hello_pi/rebuild.sh -@@ -14,6 +14,7 @@ make -C hello_videocube clean - make -C hello_teapot clean - make -C hello_fft clean - make -C hello_mmal_encode clean -+make -C hello_wayland clean - - make -C libs/ilclient - make -C libs/vgfont -@@ -31,4 +32,4 @@ make -C hello_videocube - make -C hello_teapot - make -C hello_fft - make -C hello_mmal_encode -- -+make -C hello_wayland --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0004-wayland-egl-Add-bcm_host-to-dependencies.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0004-wayland-egl-Add-bcm_host-to-dependencies.patch deleted file mode 100644 index 713fc3e5b..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0004-wayland-egl-Add-bcm_host-to-dependencies.patch +++ /dev/null @@ -1,28 +0,0 @@ -From f17879b691984b5c4950e4b94ebf102c78797ede Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Mon, 10 Aug 2015 02:38:27 -0700 -Subject: [PATCH 04/16] wayland-egl: Add bcm_host to dependencies - -It uses headers like vcos_platform_types.h but does not -depend on module which should add the required include paths -lets add the dependency on bcm_host module which should do it - -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - interface/khronos/wayland-egl/wayland-egl.pc.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/interface/khronos/wayland-egl/wayland-egl.pc.in b/interface/khronos/wayland-egl/wayland-egl.pc.in -index 8bafc15..fd259c9 100644 ---- a/interface/khronos/wayland-egl/wayland-egl.pc.in -+++ b/interface/khronos/wayland-egl/wayland-egl.pc.in -@@ -6,5 +6,6 @@ includedir=${prefix}/include - Name: wayland-egl - Description: VideoCore wayland-egl library - Version: @PROJECT_APIVER@ -+Requires: bcm_host - Libs: -L${libdir} -lwayland-egl - Cflags: -I${includedir} --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0005-interface-remove-faulty-assert-to-make-weston-happy-.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0005-interface-remove-faulty-assert-to-make-weston-happy-.patch deleted file mode 100644 index 8d78333fa..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0005-interface-remove-faulty-assert-to-make-weston-happy-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0273b7b9d7a27d8fe7d3ad8680b799f997e75dca Mon Sep 17 00:00:00 2001 -From: "Yann E. MORIN" <yann.morin.1998@free.fr> -Date: Sat, 24 Jan 2015 22:07:19 +0100 -Subject: [PATCH 05/16] interface: remove faulty assert() to make weston happy - at runtime - -This was removed after a discussion on IRC with the weston guys -('daniels' on irc.freenode.net/#wayland). - -Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr> ---- - interface/vmcs_host/vc_vchi_dispmanx.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/interface/vmcs_host/vc_vchi_dispmanx.c b/interface/vmcs_host/vc_vchi_dispmanx.c -index eab146e..29e0dee 100755 ---- a/interface/vmcs_host/vc_vchi_dispmanx.c -+++ b/interface/vmcs_host/vc_vchi_dispmanx.c -@@ -1306,7 +1306,6 @@ static void *dispmanx_notify_func( void *arg ) { - // Decrement the use count - the corresponding "use" is in vc_dispmanx_update_submit. - vchi_service_release(dispmanx_client.notify_handle[0]); - if (dispmanx_client.update_callback ) { -- vcos_assert( dispmanx_client.pending_update_handle == handle); - dispmanx_client.update_callback(handle, dispmanx_client.update_callback_param); - } - } else { --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0006-zero-out-wl-buffers-in-egl_surface_free.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0006-zero-out-wl-buffers-in-egl_surface_free.patch deleted file mode 100644 index 43eb7f0b0..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0006-zero-out-wl-buffers-in-egl_surface_free.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0d678cd2042551cc4e26ec42fa3aba7c72d033b4 Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Sat, 6 Feb 2016 11:10:47 -0800 -Subject: [PATCH 06/16] zero-out wl buffers in egl_surface_free - -origins from buildroot - -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - interface/khronos/egl/egl_client_surface.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c -index 42350bf..1f923d9 100644 ---- a/interface/khronos/egl/egl_client_surface.c -+++ b/interface/khronos/egl/egl_client_surface.c -@@ -690,11 +690,13 @@ void egl_surface_free(EGL_SURFACE_T *surface) - if (surface->back_wl_buffer) { - wl_buffer_destroy(surface->back_wl_buffer->wl_buffer); - free(surface->back_wl_buffer); -+ surface->back_wl_buffer = 0; - } - - if (surface->front_wl_buffer) { - wl_buffer_destroy(surface->front_wl_buffer->wl_buffer); - free(surface->front_wl_buffer); -+ surface->front_wl_buffer = 0; - } - #endif - } --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0007-initialize-front-back-wayland-buffers.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0007-initialize-front-back-wayland-buffers.patch deleted file mode 100644 index 987740b07..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0007-initialize-front-back-wayland-buffers.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ec2e00989bf614b259bc9a47b5035f8586e8a214 Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Sat, 6 Feb 2016 11:11:41 -0800 -Subject: [PATCH 07/16] initialize front back wayland buffers - -origins from metrological wayland support - -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - interface/khronos/egl/egl_client_surface.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c -index 1f923d9..9a9582c 100644 ---- a/interface/khronos/egl/egl_client_surface.c -+++ b/interface/khronos/egl/egl_client_surface.c -@@ -401,11 +401,14 @@ EGL_SURFACE_T *egl_surface_create( - #ifdef BUILD_WAYLAND - if (type == WINDOW && wl_display) { - surface->wl_egl_window = (struct wl_egl_window*)win; -+ surface->front_wl_buffer = NULL; - surface->back_wl_buffer = allocate_wl_buffer( - surface->wl_egl_window, color); - resource = surface->back_wl_buffer->resource; - } else { - surface->wl_egl_window = NULL; -+ surface->front_wl_buffer = NULL; -+ surface->back_wl_buffer = NULL; - resource = DISPMANX_NO_HANDLE; - } - #endif --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0008-Remove-RPC_FLUSH.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0008-Remove-RPC_FLUSH.patch deleted file mode 100644 index 4bf05c129..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0008-Remove-RPC_FLUSH.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 59ba66c2ea17f7a57124b9fd6c9bdff4325ff5c9 Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Sat, 6 Feb 2016 11:09:18 -0800 -Subject: [PATCH 08/16] Remove RPC_FLUSH - -Origins from buildroot - -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - interface/khronos/ext/gl_oes_egl_image_client.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/interface/khronos/ext/gl_oes_egl_image_client.c b/interface/khronos/ext/gl_oes_egl_image_client.c -index f9b7287..b04ffef 100644 ---- a/interface/khronos/ext/gl_oes_egl_image_client.c -+++ b/interface/khronos/ext/gl_oes_egl_image_client.c -@@ -107,7 +107,6 @@ GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageO - GLEGLIMAGETARGETTEXTURE2DOES_ID, - RPC_ENUM(target), - RPC_EGLID(image)); -- RPC_FLUSH(thread); - #if EGL_BRCM_global_image - } - #endif --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0009-fix-cmake-dependency-race.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0009-fix-cmake-dependency-race.patch deleted file mode 100644 index a2c1df5b6..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0009-fix-cmake-dependency-race.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 264d82387ea1e607b2e5c899ff6bd46807c7b185 Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Sat, 6 Feb 2016 13:12:47 -0800 -Subject: [PATCH 09/16] fix cmake dependency race - -Fixes errors like - -/a/builder/mnt/build-oe/tmp-glibc/work/raspberrypi2-oe-linux-gnueabi/userland/git-r5/git/interface/vmcs_host/vc_vchi_dispmanx.h:72:66: -fatal error: interface/vmcs_host/wayland-dispmanx-server-protocol.h: No -such file or directory -compilation terminated. -interface/khronos/CMakeFiles/EGL_static.dir/build.make:773: recipe for -target 'interface/khronos/CMakeFiles/EGL_static.dir/ext/egl_wayland.c.o' -failed -make[2]: *** -[interface/khronos/CMakeFiles/EGL_static.dir/ext/egl_wayland.c.o] Error 1 - -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - interface/vcos/pthreads/CMakeLists.txt | 8 ++++++++ - interface/vmcs_host/CMakeLists.txt | 8 -------- - interface/vmcs_host/vc_vchi_dispmanx.h | 2 +- - 3 files changed, 9 insertions(+), 9 deletions(-) - -diff --git a/interface/vcos/pthreads/CMakeLists.txt b/interface/vcos/pthreads/CMakeLists.txt -index 1d81ca3..d6cd415 100644 ---- a/interface/vcos/pthreads/CMakeLists.txt -+++ b/interface/vcos/pthreads/CMakeLists.txt -@@ -33,6 +33,14 @@ set (SOURCES - ../generic/vcos_generic_blockpool.c - ) - -+if (BUILD_WAYLAND) -+wayland_add_protocol_server( -+ SOURCES -+ ../../../interface/wayland/dispmanx.xml -+ dispmanx -+) -+endif () -+ - if (VCOS_PTHREADS_BUILD_SHARED) - add_library (vcos SHARED ${SOURCES}) - target_link_libraries (vcos pthread dl rt) -diff --git a/interface/vmcs_host/CMakeLists.txt b/interface/vmcs_host/CMakeLists.txt -index 6718215..c415176 100755 ---- a/interface/vmcs_host/CMakeLists.txt -+++ b/interface/vmcs_host/CMakeLists.txt -@@ -17,14 +17,6 @@ set(VCHOSTIF_SOURCE - # ${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 ) -diff --git a/interface/vmcs_host/vc_vchi_dispmanx.h b/interface/vmcs_host/vc_vchi_dispmanx.h -index f0bae30..8c44c58 100644 ---- a/interface/vmcs_host/vc_vchi_dispmanx.h -+++ b/interface/vmcs_host/vc_vchi_dispmanx.h -@@ -69,7 +69,7 @@ typedef struct { - #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" -+#include "interface/vcos/pthreads/wayland-dispmanx-server-protocol.h" - struct wl_dispmanx_server_buffer { - struct wl_resource *resource; - struct wl_dispmanx *dispmanx; --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0010-Fix-for-framerate-with-nested-composition.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0010-Fix-for-framerate-with-nested-composition.patch deleted file mode 100644 index a6c9a59fb..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0010-Fix-for-framerate-with-nested-composition.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 7c51c2d37bfadaabbbf205237d932b685b09d34f Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Tue, 29 Mar 2016 20:38:30 -0700 -Subject: [PATCH 10/16] Fix for framerate with nested composition - -frame rate appears irregular and lower than expected when using nested composition. - -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - interface/khronos/egl/egl_client.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/interface/khronos/egl/egl_client.c b/interface/khronos/egl/egl_client.c -index 03fe67b..13a110c 100644 ---- a/interface/khronos/egl/egl_client.c -+++ b/interface/khronos/egl/egl_client.c -@@ -2342,6 +2342,9 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf) - surface->back_wl_buffer = buffer; - } - -+ glFlush(); -+ glFinish(); -+ - RPC_CALL7(eglIntSwapBuffers_impl, - thread, - EGLINTSWAPBUFFERS_ID_V2, -@@ -2353,6 +2356,8 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf) - RPC_UINT(khrn_platform_get_window_position(surface->win)), - RPC_INT(surface->back_wl_buffer->resource)); - -+ RPC_FLUSH(thread); -+ - surface->front_wl_buffer->in_use = 1; - wl_surface_attach(wl_egl_window->wl_surface, - surface->front_wl_buffer->wl_buffer, -@@ -2360,11 +2365,13 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf) - wl_surface_damage(wl_egl_window->wl_surface, 0, 0, - surface->width, surface->height); - wl_surface_commit(wl_egl_window->wl_surface); -+ wl_display_flush(wl_display); - - 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, -@@ -2376,6 +2383,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf) - RPC_UINT(khrn_platform_get_window_position(surface->win))); - - RPC_FLUSH(thread); -+ } - - #ifdef ANDROID - CLIENT_UNLOCK(); --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0011-build-shared-library-for-vchostif.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0011-build-shared-library-for-vchostif.patch deleted file mode 100644 index 55a5be89a..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0011-build-shared-library-for-vchostif.patch +++ /dev/null @@ -1,28 +0,0 @@ -From fb3002f77a175633af31019c513754d2ef5f3ac0 Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Sat, 2 Apr 2016 10:37:24 -0700 -Subject: [PATCH 11/16] build shared library for vchostif - -Fixes #149 - -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - interface/vmcs_host/CMakeLists.txt | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/interface/vmcs_host/CMakeLists.txt b/interface/vmcs_host/CMakeLists.txt -index c415176..d0cca1a 100755 ---- a/interface/vmcs_host/CMakeLists.txt -+++ b/interface/vmcs_host/CMakeLists.txt -@@ -17,7 +17,7 @@ set(VCHOSTIF_SOURCE - # ${VMCS_TARGET}/vmcs_main.c - # vc_vchi_haud.c - --add_library(vchostif ${VCHOSTIF_SOURCE}) -+add_library(vchostif SHARED ${VCHOSTIF_SOURCE}) - - #add_library(bufman vc_vchi_bufman.c ) - --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0012-implement-buffer-wrapping-interface-for-dispmanx.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0012-implement-buffer-wrapping-interface-for-dispmanx.patch deleted file mode 100644 index 28a5fc6d8..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0012-implement-buffer-wrapping-interface-for-dispmanx.patch +++ /dev/null @@ -1,92 +0,0 @@ -From df8b9633a45069bdd1bf256d974636ef11aa39cb Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Sat, 2 Apr 2016 10:54:59 -0700 -Subject: [PATCH 12/16] implement buffer wrapping interface for dispmanx - -Courtesy: Zan Dobersek - -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - interface/khronos/ext/egl_wayland.c | 42 +++++++++++++++++++++++++++++++++++++ - interface/wayland/dispmanx.xml | 10 +++++++++ - 2 files changed, 52 insertions(+) - -diff --git a/interface/khronos/ext/egl_wayland.c b/interface/khronos/ext/egl_wayland.c -index 5730743..9ef89cd 100644 ---- a/interface/khronos/ext/egl_wayland.c -+++ b/interface/khronos/ext/egl_wayland.c -@@ -133,8 +133,50 @@ dispmanx_create_buffer(struct wl_client *client, struct wl_resource *resource, - buffer->handle); - } - -+static void -+dispmanx_wrap_buffer(struct wl_client *client, struct wl_resource *resource, -+ uint32_t id, uint32_t handle, 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 = handle; -+ 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); -+} -+ - static const struct wl_dispmanx_interface dispmanx_interface = { - dispmanx_create_buffer, -+ dispmanx_wrap_buffer, - }; - - static void -diff --git a/interface/wayland/dispmanx.xml b/interface/wayland/dispmanx.xml -index c18626d..11ed1ef 100644 ---- a/interface/wayland/dispmanx.xml -+++ b/interface/wayland/dispmanx.xml -@@ -118,6 +118,16 @@ - <arg name="buffer" type="object" interface="wl_buffer"/> - <arg name="handle" type="uint"/> - </event> -+ -+ <request name="wrap_buffer"> -+ <arg name="id" type="new_id" interface="wl_buffer"/> -+ <arg name="handle" type="uint"/> -+ <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> - </interface> - - </protocol> --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0013-Implement-triple-buffering-for-wayland.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0013-Implement-triple-buffering-for-wayland.patch deleted file mode 100644 index ebff3140f..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0013-Implement-triple-buffering-for-wayland.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 2e0e331da8556fecd841349cfae294baf0f14485 Mon Sep 17 00:00:00 2001 -From: Jeff Wannamaker <jeff_wannamaker@cable.comcast.com> -Date: Thu, 19 Jan 2017 18:56:07 +0000 -Subject: [PATCH 13/16] Implement triple buffering for wayland - -Change from double to triple buffering for wayland. -This enables higher frame rates without tearing artifacts -by allowing both the glFinish and the buffer release -interlock to operate without pushing the frame period -to two vertical intervals - -Signed-off-by: Jeff Wannamaker <jeff_wannamaker@cable.comcast.com> -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - interface/khronos/egl/egl_client.c | 3 ++- - interface/khronos/egl/egl_client_surface.c | 8 ++++++++ - interface/khronos/egl/egl_client_surface.h | 11 +++++++++++ - 3 files changed, 21 insertions(+), 1 deletion(-) - -diff --git a/interface/khronos/egl/egl_client.c b/interface/khronos/egl/egl_client.c -index 13a110c..0380274 100644 ---- a/interface/khronos/egl/egl_client.c -+++ b/interface/khronos/egl/egl_client.c -@@ -2323,7 +2323,8 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf) - - buffer_temp = surface->front_wl_buffer; - surface->front_wl_buffer = surface->back_wl_buffer; -- surface->back_wl_buffer = buffer_temp; -+ surface->back_wl_buffer = surface->middle_wl_buffer; -+ surface->middle_wl_buffer = buffer_temp; - - configid = egl_config_to_id(surface->config); - color = egl_config_get_color_format(configid); -diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c -index 9a9582c..10b3b04 100644 ---- a/interface/khronos/egl/egl_client_surface.c -+++ b/interface/khronos/egl/egl_client_surface.c -@@ -402,12 +402,14 @@ EGL_SURFACE_T *egl_surface_create( - if (type == WINDOW && wl_display) { - surface->wl_egl_window = (struct wl_egl_window*)win; - surface->front_wl_buffer = NULL; -+ surface->middle_wl_buffer = NULL; - surface->back_wl_buffer = allocate_wl_buffer( - surface->wl_egl_window, color); - resource = surface->back_wl_buffer->resource; - } else { - surface->wl_egl_window = NULL; - surface->front_wl_buffer = NULL; -+ surface->middle_wl_buffer = NULL; - surface->back_wl_buffer = NULL; - resource = DISPMANX_NO_HANDLE; - } -@@ -696,6 +698,12 @@ void egl_surface_free(EGL_SURFACE_T *surface) - surface->back_wl_buffer = 0; - } - -+ if (surface->middle_wl_buffer) { -+ wl_buffer_destroy(surface->middle_wl_buffer->wl_buffer); -+ free(surface->middle_wl_buffer); -+ surface->middle_wl_buffer = 0; -+ } -+ - if (surface->front_wl_buffer) { - wl_buffer_destroy(surface->front_wl_buffer->wl_buffer); - free(surface->front_wl_buffer); -diff --git a/interface/khronos/egl/egl_client_surface.h b/interface/khronos/egl/egl_client_surface.h -index e328b77..58a3184 100644 ---- a/interface/khronos/egl/egl_client_surface.h -+++ b/interface/khronos/egl/egl_client_surface.h -@@ -312,6 +312,17 @@ typedef struct { - */ - struct wl_dispmanx_client_buffer *front_wl_buffer; - -+ /* -+ middle_wl_buffer -+ -+ Validity: -+ type == WINDOW -+ -+ Invariant: -+ client-side information about the wl_buffer in the middle -+ */ -+ struct wl_dispmanx_client_buffer *middle_wl_buffer; -+ - /* - back_wl_buffer - --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0014-GLES2-gl2ext.h-Define-GL_R8_EXT-and-GL_RG8_EXT.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0014-GLES2-gl2ext.h-Define-GL_R8_EXT-and-GL_RG8_EXT.patch deleted file mode 100644 index 025b6bcb9..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0014-GLES2-gl2ext.h-Define-GL_R8_EXT-and-GL_RG8_EXT.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 8d9299d219a2a4f76f8278973584e1a9f7116c78 Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Wed, 10 May 2017 06:39:34 +0000 -Subject: [PATCH 14/16] GLES2/gl2ext.h: Define GL_R8_EXT and GL_RG8_EXT - -weston code uses these defines -Upstream-Status: Pending - -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - interface/khronos/include/GLES2/gl2ext.h | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/interface/khronos/include/GLES2/gl2ext.h b/interface/khronos/include/GLES2/gl2ext.h -index 4eacf7f..283e3e1 100644 ---- a/interface/khronos/include/GLES2/gl2ext.h -+++ b/interface/khronos/include/GLES2/gl2ext.h -@@ -327,6 +327,9 @@ typedef void* GLeglImageOES; - #define GL_RGBX_BRCM 0x80EE - #endif - -+#define GL_R8_EXT 0x8229 -+#define GL_RG8_EXT 0x822B -+ - /* GL_EXT_texture_type_2_10_10_10_REV */ - #ifndef GL_EXT_texture_type_2_10_10_10_REV - #define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0015-EGL-glplatform.h-define-EGL_CAST.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0015-EGL-glplatform.h-define-EGL_CAST.patch deleted file mode 100644 index 605d0c043..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0015-EGL-glplatform.h-define-EGL_CAST.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a2182e5437a6664cdb0f3330f6cbee873b6f975a Mon Sep 17 00:00:00 2001 -From: Andrea Galbusera <gizero@gmail.com> -Date: Fri, 14 Jul 2017 09:52:54 +0200 -Subject: [PATCH 15/16] EGL/glplatform.h: define EGL_CAST - -C++ / C typecast macros for special EGL handle values: used by libepoxy code -The definition comes from the updated version of this header in mesa. - -Upstream-Status: Pending ---- - interface/khronos/include/EGL/eglplatform.h | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/interface/khronos/include/EGL/eglplatform.h b/interface/khronos/include/EGL/eglplatform.h -index 1f7c930..c39d425 100644 ---- a/interface/khronos/include/EGL/eglplatform.h -+++ b/interface/khronos/include/EGL/eglplatform.h -@@ -202,4 +202,11 @@ EGLAPI void EGLAPIENTRY BEGL_GetDefaultDriverInterfaces(BEGL_DriverInterfaces *i - #include "interface/khronos/common/khrn_client_mangle.h" - #endif - -+/* C++ / C typecast macros for special EGL handle values */ -+#if defined(__cplusplus) -+#define EGL_CAST(type, value) (static_cast<type>(value)) -+#else -+#define EGL_CAST(type, value) ((type) (value)) -+#endif -+ - #endif /* __eglplatform_h */ --- -2.16.1 - diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0016-Allow-multiple-wayland-compositor-state-data-per-pro.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0016-Allow-multiple-wayland-compositor-state-data-per-pro.patch deleted file mode 100644 index d20ec829f..000000000 --- a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0016-Allow-multiple-wayland-compositor-state-data-per-pro.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 6b4c4d469d435bfcfb464356b6ccc9421c6b8fd5 Mon Sep 17 00:00:00 2001 -From: Jeff Wannamaker <jeff_wannamaker@cable.comcast.com> -Date: Sat, 27 Jan 2018 12:28:31 -0500 -Subject: [PATCH 16/16] Allow multiple wayland compositor state data per - process - -When eglBindWaylandDisplayWL is called store the wl_global -created in a list associated with the wayland display. -This allows multiple wayland compositor instances to be -created and used per process. This scenario is common for -applications integrating externl process UI elements -via embedded composition e.g. westeros - -Signed-off-by: Jeff Wannamaker <jeff_wannamaker@cable.comcast.com> -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - interface/khronos/common/khrn_client.c | 2 +- - interface/khronos/common/khrn_client.h | 11 +++++++- - interface/khronos/ext/egl_wayland.c | 50 ++++++++++++++++++++++++++++++---- - 3 files changed, 55 insertions(+), 8 deletions(-) - -diff --git a/interface/khronos/common/khrn_client.c b/interface/khronos/common/khrn_client.c -index d7e798e..60bdb63 100644 ---- a/interface/khronos/common/khrn_client.c -+++ b/interface/khronos/common/khrn_client.c -@@ -147,7 +147,7 @@ bool client_process_state_init(CLIENT_PROCESS_STATE_T *process) - { - if (!process->inited) { - #ifdef BUILD_WAYLAND -- process->wl_global = NULL; -+ process->wlStateMap = NULL; - #endif - - if (!khrn_pointer_map_init(&process->contexts, 64)) -diff --git a/interface/khronos/common/khrn_client.h b/interface/khronos/common/khrn_client.h -index 615f7b4..4fa86f7 100644 ---- a/interface/khronos/common/khrn_client.h -+++ b/interface/khronos/common/khrn_client.h -@@ -170,6 +170,15 @@ static INLINE CLIENT_THREAD_STATE_T *CLIENT_GET_CHECK_THREAD_STATE(void) - return (CLIENT_THREAD_STATE_T *)platform_tls_get_check(client_tls); - } - -+#ifdef BUILD_WAYLAND -+typedef struct WAYLAND_STATE -+{ -+ struct WAYLAND_STATE *next; -+ struct wl_display *display; -+ struct wl_global *wl_global; -+} WAYLAND_STATE_T; -+#endif -+ - /* - per-process state - -@@ -318,7 +327,7 @@ struct CLIENT_PROCESS_STATE { - struct wl_event_queue *wl_queue; - - /* Compositor-side Wayland state */ -- struct wl_global *wl_global; -+ WAYLAND_STATE_T *wlStateMap; - #endif - }; - -diff --git a/interface/khronos/ext/egl_wayland.c b/interface/khronos/ext/egl_wayland.c -index 9ef89cd..abd5ab3 100644 ---- a/interface/khronos/ext/egl_wayland.c -+++ b/interface/khronos/ext/egl_wayland.c -@@ -208,17 +208,38 @@ eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) - { - CLIENT_THREAD_STATE_T *thread; - CLIENT_PROCESS_STATE_T *process; -+ WAYLAND_STATE_T *stateIter; -+ WAYLAND_STATE_T *stateNew; -+ struct wl_global *wl_global; - - if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process)) - return EGL_FALSE; - -- if (process->wl_global != NULL) -+ stateIter= process->wlStateMap; -+ while( stateIter ) -+ { -+ if ( stateIter->display == display ) -+ goto error; -+ stateIter= stateIter->next; -+ } -+ -+ wl_global = wl_global_create(display, &wl_dispmanx_interface, 1, -+ NULL, bind_dispmanx); -+ if (wl_global == NULL) - goto error; - -- process->wl_global = wl_global_create(display, &wl_dispmanx_interface, 1, -- NULL, bind_dispmanx); -- if (process->wl_global == NULL) -+ stateNew= (WAYLAND_STATE_T*)calloc( 1, sizeof(WAYLAND_STATE_T)); -+ if (stateNew == NULL ) -+ { -+ wl_global_destroy(wl_global); - goto error; -+ } -+ -+ stateNew->next= process->wlStateMap; -+ stateNew->display= display; -+ stateNew->wl_global= wl_global; -+ process->wlStateMap= stateNew; -+ CLIENT_UNLOCK(); - - return EGL_TRUE; - -@@ -232,12 +253,29 @@ eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) - { - CLIENT_THREAD_STATE_T *thread; - CLIENT_PROCESS_STATE_T *process; -+ WAYLAND_STATE_T *stateIter; -+ WAYLAND_STATE_T *statePrev; - - if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process)) - return EGL_FALSE; - -- wl_global_destroy(process->wl_global); -- process->wl_global = NULL; -+ statePrev= NULL; -+ stateIter= process->wlStateMap; -+ while( stateIter ) -+ { -+ if ( stateIter->display == display ) -+ { -+ wl_global_destroy(stateIter->wl_global); -+ if ( statePrev ) -+ statePrev->next= stateIter->next; -+ else -+ process->wlStateMap= stateIter->next; -+ free( stateIter ); -+ break; -+ } -+ statePrev= stateIter; -+ stateIter= stateIter->next; -+ } - - CLIENT_UNLOCK(); - --- -2.16.1 - |