summaryrefslogtreecommitdiffstats
path: root/recipes-graphics/userland/files
diff options
context:
space:
mode:
authorKhem Raj <raj.khem@gmail.com>2018-11-06 23:16:02 -0800
committerAndrei Gherzan <andrei@gherzan.ro>2018-11-07 14:25:00 +0000
commitd05f5590891cc0d107473e1bf2e36523678d0114 (patch)
tree6831b10e4828f7a87020c9a10289ff17720afaa5 /recipes-graphics/userland/files
parentf7a2726cdf741e71e1bab81b46ba1e3e20f4b1f7 (diff)
downloadmeta-raspberrypi-d05f5590891cc0d107473e1bf2e36523678d0114.tar.gz
userland-nogl: Add recipe which does not include GL libraries
This is needed when mesa is providing these libraries especially when using vc4graphics Signed-off-by: Khem Raj <raj.khem@gmail.com>
Diffstat (limited to 'recipes-graphics/userland/files')
-rw-r--r--recipes-graphics/userland/files/0001-Allow-applications-to-set-next-resource-handle.patch208
-rw-r--r--recipes-graphics/userland/files/0002-wayland-Add-support-for-the-Wayland-winsys.patch1861
-rw-r--r--recipes-graphics/userland/files/0003-wayland-Add-Wayland-example.patch866
-rw-r--r--recipes-graphics/userland/files/0004-wayland-egl-Add-bcm_host-to-dependencies.patch28
-rw-r--r--recipes-graphics/userland/files/0005-interface-remove-faulty-assert-to-make-weston-happy-.patch29
-rw-r--r--recipes-graphics/userland/files/0006-zero-out-wl-buffers-in-egl_surface_free.patch33
-rw-r--r--recipes-graphics/userland/files/0007-initialize-front-back-wayland-buffers.patch34
-rw-r--r--recipes-graphics/userland/files/0008-Remove-RPC_FLUSH.patch27
-rw-r--r--recipes-graphics/userland/files/0009-fix-cmake-dependency-race.patch78
-rw-r--r--recipes-graphics/userland/files/0010-Fix-for-framerate-with-nested-composition.patch60
-rw-r--r--recipes-graphics/userland/files/0011-build-shared-library-for-vchostif.patch28
-rw-r--r--recipes-graphics/userland/files/0012-implement-buffer-wrapping-interface-for-dispmanx.patch92
-rw-r--r--recipes-graphics/userland/files/0013-Implement-triple-buffering-for-wayland.patch90
-rw-r--r--recipes-graphics/userland/files/0014-GLES2-gl2ext.h-Define-GL_R8_EXT-and-GL_RG8_EXT.patch35
-rw-r--r--recipes-graphics/userland/files/0015-EGL-glplatform.h-define-EGL_CAST.patch32
-rw-r--r--recipes-graphics/userland/files/0016-Allow-multiple-wayland-compositor-state-data-per-pro.patch145
-rw-r--r--recipes-graphics/userland/files/0017-khronos-backport-typedef-for-EGL_EXT_image_dma_buf_i.patch35
-rw-r--r--recipes-graphics/userland/files/0018-Add-EGL_IMG_context_priority-related-defines.patch35
18 files changed, 3716 insertions, 0 deletions
diff --git a/recipes-graphics/userland/files/0001-Allow-applications-to-set-next-resource-handle.patch b/recipes-graphics/userland/files/0001-Allow-applications-to-set-next-resource-handle.patch
new file mode 100644
index 0000000..933f279
--- /dev/null
+++ b/recipes-graphics/userland/files/0001-Allow-applications-to-set-next-resource-handle.patch
@@ -0,0 +1,208 @@
1From 0a64dc61d3d7db69389157ae757203b4b3afdbfa Mon Sep 17 00:00:00 2001
2From: Dom Cobley <dc4@broadcom.com>
3Date: Tue, 9 Jul 2013 09:26:26 -0400
4Subject: [PATCH 01/16] Allow applications to set next resource handle
5
6This patch adds provisions in userland to
7let apps callers set the next rendereing dispmanx resource.
8It's useful for implementing, say, a buffer carousel.
9---
10 interface/khronos/common/khrn_client_rpc.h | 2 ++
11 interface/khronos/common/khrn_int_ids.h | 2 ++
12 interface/khronos/egl/egl_client.c | 30 +++++++++++++++++++++++++++---
13 interface/khronos/egl/egl_client_surface.c | 24 +++++++++++++++++++++++-
14 interface/khronos/egl/egl_client_surface.h | 3 ++-
15 interface/khronos/egl/egl_int_impl.h | 5 +++--
16 6 files changed, 59 insertions(+), 7 deletions(-)
17
18diff --git a/interface/khronos/common/khrn_client_rpc.h b/interface/khronos/common/khrn_client_rpc.h
19index dc4351d..10ea060 100644
20--- a/interface/khronos/common/khrn_client_rpc.h
21+++ b/interface/khronos/common/khrn_client_rpc.h
22@@ -685,6 +685,7 @@ static INLINE void rpc_call12_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id
23 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); }
24 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); }
25 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); }
26+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); }
27 #endif
28
29 #define RPC_CALL1_OUT_CTRL(fn, thread, id, out) rpc_call1_out_ctrl(thread, id, out)
30@@ -702,6 +703,7 @@ static INLINE void rpc_call15_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id
31 #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)
32 #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)
33 #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)
34+#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)
35
36 # if !defined(__SYMBIAN32__) //use functions defined in khrpc.cpp
37 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; }
38diff --git a/interface/khronos/common/khrn_int_ids.h b/interface/khronos/common/khrn_int_ids.h
39index 8378f4a..ec961e0 100644
40--- a/interface/khronos/common/khrn_int_ids.h
41+++ b/interface/khronos/common/khrn_int_ids.h
42@@ -367,6 +367,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 */
44
45 #define EGLINTCREATESURFACE_ID 0x4000
46+#define EGLINTCREATESURFACE_ID_V2 0x4100
47 #define EGLINTCREATEGLES11_ID 0x4001
48 #define EGLINTCREATEGLES20_ID 0x4002
49 #define EGLINTCREATEVG_ID 0x4003
50@@ -377,6 +378,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 #define EGLINTMAKECURRENT_ID 0x4008
52 #define EGLINTFLUSHANDWAIT_ID 0x4009
53 #define EGLINTSWAPBUFFERS_ID 0x400a
54+#define EGLINTSWAPBUFFERS_ID_V2 0x410a
55 #define EGLINTSELECTMIPMAP_ID 0x400b
56 #define EGLINTFLUSH_ID 0x400c
57 #define EGLINTGETCOLORDATA_ID 0x400d
58diff --git a/interface/khronos/egl/egl_client.c b/interface/khronos/egl/egl_client.c
59index 9d617c8..b8bb374 100644
60--- a/interface/khronos/egl/egl_client.c
61+++ b/interface/khronos/egl/egl_client.c
62@@ -162,6 +162,17 @@ static void egl_current_release(CLIENT_PROCESS_STATE_T *process, EGL_CURRENT_T *
63 void egl_gl_flush_callback(bool wait);
64 void egl_vg_flush_callback(bool wait);
65
66+#include "interface/vmcs_host/vc_dispmanx_types.h"
67+/**HACKHACK - give us the ability to inject a DispmanX
68+ * resource handle into the CreateWindowSurface and
69+ * SwapBuffers calls */
70+static DISPMANX_RESOURCE_HANDLE_T next_resource_handle;
71+
72+EGLAPI EGLBoolean EGLAPIENTRY eglSetNextResourceHandle(DISPMANX_RESOURCE_HANDLE_T handle)
73+{
74+ next_resource_handle = handle;
75+}
76+
77 /*
78 TODO: do an RPC call to make sure the Khronos vll is loaded (and that it stays loaded until eglTerminate)
79 Also affects global image (and possibly others?)
80@@ -644,7 +655,8 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig c
81 false,
82 EGL_NO_TEXTURE,
83 EGL_NO_TEXTURE,
84- 0, 0);
85+ 0, 0,
86+ next_resource_handle);
87
88 if (surface) {
89 if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
90@@ -889,7 +901,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig
91 mipmap_texture,
92 texture_format,
93 texture_target,
94- 0, 0);
95+ 0, 0, 0);
96
97 if (surface) {
98 if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
99@@ -1031,7 +1043,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig c
100 false,
101 EGL_NO_TEXTURE,
102 EGL_NO_TEXTURE,
103- pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle);
104+ pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle, 0);
105
106 if (surface) {
107 if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
108@@ -2303,6 +2315,18 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
109
110 vcos_log_trace("eglSwapBuffers server call");
111
112+ if (next_resource_handle)
113+ RPC_CALL7(eglIntSwapBuffers_impl,
114+ thread,
115+ EGLINTSWAPBUFFERS_ID_V2,
116+ RPC_UINT(surface->serverbuffer),
117+ RPC_UINT(surface->width),
118+ RPC_UINT(surface->height),
119+ RPC_UINT(surface->internal_handle),
120+ RPC_UINT(surface->swap_behavior == EGL_BUFFER_PRESERVED ? 1 : 0),
121+ RPC_UINT(khrn_platform_get_window_position(surface->win)),
122+ RPC_INT(next_resource_handle));
123+ else
124 RPC_CALL6(eglIntSwapBuffers_impl,
125 thread,
126 EGLINTSWAPBUFFERS_ID,
127diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c
128index 6846dfa..128325e 100644
129--- a/interface/khronos/egl/egl_client_surface.c
130+++ b/interface/khronos/egl/egl_client_surface.c
131@@ -314,7 +314,8 @@ EGL_SURFACE_T *egl_surface_create(
132 EGLenum texture_format,
133 EGLenum texture_target,
134 EGLNativePixmapType pixmap,
135- const uint32_t *pixmap_server_handle)
136+ const uint32_t *pixmap_server_handle,
137+ DISPMANX_RESOURCE_HANDLE_T next_resource_handle)
138 {
139 KHRN_IMAGE_FORMAT_T color;
140 KHRN_IMAGE_FORMAT_T depth;
141@@ -473,6 +474,27 @@ EGL_SURFACE_T *egl_surface_create(
142 #endif
143 uint32_t results[3];
144
145+ if (next_resource_handle)
146+ RPC_CALL16_OUT_CTRL(eglIntCreateSurface_impl,
147+ thread,
148+ EGLINTCREATESURFACE_ID_V2,
149+ RPC_UINT(serverwin),
150+ RPC_UINT(buffers),
151+ RPC_UINT(width),
152+ RPC_UINT(height),
153+ RPC_UINT(color),
154+ RPC_UINT(depth),
155+ RPC_UINT(mask),
156+ RPC_UINT(multi),
157+ RPC_UINT(largest_pbuffer),
158+ RPC_UINT(mipmap_texture),
159+ RPC_UINT(config_depth_bits),
160+ RPC_UINT(config_stencil_bits),
161+ RPC_UINT(sem_name),
162+ RPC_UINT(type),
163+ RPC_INT(next_resource_handle),
164+ results);
165+ else
166 RPC_CALL15_OUT_CTRL(eglIntCreateSurface_impl,
167 thread,
168 EGLINTCREATESURFACE_ID,
169diff --git a/interface/khronos/egl/egl_client_surface.h b/interface/khronos/egl/egl_client_surface.h
170index c99d44c..b5bf70a 100644
171--- a/interface/khronos/egl/egl_client_surface.h
172+++ b/interface/khronos/egl/egl_client_surface.h
173@@ -322,7 +322,8 @@ extern EGL_SURFACE_T *egl_surface_create(
174 EGLenum texture_format,
175 EGLenum texture_target,
176 EGLNativePixmapType pixmap,
177- const uint32_t *pixmap_server_handle);
178+ const uint32_t *pixmap_server_handle,
179+ DISPMANX_RESOURCE_HANDLE_T next_resource_handle);
180 extern EGL_SURFACE_T *egl_surface_from_vg_image(
181 VGImage vg_handle,
182 EGLSurface name,
183diff --git a/interface/khronos/egl/egl_int_impl.h b/interface/khronos/egl/egl_int_impl.h
184index 8a5734c..51b3580 100644
185--- a/interface/khronos/egl/egl_int_impl.h
186+++ b/interface/khronos/egl/egl_int_impl.h
187@@ -56,7 +56,8 @@ FN(int, eglIntCreateSurface_impl, (
188 uint32_t config_stencil_bits,
189 uint32_t sem,
190 uint32_t type,
191- uint32_t *results))
192+ uint32_t *results,
193+ DISPMANX_RESOURCE_HANDLE_T next_resource_handle))
194
195 FN(int, eglIntCreatePbufferFromVGImage_impl, (
196 VGImage vg_handle,
197@@ -110,7 +111,7 @@ FN(void, eglIntMakeCurrent_impl, (uint32_t pid_0, uint32_t pid_1, uint32_t glver
198 FN(int, eglIntFlushAndWait_impl, (uint32_t flushgl, uint32_t flushvg))
199 FN(void, eglIntFlush_impl, (uint32_t flushgl, uint32_t flushvg))
200
201-FN(void, eglIntSwapBuffers_impl, (EGL_SURFACE_ID_T s, uint32_t width, uint32_t height, uint32_t handle, uint32_t preserve, uint32_t position))
202+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))
203 FN(void, eglIntSelectMipmap_impl, (EGL_SURFACE_ID_T s, int level))
204
205 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))
206--
2072.16.1
208
diff --git a/recipes-graphics/userland/files/0002-wayland-Add-support-for-the-Wayland-winsys.patch b/recipes-graphics/userland/files/0002-wayland-Add-support-for-the-Wayland-winsys.patch
new file mode 100644
index 0000000..4613504
--- /dev/null
+++ b/recipes-graphics/userland/files/0002-wayland-Add-support-for-the-Wayland-winsys.patch
@@ -0,0 +1,1861 @@
1From 5608ec8002be8370e78c9dbb1e07cee4cfb18b58 Mon Sep 17 00:00:00 2001
2From: Tomeu Vizoso <tomeu.vizoso@collabora.com>
3Date: Tue, 1 Oct 2013 13:19:20 +0200
4Subject: [PATCH 02/16] wayland: Add support for the Wayland winsys
5
6* Adds EGL_WL_bind_wayland_display extension
7* Adds wayland-egl library
8* Adds wl_dispmanx_buffer protocol extension
9
10TODO: Check that platform_get_dimensions() returning swapchain_count == 1 is correct
11
12TODO: Remove the requirement of passing a valid DispmanX element handle to
13the SwapBuffers and CreateSurface RPC calls. This will remove the need to open
14a DispmanX display from the clients.
15
16TODO: wl_dispmanx_server_buffer should probably be defined in a
17private header that can be included from EGL and vc_* instead of in
18vc_vchi_dispmanx.h
19---
20 .gitignore | 1 +
21 CMakeLists.txt | 11 +
22 README.md | 4 +
23 buildme | 10 +-
24 .../linux/apps/raspicam/CMakeLists.txt | 2 +-
25 interface/khronos/CMakeLists.txt | 53 ++++-
26 interface/khronos/common/khrn_client.c | 15 ++
27 interface/khronos/common/khrn_client.h | 10 +
28 interface/khronos/common/khrn_client_mangle.h | 3 +
29 interface/khronos/common/khrn_client_platform.h | 8 +
30 interface/khronos/common/khrn_client_unmangle.h | 3 +
31 .../common/linux/khrn_client_platform_linux.c | 115 ++++++++--
32 interface/khronos/common/linux/khrn_wayland.c | 215 ++++++++++++++++++
33 .../common/linux/khrn_wayland.h} | 46 +---
34 interface/khronos/egl/egl_client.c | 92 +++++---
35 interface/khronos/egl/egl_client_get_proc.c | 11 +
36 interface/khronos/egl/egl_client_surface.c | 42 +++-
37 interface/khronos/egl/egl_client_surface.h | 38 +++-
38 interface/khronos/egl/egl_int_impl.h | 2 +-
39 interface/khronos/ext/egl_wayland.c | 246 +++++++++++++++++++++
40 interface/khronos/include/EGL/eglext.h | 23 ++
41 interface/khronos/wayland-egl/wayland-egl-priv.h | 53 +++++
42 interface/khronos/wayland-egl/wayland-egl.c | 59 +++++
43 interface/khronos/wayland-egl/wayland-egl.pc.in | 10 +
44 interface/vmcs_host/CMakeLists.txt | 21 +-
45 interface/vmcs_host/vc_dispmanx.h | 10 +
46 interface/vmcs_host/vc_vchi_dispmanx.c | 42 ++++
47 interface/vmcs_host/vc_vchi_dispmanx.h | 15 ++
48 interface/wayland/dispmanx.xml | 123 +++++++++++
49 makefiles/cmake/Wayland.cmake | 72 ++++++
50 30 files changed, 1257 insertions(+), 98 deletions(-)
51 create mode 100644 interface/khronos/common/linux/khrn_wayland.c
52 copy interface/{vmcs_host/vc_vchi_dispmanx.h => khronos/common/linux/khrn_wayland.h} (56%)
53 create mode 100644 interface/khronos/ext/egl_wayland.c
54 create mode 100644 interface/khronos/wayland-egl/wayland-egl-priv.h
55 create mode 100644 interface/khronos/wayland-egl/wayland-egl.c
56 create mode 100644 interface/khronos/wayland-egl/wayland-egl.pc.in
57 create mode 100644 interface/wayland/dispmanx.xml
58 create mode 100644 makefiles/cmake/Wayland.cmake
59
60Index: git/.gitignore
61===================================================================
62--- git.orig/.gitignore
63+++ git/.gitignore
64@@ -30,3 +30,4 @@ build/
65 *.pts
66 *.ppm
67 *.mkv
68+*~
69Index: git/CMakeLists.txt
70===================================================================
71--- git.orig/CMakeLists.txt
72+++ git/CMakeLists.txt
73@@ -24,6 +24,17 @@ include(makefiles/cmake/global_settings.
74 include(makefiles/cmake/arm-linux.cmake)
75 include(makefiles/cmake/vmcs.cmake)
76
77+if (BUILD_WAYLAND)
78+ include(makefiles/cmake/Wayland.cmake)
79+
80+ # Find Wayland libraries
81+ find_package(PkgConfig)
82+ pkg_check_modules(WAYLAND_CLIENT wayland-client REQUIRED)
83+ pkg_check_modules(WAYLAND_SERVER wayland-server REQUIRED)
84+
85+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBUILD_WAYLAND")
86+endif()
87+
88 enable_language(ASM)
89
90 # Global include paths
91Index: git/README.md
92===================================================================
93--- git.orig/README.md
94+++ git/README.md
95@@ -6,3 +6,7 @@ Use buildme to build. It requires cmake
96 https://github.com/raspberrypi/tools/tree/master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian
97
98 Note that this repository does not contain the source for the edid_parser and vcdbg binaries due to licensing restrictions.
99+
100+To build support for the Wayland winsys in EGL, execute the buildme script like this:
101+
102+$ BUILD_WAYLAND=1 ./buildme.
103Index: git/buildme
104===================================================================
105--- git.orig/buildme
106+++ git/buildme
107@@ -8,6 +8,10 @@ fi
108
109 BUILDSUBDIR=`echo $BUILDTYPE | tr '[A-Z]' '[a-z]'`;
110
111+if [ -n "$BUILD_WAYLAND" ]; then
112+ WAYLAND_VARS="-DBUILD_WAYLAND=TRUE"
113+fi
114+
115 if [ "armv6l" = `arch` ] || [ "armv7l" = `arch` ]; then
116 # Native compile on the Raspberry Pi
117 mkdir -p build/raspberry/$BUILDSUBDIR
118@@ -32,9 +36,13 @@ elif [ "$1" = "--native" ]; then
119 make -j `nproc` $*
120 else
121 # Cross compile on a more capable machine
122+ if [ -n "$BUILD_WAYLAND" ]; then
123+ # Use wayland-scanner from the build platform
124+ WAYLAND_VARS+=" -DWAYLAND_SCANNER_EXECUTABLE:FILEPATH=/usr/bin/wayland-scanner"
125+ fi
126 mkdir -p build/arm-linux/$BUILDSUBDIR
127 pushd build/arm-linux/$BUILDSUBDIR
128- cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=$BUILDTYPE ../../..
129+ cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=$BUILDTYPE $WAYLAND_VARS ../../..
130 make -j `nproc`
131
132 if [ "$1" != "" ]; then
133Index: git/host_applications/linux/apps/raspicam/CMakeLists.txt
134===================================================================
135--- git.orig/host_applications/linux/apps/raspicam/CMakeLists.txt
136+++ git/host_applications/linux/apps/raspicam/CMakeLists.txt
137@@ -28,7 +28,7 @@ add_executable(raspividyuv ${COMMON_SOU
138
139 set (MMAL_LIBS mmal_core mmal_util mmal_vc_client)
140
141-target_link_libraries(raspistill ${MMAL_LIBS} vcos bcm_host brcmGLESv2 brcmEGL m)
142+target_link_libraries(raspistill ${MMAL_LIBS} vcos bcm_host brcmGLESv2 brcmEGL m ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_CLIENT_LIBRARIES})
143 target_link_libraries(raspiyuv ${MMAL_LIBS} vcos bcm_host)
144 target_link_libraries(raspivid ${MMAL_LIBS} vcos bcm_host)
145 target_link_libraries(raspividyuv ${MMAL_LIBS} vcos bcm_host)
146Index: git/interface/khronos/CMakeLists.txt
147===================================================================
148--- git.orig/interface/khronos/CMakeLists.txt
149+++ git/interface/khronos/CMakeLists.txt
150@@ -6,6 +6,12 @@
151 # have quite a few circular dependencies, and so the only way
152 # to make it work seems to be to have everything static.
153
154+if (BUILD_WAYLAND)
155+include_directories(
156+ ${WAYLAND_SERVER_INCLUDE_DIRS}
157+)
158+endif ()
159+
160 set(EGL_SOURCE
161 egl/egl_client_config.c
162 egl/egl_client_context.c
163@@ -55,12 +61,55 @@ set(CLIENT_SOURCE
164 common/khrn_int_hash_asm.s
165 common/khrn_client_cache.c)
166
167+set(EGL_LIBS
168+ khrn_client
169+ vchiq_arm
170+ vcos
171+ bcm_host)
172+
173+if (BUILD_WAYLAND)
174+ set(EGL_SOURCE
175+ ${EGL_SOURCE}
176+ ext/egl_wayland.c
177+ common/linux/khrn_wayland.c)
178+
179+ set(EGL_LIBS
180+ ${EGL_LIBS}
181+ wayland-client
182+ wayland-server)
183+
184+ set(WAYLAND_EGL_SOURCE
185+ wayland-egl/wayland-egl.c)
186+
187+ wayland_add_protocol_server(
188+ EGL_SOURCE
189+ ../../interface/wayland/dispmanx.xml
190+ dispmanx
191+ )
192+
193+ wayland_add_protocol_client(
194+ EGL_SOURCE
195+ ../../interface/wayland/dispmanx.xml
196+ dispmanx
197+ )
198+
199+ add_library(wayland-egl ${SHARED} ${WAYLAND_EGL_SOURCE})
200+ install(TARGETS wayland-egl DESTINATION lib)
201+
202+ configure_file ("wayland-egl/wayland-egl.pc.in" "wayland-egl/wayland-egl.pc" @ONLY)
203+ install (FILES "${CMAKE_CURRENT_BINARY_DIR}/wayland-egl/wayland-egl.pc"
204+ DESTINATION lib/pkgconfig)
205+endif ()
206+
207 add_library(EGL ${SHARED} ${EGL_SOURCE})
208 add_library(GLESv2 ${SHARED} ${GLES_SOURCE})
209 add_library(OpenVG ${SHARED} ${VG_SOURCE})
210 add_library(WFC ${SHARED} ${WFC_SOURCE})
211 add_library(khrn_client ${CLIENT_SOURCE})
212
213+set_target_properties(EGL PROPERTIES SOVERSION 1 VERSION 1.0.0)
214+set_target_properties(GLESv2 PROPERTIES SOVERSION 2 VERSION 2.0.0)
215+
216 # TODO do we need EGL_static and GLESv2_static now that khrn_static exists?
217 add_library(EGL_static STATIC ${EGL_SOURCE})
218 add_library(GLESv2_static STATIC ${GLES_SOURCE})
219@@ -72,8 +121,7 @@ include_directories (../../host_applicat
220 set(VCSM_LIBS vcsm)
221 add_definitions(-DKHRONOS_HAVE_VCSM)
222 endif()
223-
224-target_link_libraries(EGL khrn_client vchiq_arm vcos bcm_host ${VCSM_LIBS} -lm)
225+target_link_libraries(EGL ${EGL_LIBS} ${VCSM_LIBS} -lm)
226 target_link_libraries(GLESv2 EGL khrn_client vcos)
227 target_link_libraries(WFC EGL)
228 target_link_libraries(OpenVG EGL)
229@@ -87,7 +135,7 @@ add_library(brcmGLESv2 ${SHARED} ${GLES_
230 add_library(brcmOpenVG ${SHARED} ${VG_SOURCE})
231 add_library(brcmWFC ${SHARED} ${WFC_SOURCE})
232
233-target_link_libraries(brcmEGL khrn_client vchiq_arm vcos bcm_host ${VCSM_LIBS} -lm)
234+target_link_libraries(brcmEGL ${EGL_LIBS} ${VCSM_LIBS} -lm)
235 target_link_libraries(brcmGLESv2 brcmEGL khrn_client vcos)
236 target_link_libraries(brcmWFC brcmEGL)
237 target_link_libraries(brcmOpenVG brcmEGL)
238Index: git/interface/khronos/common/khrn_client.c
239===================================================================
240--- git.orig/interface/khronos/common/khrn_client.c
241+++ git/interface/khronos/common/khrn_client.c
242@@ -54,6 +54,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
243 #include "applications/vmcs/khronos/khronos_server.h"
244 #endif
245
246+#ifdef BUILD_WAYLAND
247+#include "interface/khronos/common/linux/khrn_wayland.h"
248+#endif
249+
250 VCOS_LOG_CAT_T khrn_client_log = VCOS_LOG_INIT("khrn_client", VCOS_LOG_WARN);
251
252 /*
253@@ -142,6 +146,10 @@ void client_try_unload_server(CLIENT_PRO
254 bool client_process_state_init(CLIENT_PROCESS_STATE_T *process)
255 {
256 if (!process->inited) {
257+#ifdef BUILD_WAYLAND
258+ process->wl_global = NULL;
259+#endif
260+
261 if (!khrn_pointer_map_init(&process->contexts, 64))
262 return false;
263
264@@ -194,6 +202,13 @@ bool client_process_state_init(CLIENT_PR
265 }
266 #endif
267
268+#ifdef BUILD_WAYLAND
269+ struct wl_display *wl_display = khrn_platform_get_wl_display();
270+ if (wl_display)
271+ if (!init_process_wayland(process))
272+ return false;
273+#endif
274+
275 process->inited = true;
276 }
277
278Index: git/interface/khronos/common/khrn_client.h
279===================================================================
280--- git.orig/interface/khronos/common/khrn_client.h
281+++ git/interface/khronos/common/khrn_client.h
282@@ -310,6 +310,16 @@ struct CLIENT_PROCESS_STATE {
283 #ifdef RPC_LIBRARY
284 KHRONOS_SERVER_CONNECTION_T khrn_connection;
285 #endif
286+
287+#ifdef BUILD_WAYLAND
288+ /* Client-side Wayland state */
289+ struct wl_registry *wl_registry;
290+ struct wl_dispmanx *wl_dispmanx;
291+ struct wl_event_queue *wl_queue;
292+
293+ /* Compositor-side Wayland state */
294+ struct wl_global *wl_global;
295+#endif
296 };
297
298 extern bool client_process_state_init(CLIENT_PROCESS_STATE_T *process);
299Index: git/interface/khronos/common/khrn_client_mangle.h
300===================================================================
301--- git.orig/interface/khronos/common/khrn_client_mangle.h
302+++ git/interface/khronos/common/khrn_client_mangle.h
303@@ -83,6 +83,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
304 #define eglReleaseGlobalImageBRCM mangled_eglReleaseGlobalImageBRCM
305 #define eglInitGlobalImageBRCM mangled_eglInitGlobalImageBRCM
306 #define eglTermGlobalImageBRCM mangled_eglTermGlobalImageBRCM
307+#define eglBindWaylandDisplayWL mangled_eglBindWaylandDisplayWL
308+#define eglUnbindWaylandDisplayWL mangled_eglUnbindWaylandDisplayWL
309+#define eglQueryWaylandBufferWL mangled_eglQueryWaylandBufferWL
310
311 /* OpenGL ES 1.1 and 2.0 functions */
312
313Index: git/interface/khronos/common/khrn_client_platform.h
314===================================================================
315--- git.orig/interface/khronos/common/khrn_client_platform.h
316+++ git/interface/khronos/common/khrn_client_platform.h
317@@ -48,6 +48,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
318 #include "interface/khronos/common/vcos/khrn_client_platform_filler_vcos.h"
319 #endif
320
321+#ifdef BUILD_WAYLAND
322+#include <wayland-client.h>
323+#endif
324+
325 #ifdef __cplusplus
326 extern "C" {
327 #endif
328@@ -328,4 +332,8 @@ typedef struct
329
330 void *platform_wfc_bounce_thread(void *param);
331
332+#ifdef BUILD_WAYLAND
333+struct wl_display *khrn_platform_get_wl_display();
334+#endif
335+
336 #endif // KHRN_CLIENT_PLATFORM_H
337Index: git/interface/khronos/common/khrn_client_unmangle.h
338===================================================================
339--- git.orig/interface/khronos/common/khrn_client_unmangle.h
340+++ git/interface/khronos/common/khrn_client_unmangle.h
341@@ -83,6 +83,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
342 #undef eglReleaseGlobalImageBRCM
343 #undef eglInitGlobalImageBRCM
344 #undef eglTermGlobalImageBRCM
345+#undef eglBindWaylandDisplayWL
346+#undef eglUnbindWaylandDisplayWL
347+#undef eglQueryWaylandBufferWL
348
349 /* OpenGL ES 1.1 and 2.0 functions */
350
351Index: git/interface/khronos/common/linux/khrn_client_platform_linux.c
352===================================================================
353--- git.orig/interface/khronos/common/linux/khrn_client_platform_linux.c
354+++ git/interface/khronos/common/linux/khrn_client_platform_linux.c
355@@ -37,6 +37,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
356 #include "X11/Xlib.h"
357 #endif
358
359+#ifdef BUILD_WAYLAND
360+#include <wayland-client.h>
361+#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
362+#endif
363+
364 extern VCOS_LOG_CAT_T khrn_client_log;
365
366 extern void vc_vchi_khronos_init();
367@@ -464,14 +469,37 @@ EGLDisplay khrn_platform_set_display_id(
368 return EGL_NO_DISPLAY;
369 }
370 #else
371+
372+#ifdef BUILD_WAYLAND
373+static struct wl_display *hacky_display = NULL;
374+#endif
375+
376 EGLDisplay khrn_platform_set_display_id(EGLNativeDisplayType display_id)
377 {
378 if (display_id == EGL_DEFAULT_DISPLAY)
379 return (EGLDisplay)1;
380- else
381- return EGL_NO_DISPLAY;
382+ else {
383+#ifdef BUILD_WAYLAND
384+ void *first_pointer = *(void **) display_id;
385+
386+ /* wl_display is a wl_proxy, which is a wl_object.
387+ * wl_object's first element points to the interfacetype. */
388+ if (first_pointer == &wl_display_interface) {
389+ hacky_display = (struct wl_display*)display_id;
390+ return (EGLDisplay)1;
391+ } else
392+#endif
393+ return EGL_NO_DISPLAY;
394+ }
395+}
396+
397+#ifdef BUILD_WAYLAND
398+struct wl_display *khrn_platform_get_wl_display()
399+{
400+ return hacky_display;
401 }
402 #endif
403+#endif
404
405 #ifdef WANT_X
406 static void dump_hierarchy(Window w, Window thisw, Window look, int level)
407@@ -805,22 +833,81 @@ static EGL_DISPMANX_WINDOW_T *check_defa
408 void platform_get_dimensions(EGLDisplay dpy, EGLNativeWindowType win,
409 uint32_t *width, uint32_t *height, uint32_t *swapchain_count)
410 {
411- EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
412- vcos_assert(dwin);
413- vcos_assert(dwin->width < 1<<16); // sanity check
414- vcos_assert(dwin->height < 1<<16); // sanity check
415- *width = dwin->width;
416- *height = dwin->height;
417- *swapchain_count = 0;
418+#ifdef BUILD_WAYLAND
419+ if(khrn_platform_get_wl_display()) {
420+ struct wl_egl_window *wl_egl_window = (struct wl_egl_window*)win;
421+ *width = wl_egl_window->width;
422+ *height = wl_egl_window->height;
423+ /* This seems to be used for sync'ing with the VC on buffer creation, but
424+ we are managing them on the CPU side */
425+ *swapchain_count = 1;
426+ } else {
427+#endif
428+ EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
429+ vcos_assert(dwin);
430+ vcos_assert(dwin->width < 1<<16); // sanity check
431+ vcos_assert(dwin->height < 1<<16); // sanity check
432+ *width = dwin->width;
433+ *height = dwin->height;
434+ *swapchain_count = 0;
435+#ifdef BUILD_WAYLAND
436+ }
437+#endif
438+}
439+
440+#ifdef BUILD_WAYLAND
441+static DISPMANX_ELEMENT_HANDLE_T create_dummy_element()
442+{
443+ DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(0);
444+ DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);
445+ DISPMANX_ELEMENT_HANDLE_T element;
446+ VC_DISPMANX_ALPHA_T alpha = {DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0};
447+ VC_RECT_T src_rect;
448+ VC_RECT_T dst_rect;
449+
450+ src_rect.x = 0;
451+ src_rect.y = 0;
452+ src_rect.width = 1 << 16;
453+ src_rect.height = 1 << 16;
454+
455+ dst_rect.x = 0;
456+ dst_rect.y = 0;
457+ dst_rect.width = 1;
458+ dst_rect.height = 1;
459+
460+ element = vc_dispmanx_element_add(update, display, 0/*layer*/, &dst_rect,
461+ 0/*src*/, &src_rect,
462+ DISPMANX_PROTECTION_NONE, &alpha,
463+ 0/*clamp*/, 0/*transform*/);
464+
465+ vc_dispmanx_update_submit_sync(update);
466+
467+ vc_dispmanx_display_close(display);
468+
469+ return element;
470 }
471+#endif
472
473 uint32_t platform_get_handle(EGLDisplay dpy, EGLNativeWindowType win)
474 {
475- EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
476- vcos_assert(dwin);
477- vcos_assert(dwin->width < 1<<16); // sanity check
478- vcos_assert(dwin->height < 1<<16); // sanity check
479- return dwin->element;
480+#ifdef BUILD_WAYLAND
481+ if(khrn_platform_get_wl_display()) {
482+ struct wl_egl_window *wl_egl_window = (struct wl_egl_window*)win;
483+
484+ if (wl_egl_window->dummy_element == PLATFORM_WIN_NONE)
485+ wl_egl_window->dummy_element = create_dummy_element();
486+
487+ return wl_egl_window->dummy_element;
488+ } else {
489+#endif
490+ EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
491+ vcos_assert(dwin);
492+ vcos_assert(dwin->width < 1<<16); // sanity check
493+ vcos_assert(dwin->height < 1<<16); // sanity check
494+ return dwin->element;
495+#ifdef BUILD_WAYLAND
496+ }
497+#endif
498 }
499
500 #endif
501Index: git/interface/khronos/common/linux/khrn_wayland.c
502===================================================================
503--- /dev/null
504+++ git/interface/khronos/common/linux/khrn_wayland.c
505@@ -0,0 +1,215 @@
506+/*
507+Copyright (c) 2013, Raspberry Pi Foundation
508+All rights reserved.
509+
510+Redistribution and use in source and binary forms, with or without
511+modification, are permitted provided that the following conditions are met:
512+ * Redistributions of source code must retain the above copyright
513+ notice, this list of conditions and the following disclaimer.
514+ * Redistributions in binary form must reproduce the above copyright
515+ notice, this list of conditions and the following disclaimer in the
516+ documentation and/or other materials provided with the distribution.
517+ * Neither the name of the copyright holder nor the
518+ names of its contributors may be used to endorse or promote products
519+ derived from this software without specific prior written permission.
520+
521+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
522+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
523+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
524+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
525+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
526+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
527+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
528+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
529+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
530+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
531+*/
532+
533+#define VCOS_LOG_CATEGORY (&khrn_client_log)
534+
535+#include "interface/khronos/common/linux/khrn_wayland.h"
536+#include "interface/khronos/wayland-dispmanx-client-protocol.h"
537+#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
538+
539+extern VCOS_LOG_CAT_T khrn_client_log;
540+
541+static void handle_dispmanx_format(void *data, struct wl_dispmanx *dispmanx,
542+ uint32_t format)
543+{
544+}
545+
546+static void handle_dispmanx_allocated(void *data, struct wl_dispmanx *dispmanx,
547+ struct wl_buffer *wl_buffer,
548+ uint32_t resource_handle)
549+{
550+ struct wl_dispmanx_client_buffer *buffer = wl_buffer_get_user_data(wl_buffer);
551+
552+ buffer->pending_allocation = 0;
553+ buffer->resource = resource_handle;
554+}
555+
556+static const struct wl_dispmanx_listener dispmanx_listener = {
557+ handle_dispmanx_format,
558+ handle_dispmanx_allocated,
559+};
560+
561+static void
562+sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
563+{
564+ int *done = data;
565+
566+ *done = 1;
567+
568+ wl_callback_destroy(callback);
569+}
570+
571+static const struct wl_callback_listener sync_listener = {
572+ sync_callback
573+};
574+
575+static int
576+roundtrip(CLIENT_PROCESS_STATE_T *process)
577+{
578+ struct wl_display *wl_display = khrn_platform_get_wl_display();
579+ struct wl_callback *callback;
580+ int done = 0, ret = 0;
581+
582+ callback = wl_display_sync(wl_display);
583+ wl_callback_add_listener(callback, &sync_listener, &done);
584+ wl_proxy_set_queue((struct wl_proxy *) callback, process->wl_queue);
585+ while (ret != -1 && !done)
586+ ret = wl_display_dispatch_queue(wl_display, process->wl_queue);
587+
588+ if (!done)
589+ wl_callback_destroy(callback);
590+
591+ return ret;
592+}
593+
594+int do_wl_roundtrip()
595+{
596+ CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
597+ return roundtrip(process);
598+}
599+
600+static void
601+registry_handle_global(void *data, struct wl_registry *registry,
602+ uint32_t name, const char *interface, uint32_t version)
603+{
604+ struct wl_display *wl_display = khrn_platform_get_wl_display();
605+ CLIENT_PROCESS_STATE_T *process = (CLIENT_PROCESS_STATE_T *)data;
606+
607+ if (strcmp(interface, "wl_dispmanx") == 0) {
608+ process->wl_dispmanx = wl_registry_bind(registry, name,
609+ &wl_dispmanx_interface, 1);
610+
611+ wl_proxy_set_queue((struct wl_proxy *) process->wl_dispmanx,
612+ process->wl_queue);
613+ wl_dispmanx_add_listener(process->wl_dispmanx, &dispmanx_listener, wl_display);
614+ roundtrip(process);
615+ }
616+}
617+
618+static void
619+registry_handle_global_remove(void *data, struct wl_registry *registry,
620+ uint32_t name)
621+{
622+}
623+
624+static const struct wl_registry_listener registry_listener = {
625+ registry_handle_global,
626+ registry_handle_global_remove
627+};
628+
629+int
630+init_process_wayland(CLIENT_PROCESS_STATE_T *process)
631+{
632+ struct wl_display *wl_display = khrn_platform_get_wl_display();
633+
634+ process->wl_queue = wl_display_create_queue(wl_display);
635+ if (!process->wl_queue) {
636+ vcos_log_error("wl_display_create_queue failed\n");
637+ return false;
638+ }
639+ wl_display_dispatch_pending(wl_display);
640+
641+ process->wl_registry = wl_display_get_registry(wl_display);
642+ if (!process->wl_registry) {
643+ vcos_log_error("wl_display_get_registry failed\n");
644+ return false;
645+ }
646+
647+ wl_proxy_set_queue((struct wl_proxy *) process->wl_registry,
648+ process->wl_queue);
649+
650+ wl_registry_add_listener(process->wl_registry, &registry_listener, process);
651+
652+ if (roundtrip(process) < 0 || process->wl_dispmanx == NULL) {
653+ vcos_log_error("failed to get wl_dispmanx\n");
654+ return false;
655+ }
656+
657+ return true;
658+}
659+
660+#ifndef ALIGN_UP
661+#define ALIGN_UP(x,y) ((x + (y)-1) & ~((y)-1))
662+#endif
663+
664+static void handle_buffer_release(void *data, struct wl_buffer *buffer_wl)
665+{
666+ struct wl_dispmanx_client_buffer *wl_dispmanx_client_buffer = data;
667+ wl_dispmanx_client_buffer->in_use = 0;
668+}
669+
670+static const struct wl_buffer_listener buffer_listener = {
671+ handle_buffer_release
672+};
673+
674+struct wl_dispmanx_client_buffer *
675+allocate_wl_buffer(struct wl_egl_window *window, KHRN_IMAGE_FORMAT_T color)
676+{
677+ CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
678+ struct wl_dispmanx_client_buffer *wl_dispmanx_client_buffer;
679+ struct wl_buffer *wl_buffer;
680+ uint32_t stride = ALIGN_UP(window->width * 4, 16);
681+ uint32_t buffer_height = ALIGN_UP(window->height, 16);
682+ enum wl_dispmanx_format color_format;
683+ int ret = 0;
684+
685+ switch (color) {
686+ case ABGR_8888:
687+ color_format = WL_DISPMANX_FORMAT_ABGR8888;
688+ break;
689+ case XBGR_8888:
690+ color_format = WL_DISPMANX_FORMAT_XBGR8888;
691+ break;
692+ case RGB_565:
693+ color_format = WL_DISPMANX_FORMAT_RGB565;
694+ break;
695+ default:
696+ vcos_log_error("unknown KHRN_IMAGE_FORMAT_T 0x%x\n", color);
697+ return NULL;
698+ }
699+
700+ wl_buffer = wl_dispmanx_create_buffer(process->wl_dispmanx, window->width,
701+ window->height, stride, buffer_height,
702+ color_format);
703+ if (wl_buffer == NULL)
704+ return NULL;
705+
706+ wl_dispmanx_client_buffer = calloc(1, sizeof(struct wl_dispmanx_client_buffer));
707+ wl_dispmanx_client_buffer->wl_buffer = wl_buffer;
708+ wl_dispmanx_client_buffer->in_use = 0;
709+ wl_dispmanx_client_buffer->pending_allocation = 1;
710+ wl_dispmanx_client_buffer->width = window->width;
711+ wl_dispmanx_client_buffer->height = window->height;
712+
713+ wl_proxy_set_queue((struct wl_proxy *) wl_buffer, process->wl_queue);
714+ wl_buffer_add_listener(wl_buffer, &buffer_listener, wl_dispmanx_client_buffer);
715+
716+ while (ret != -1 && wl_dispmanx_client_buffer->pending_allocation)
717+ ret = do_wl_roundtrip();
718+
719+ return wl_dispmanx_client_buffer;
720+}
721Index: git/interface/vmcs_host/vc_vchi_dispmanx.h
722===================================================================
723--- git.orig/interface/vmcs_host/vc_vchi_dispmanx.h
724+++ git/interface/vmcs_host/vc_vchi_dispmanx.h
725@@ -66,4 +66,19 @@ typedef struct {
726 #define ELEMENT_CHANGE_MASK_RESOURCE (1<<4)
727 #define ELEMENT_CHANGE_TRANSFORM (1<<5)
728
729+#ifdef BUILD_WAYLAND
730+/* XXX: This should be in a private header that can be included from EGL and vc_* */
731+#include <wayland-server.h>
732+#include "interface/vmcs_host/wayland-dispmanx-server-protocol.h"
733+struct wl_dispmanx_server_buffer {
734+ struct wl_resource *resource;
735+ struct wl_dispmanx *dispmanx;
736+ enum wl_dispmanx_format format;
737+ DISPMANX_RESOURCE_HANDLE_T handle;
738+ int32_t width;
739+ int32_t height;
740+ int in_use;
741+};
742+#endif
743+
744 #endif
745Index: git/interface/khronos/common/linux/khrn_wayland.h
746===================================================================
747--- /dev/null
748+++ git/interface/khronos/common/linux/khrn_wayland.h
749@@ -0,0 +1,33 @@
750+/*
751+Copyright (c) 2013, Raspberry Pi Foundation
752+All rights reserved.
753+
754+Redistribution and use in source and binary forms, with or without
755+modification, are permitted provided that the following conditions are met:
756+ * Redistributions of source code must retain the above copyright
757+ notice, this list of conditions and the following disclaimer.
758+ * Redistributions in binary form must reproduce the above copyright
759+ notice, this list of conditions and the following disclaimer in the
760+ documentation and/or other materials provided with the distribution.
761+ * Neither the name of the copyright holder nor the
762+ names of its contributors may be used to endorse or promote products
763+ derived from this software without specific prior written permission.
764+
765+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
766+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
767+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
768+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
769+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
770+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
771+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
772+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
773+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
774+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
775+*/
776+
777+#include "interface/khronos/common/khrn_client.h"
778+
779+int init_process_wayland(CLIENT_PROCESS_STATE_T *process);
780+int do_wl_roundtrip();
781+
782+struct wl_dispmanx_client_buffer *allocate_wl_buffer(struct wl_egl_window *window, KHRN_IMAGE_FORMAT_T color);
783Index: git/interface/khronos/egl/egl_client.c
784===================================================================
785--- git.orig/interface/khronos/egl/egl_client.c
786+++ git/interface/khronos/egl/egl_client.c
787@@ -153,6 +153,10 @@ by an attribute value"
788 #include <stdlib.h>
789 #include <string.h>
790
791+#ifdef BUILD_WAYLAND
792+#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
793+#include "interface/khronos/common/linux/khrn_wayland.h"
794+#endif
795
796 #include "interface/khronos/egl/egl_client_cr.c"
797
798@@ -162,17 +166,6 @@ static void egl_current_release(CLIENT_P
799 void egl_gl_flush_callback(bool wait);
800 void egl_vg_flush_callback(bool wait);
801
802-#include "interface/vmcs_host/vc_dispmanx_types.h"
803-/**HACKHACK - give us the ability to inject a DispmanX
804- * resource handle into the CreateWindowSurface and
805- * SwapBuffers calls */
806-static DISPMANX_RESOURCE_HANDLE_T next_resource_handle;
807-
808-EGLAPI EGLBoolean EGLAPIENTRY eglSetNextResourceHandle(DISPMANX_RESOURCE_HANDLE_T handle)
809-{
810- next_resource_handle = handle;
811-}
812-
813 /*
814 TODO: do an RPC call to make sure the Khronos vll is loaded (and that it stays loaded until eglTerminate)
815 Also affects global image (and possibly others?)
816@@ -451,6 +444,9 @@ EGLAPI const char EGLAPIENTRY * eglQuery
817 "EGL_KHR_fence_sync "
818 #endif
819 #endif
820+#if EGL_WL_bind_wayland_display
821+ "EGL_WL_bind_wayland_display "
822+#endif
823 ;
824 break;
825 case EGL_VENDOR:
826@@ -655,8 +651,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateW
827 false,
828 EGL_NO_TEXTURE,
829 EGL_NO_TEXTURE,
830- 0, 0,
831- next_resource_handle);
832+ 0, 0);
833
834 if (surface) {
835 if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
836@@ -901,7 +896,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateP
837 mipmap_texture,
838 texture_format,
839 texture_target,
840- 0, 0, 0);
841+ 0, 0);
842
843 if (surface) {
844 if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
845@@ -1043,7 +1038,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateP
846 false,
847 EGL_NO_TEXTURE,
848 EGL_NO_TEXTURE,
849- pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle, 0);
850+ pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle);
851
852 if (surface) {
853 if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
854@@ -2245,6 +2240,9 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuf
855 CLIENT_THREAD_STATE_T *thread;
856 CLIENT_PROCESS_STATE_T *process;
857 EGLBoolean result;
858+#ifdef BUILD_WAYLAND
859+ struct wl_display *wl_display = khrn_platform_get_wl_display();
860+#endif
861
862 vcos_log_trace("eglSwapBuffers start. dpy=%d. surf=%d.", (int)dpy, (int)surf);
863
864@@ -2315,18 +2313,58 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuf
865
866 vcos_log_trace("eglSwapBuffers server call");
867
868- if (next_resource_handle)
869- RPC_CALL7(eglIntSwapBuffers_impl,
870- thread,
871- EGLINTSWAPBUFFERS_ID_V2,
872- RPC_UINT(surface->serverbuffer),
873- RPC_UINT(surface->width),
874- RPC_UINT(surface->height),
875- RPC_UINT(surface->internal_handle),
876- RPC_UINT(surface->swap_behavior == EGL_BUFFER_PRESERVED ? 1 : 0),
877- RPC_UINT(khrn_platform_get_window_position(surface->win)),
878- RPC_INT(next_resource_handle));
879- else
880+#ifdef BUILD_WAYLAND
881+ if (wl_display) {
882+ struct wl_egl_window *wl_egl_window = surface->wl_egl_window;
883+ struct wl_dispmanx_client_buffer *buffer_temp;
884+ uint32_t configid;
885+ KHRN_IMAGE_FORMAT_T color;
886+ int ret = 0;
887+
888+ buffer_temp = surface->front_wl_buffer;
889+ surface->front_wl_buffer = surface->back_wl_buffer;
890+ surface->back_wl_buffer = buffer_temp;
891+
892+ configid = egl_config_to_id(surface->config);
893+ color = egl_config_get_color_format(configid);
894+
895+ if (surface->back_wl_buffer == NULL)
896+ surface->back_wl_buffer = allocate_wl_buffer(wl_egl_window, color);
897+ else if (surface->back_wl_buffer->width != width ||
898+ surface->back_wl_buffer->height != height) {
899+
900+ struct wl_dispmanx_client_buffer *buffer;
901+
902+ wl_buffer_destroy(surface->back_wl_buffer->wl_buffer);
903+ free(surface->back_wl_buffer);
904+
905+ buffer = allocate_wl_buffer(wl_egl_window, color);
906+ surface->back_wl_buffer = buffer;
907+ }
908+
909+ RPC_CALL7(eglIntSwapBuffers_impl,
910+ thread,
911+ EGLINTSWAPBUFFERS_ID_V2,
912+ RPC_UINT(surface->serverbuffer),
913+ RPC_UINT(surface->width),
914+ RPC_UINT(surface->height),
915+ RPC_UINT(surface->internal_handle),
916+ RPC_UINT(surface->swap_behavior == EGL_BUFFER_PRESERVED ? 1 : 0),
917+ RPC_UINT(khrn_platform_get_window_position(surface->win)),
918+ RPC_INT(surface->back_wl_buffer->resource));
919+
920+ surface->front_wl_buffer->in_use = 1;
921+ wl_surface_attach(wl_egl_window->wl_surface,
922+ surface->front_wl_buffer->wl_buffer,
923+ 0, 0);
924+ wl_surface_damage(wl_egl_window->wl_surface, 0, 0,
925+ surface->width, surface->height);
926+ wl_surface_commit(wl_egl_window->wl_surface);
927+
928+ while(ret != -1 && surface->back_wl_buffer->in_use)
929+ ret = wl_display_dispatch_queue(wl_display, process->wl_queue);
930+ } else
931+#endif
932 RPC_CALL6(eglIntSwapBuffers_impl,
933 thread,
934 EGLINTSWAPBUFFERS_ID,
935Index: git/interface/khronos/egl/egl_client_get_proc.c
936===================================================================
937--- git.orig/interface/khronos/egl/egl_client_get_proc.c
938+++ git/interface/khronos/egl/egl_client_get_proc.c
939@@ -254,6 +254,17 @@ EGLAPI void EGLAPIENTRY (* eglGetProcAdd
940 return (void(*)(void))eglQueryGlobalImageBRCM;
941 #endif
942
943+#ifdef BUILD_WAYLAND
944+#if EGL_WL_bind_wayland_display
945+ if (!strcmp(procname, "eglBindWaylandDisplayWL"))
946+ return (void(*)(void))eglBindWaylandDisplayWL;
947+ if (!strcmp(procname, "eglUnbindWaylandDisplayWL"))
948+ return (void(*)(void))eglUnbindWaylandDisplayWL;
949+ if (!strcmp(procname, "eglQueryWaylandBufferWL"))
950+ return (void(*)(void))eglQueryWaylandBufferWL;
951+#endif
952+#endif
953+
954 return (void(*)(void)) NULL;
955 }
956
957Index: git/interface/khronos/egl/egl_client_surface.c
958===================================================================
959--- git.orig/interface/khronos/egl/egl_client_surface.c
960+++ git/interface/khronos/egl/egl_client_surface.c
961@@ -46,6 +46,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
962 #include "interface/khronos/egl/egl_int_impl.h"
963 #endif
964
965+#ifdef BUILD_WAYLAND
966+#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
967+#include "interface/khronos/common/linux/khrn_wayland.h"
968+#endif
969+
970 #include <stdlib.h>
971
972
973@@ -314,8 +319,7 @@ EGL_SURFACE_T *egl_surface_create(
974 EGLenum texture_format,
975 EGLenum texture_target,
976 EGLNativePixmapType pixmap,
977- const uint32_t *pixmap_server_handle,
978- DISPMANX_RESOURCE_HANDLE_T next_resource_handle)
979+ const uint32_t *pixmap_server_handle)
980 {
981 KHRN_IMAGE_FORMAT_T color;
982 KHRN_IMAGE_FORMAT_T depth;
983@@ -326,6 +330,10 @@ EGL_SURFACE_T *egl_surface_create(
984 EGLint config_depth_bits;
985 EGLint config_stencil_bits;
986 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
987+#ifdef BUILD_WAYLAND
988+ struct wl_display *wl_display = khrn_platform_get_wl_display();
989+ DISPMANX_RESOURCE_HANDLE_T resource;
990+#endif
991
992 EGL_SURFACE_T *surface = egl_surface_pool_alloc();
993
994@@ -390,6 +398,18 @@ EGL_SURFACE_T *egl_surface_create(
995
996 vcos_assert(color != IMAGE_FORMAT_INVALID);
997
998+#ifdef BUILD_WAYLAND
999+ if (type == WINDOW && wl_display) {
1000+ surface->wl_egl_window = (struct wl_egl_window*)win;
1001+ surface->back_wl_buffer = allocate_wl_buffer(
1002+ surface->wl_egl_window, color);
1003+ resource = surface->back_wl_buffer->resource;
1004+ } else {
1005+ surface->wl_egl_window = NULL;
1006+ resource = DISPMANX_NO_HANDLE;
1007+ }
1008+#endif
1009+
1010 #ifdef KHRONOS_EGL_PLATFORM_OPENWFC
1011 // Create stream for this window
1012 if(type != PBUFFER)
1013@@ -474,7 +494,8 @@ EGL_SURFACE_T *egl_surface_create(
1014 #endif
1015 uint32_t results[3];
1016
1017- if (next_resource_handle)
1018+#ifdef BUILD_WAYLAND
1019+ if (resource != DISPMANX_NO_HANDLE)
1020 RPC_CALL16_OUT_CTRL(eglIntCreateSurface_impl,
1021 thread,
1022 EGLINTCREATESURFACE_ID_V2,
1023@@ -492,9 +513,10 @@ EGL_SURFACE_T *egl_surface_create(
1024 RPC_UINT(config_stencil_bits),
1025 RPC_UINT(sem_name),
1026 RPC_UINT(type),
1027- RPC_INT(next_resource_handle),
1028+ RPC_INT(resource),
1029 results);
1030 else
1031+#endif
1032 RPC_CALL15_OUT_CTRL(eglIntCreateSurface_impl,
1033 thread,
1034 EGLINTCREATESURFACE_ID,
1035@@ -663,6 +685,18 @@ void egl_surface_free(EGL_SURFACE_T *sur
1036 if( surface->type == WINDOW ) {
1037 vcos_log_trace("egl_surface_free: calling platform_destroy_winhandle...");
1038 platform_destroy_winhandle( surface->win, surface->internal_handle );
1039+
1040+#ifdef BUILD_WAYLAND
1041+ if (surface->back_wl_buffer) {
1042+ wl_buffer_destroy(surface->back_wl_buffer->wl_buffer);
1043+ free(surface->back_wl_buffer);
1044+ }
1045+
1046+ if (surface->front_wl_buffer) {
1047+ wl_buffer_destroy(surface->front_wl_buffer->wl_buffer);
1048+ free(surface->front_wl_buffer);
1049+ }
1050+#endif
1051 }
1052 /* return value ignored -- read performed to ensure blocking. we want this to
1053 * block so clients can safely destroy the surface's window as soon as the
1054Index: git/interface/khronos/egl/egl_client_surface.h
1055===================================================================
1056--- git.orig/interface/khronos/egl/egl_client_surface.h
1057+++ git/interface/khronos/egl/egl_client_surface.h
1058@@ -288,6 +288,41 @@ typedef struct {
1059 type == PIXMAP
1060 */
1061 bool server_owned;
1062+
1063+#ifdef BUILD_WAYLAND
1064+ /*
1065+ wl_egl_window
1066+
1067+ Validity:
1068+ type == WINDOW
1069+
1070+ Invariant:
1071+ wayland EGL window
1072+ */
1073+ struct wl_egl_window *wl_egl_window;
1074+
1075+ /*
1076+ front_wl_buffer
1077+
1078+ Validity:
1079+ type == WINDOW
1080+
1081+ Invariant:
1082+ client-side information about the wl_buffer in the front
1083+ */
1084+ struct wl_dispmanx_client_buffer *front_wl_buffer;
1085+
1086+ /*
1087+ back_wl_buffer
1088+
1089+ Validity:
1090+ type == WINDOW
1091+
1092+ Invariant:
1093+ client-side information about the wl_buffer in the back
1094+ */
1095+ struct wl_dispmanx_client_buffer *back_wl_buffer;
1096+#endif
1097 } EGL_SURFACE_T;
1098
1099 extern bool egl_surface_check_attribs(
1100@@ -322,8 +357,7 @@ extern EGL_SURFACE_T *egl_surface_create
1101 EGLenum texture_format,
1102 EGLenum texture_target,
1103 EGLNativePixmapType pixmap,
1104- const uint32_t *pixmap_server_handle,
1105- DISPMANX_RESOURCE_HANDLE_T next_resource_handle);
1106+ const uint32_t *pixmap_server_handle);
1107 extern EGL_SURFACE_T *egl_surface_from_vg_image(
1108 VGImage vg_handle,
1109 EGLSurface name,
1110Index: git/interface/khronos/egl/egl_int_impl.h
1111===================================================================
1112--- git.orig/interface/khronos/egl/egl_int_impl.h
1113+++ git/interface/khronos/egl/egl_int_impl.h
1114@@ -57,7 +57,7 @@ FN(int, eglIntCreateSurface_impl, (
1115 uint32_t sem,
1116 uint32_t type,
1117 uint32_t *results,
1118- DISPMANX_RESOURCE_HANDLE_T next_resource_handle))
1119+ DISPMANX_RESOURCE_HANDLE_T resource_handle))
1120
1121 FN(int, eglIntCreatePbufferFromVGImage_impl, (
1122 VGImage vg_handle,
1123Index: git/interface/khronos/ext/egl_wayland.c
1124===================================================================
1125--- /dev/null
1126+++ git/interface/khronos/ext/egl_wayland.c
1127@@ -0,0 +1,246 @@
1128+/*
1129+Copyright (c) 2013, Raspberry Pi Foundation
1130+All rights reserved.
1131+
1132+Redistribution and use in source and binary forms, with or without
1133+modification, are permitted provided that the following conditions are met:
1134+ * Redistributions of source code must retain the above copyright
1135+ notice, this list of conditions and the following disclaimer.
1136+ * Redistributions in binary form must reproduce the above copyright
1137+ notice, this list of conditions and the following disclaimer in the
1138+ documentation and/or other materials provided with the distribution.
1139+ * Neither the name of the copyright holder nor the
1140+ names of its contributors may be used to endorse or promote products
1141+ derived from this software without specific prior written permission.
1142+
1143+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1144+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1145+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1146+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
1147+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1148+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1149+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1150+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1151+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1152+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1153+*/
1154+
1155+#include "interface/khronos/common/khrn_client_mangle.h"
1156+#include "interface/khronos/common/khrn_client_rpc.h"
1157+
1158+#include "interface/khronos/ext/egl_khr_sync_client.h"
1159+#include "interface/khronos/include/EGL/egl.h"
1160+#include "interface/khronos/include/EGL/eglext.h"
1161+
1162+#include "interface/vmcs_host/vc_vchi_dispmanx.h"
1163+
1164+#include <wayland-server.h>
1165+#include "interface/khronos/wayland-dispmanx-server-protocol.h"
1166+
1167+static void
1168+destroy_buffer(struct wl_resource *resource)
1169+{
1170+ struct wl_dispmanx_server_buffer *buffer = wl_resource_get_user_data(resource);
1171+
1172+ if(!buffer->in_use)
1173+ vc_dispmanx_resource_delete(buffer->handle);
1174+
1175+ free(buffer);
1176+}
1177+
1178+static void
1179+buffer_destroy(struct wl_client *client, struct wl_resource *resource)
1180+{
1181+ wl_resource_destroy(resource);
1182+}
1183+
1184+static const struct wl_buffer_interface dispmanx_buffer_interface = {
1185+ buffer_destroy
1186+};
1187+
1188+static VC_IMAGE_TYPE_T
1189+get_vc_format(enum wl_dispmanx_format format)
1190+{
1191+ /* XXX: The app is likely to have been premultiplying in its shaders,
1192+ * but the VC scanout hardware on the RPi cannot mix premultiplied alpha
1193+ * channel with the element's alpha.
1194+ */
1195+ switch (format) {
1196+ case WL_DISPMANX_FORMAT_ABGR8888:
1197+ return VC_IMAGE_RGBA32;
1198+ case WL_DISPMANX_FORMAT_XBGR8888:
1199+ return VC_IMAGE_BGRX8888;
1200+ case WL_DISPMANX_FORMAT_RGB565:
1201+ return VC_IMAGE_RGB565;
1202+ default:
1203+ /* invalid format */
1204+ return VC_IMAGE_MIN;
1205+ }
1206+}
1207+
1208+static void
1209+dispmanx_create_buffer(struct wl_client *client, struct wl_resource *resource,
1210+ uint32_t id, int32_t width, int32_t height,
1211+ uint32_t stride, uint32_t buffer_height, uint32_t format)
1212+{
1213+ struct wl_dispmanx_server_buffer *buffer;
1214+ VC_IMAGE_TYPE_T vc_format = get_vc_format(format);
1215+ uint32_t dummy;
1216+
1217+ if(vc_format == VC_IMAGE_MIN) {
1218+ wl_resource_post_error(resource,
1219+ WL_DISPMANX_ERROR_INVALID_FORMAT,
1220+ "invalid format");
1221+ return;
1222+ }
1223+
1224+ buffer = calloc(1, sizeof *buffer);
1225+ if (buffer == NULL) {
1226+ wl_resource_post_no_memory(resource);
1227+ return;
1228+ }
1229+
1230+ buffer->handle = vc_dispmanx_resource_create(vc_format,
1231+ width | (stride << 16),
1232+ height | (buffer_height << 16),
1233+ &dummy);
1234+ if(buffer->handle == DISPMANX_NO_HANDLE) {
1235+ wl_resource_post_error(resource,
1236+ WL_DISPMANX_ERROR_ALLOC_FAILED,
1237+ "allocation failed");
1238+ free(buffer);
1239+ return;
1240+ }
1241+
1242+ buffer->width = width;
1243+ buffer->height = height;
1244+ buffer->format = format;
1245+
1246+ buffer->resource = wl_resource_create(resource->client, &wl_buffer_interface,
1247+ 1, id);
1248+ if (!buffer->resource) {
1249+ wl_resource_post_no_memory(resource);
1250+ vc_dispmanx_resource_delete(buffer->handle);
1251+ free(buffer);
1252+ return;
1253+ }
1254+
1255+ wl_resource_set_implementation(buffer->resource,
1256+ (void (**)(void)) &dispmanx_buffer_interface,
1257+ buffer, destroy_buffer);
1258+
1259+ wl_dispmanx_send_buffer_allocated(resource, buffer->resource,
1260+ buffer->handle);
1261+}
1262+
1263+static const struct wl_dispmanx_interface dispmanx_interface = {
1264+ dispmanx_create_buffer,
1265+};
1266+
1267+static void
1268+bind_dispmanx(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1269+{
1270+ struct wl_resource *resource;
1271+
1272+ resource = wl_resource_create(client, &wl_dispmanx_interface, 1, id);
1273+ wl_resource_set_implementation(resource, &dispmanx_interface, NULL, NULL);
1274+
1275+ wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
1276+ WL_DISPMANX_FORMAT_ARGB8888);
1277+
1278+ wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
1279+ WL_DISPMANX_FORMAT_XRGB8888);
1280+
1281+ wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
1282+ WL_DISPMANX_FORMAT_ABGR8888);
1283+
1284+ wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
1285+ WL_DISPMANX_FORMAT_XBGR8888);
1286+
1287+ wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
1288+ WL_DISPMANX_FORMAT_RGB565);
1289+}
1290+
1291+EGLBoolean EGLAPIENTRY
1292+eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1293+{
1294+ CLIENT_THREAD_STATE_T *thread;
1295+ CLIENT_PROCESS_STATE_T *process;
1296+
1297+ if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
1298+ return EGL_FALSE;
1299+
1300+ if (process->wl_global != NULL)
1301+ goto error;
1302+
1303+ process->wl_global = wl_global_create(display, &wl_dispmanx_interface, 1,
1304+ NULL, bind_dispmanx);
1305+ if (process->wl_global == NULL)
1306+ goto error;
1307+
1308+ return EGL_TRUE;
1309+
1310+error:
1311+ CLIENT_UNLOCK();
1312+ return EGL_FALSE;
1313+}
1314+
1315+EGLBoolean EGLAPIENTRY
1316+eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1317+{
1318+ CLIENT_THREAD_STATE_T *thread;
1319+ CLIENT_PROCESS_STATE_T *process;
1320+
1321+ if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
1322+ return EGL_FALSE;
1323+
1324+ wl_global_destroy(process->wl_global);
1325+ process->wl_global = NULL;
1326+
1327+ CLIENT_UNLOCK();
1328+
1329+ return EGL_TRUE;
1330+}
1331+
1332+static int
1333+get_egl_format(enum wl_dispmanx_format format)
1334+{
1335+ switch (format) {
1336+ case WL_DISPMANX_FORMAT_ABGR8888:
1337+ return EGL_TEXTURE_RGBA;
1338+ case WL_DISPMANX_FORMAT_XBGR8888:
1339+ return EGL_TEXTURE_RGB;
1340+ case WL_DISPMANX_FORMAT_RGB565:
1341+ return EGL_TEXTURE_RGB;
1342+ default:
1343+ /* invalid format */
1344+ return EGL_NO_TEXTURE;
1345+ }
1346+}
1347+
1348+EGLBoolean EGLAPIENTRY
1349+eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *_buffer,
1350+ EGLint attribute, EGLint *value)
1351+{
1352+ struct wl_dispmanx_server_buffer *buffer = wl_resource_get_user_data(_buffer);
1353+
1354+ if (wl_resource_instance_of(_buffer, &wl_dispmanx_interface,
1355+ &dispmanx_buffer_interface))
1356+ return EGL_FALSE;
1357+
1358+ switch (attribute) {
1359+ case EGL_TEXTURE_FORMAT:
1360+ *value = get_egl_format(buffer->format);
1361+ if (*value == EGL_NO_TEXTURE)
1362+ return EGL_FALSE;
1363+ return EGL_TRUE;
1364+ case EGL_WIDTH:
1365+ *value = buffer->width;
1366+ return EGL_TRUE;
1367+ case EGL_HEIGHT:
1368+ *value = buffer->height;
1369+ return EGL_TRUE;
1370+ }
1371+
1372+ return EGL_FALSE;
1373+}
1374Index: git/interface/khronos/include/EGL/eglext.h
1375===================================================================
1376--- git.orig/interface/khronos/include/EGL/eglext.h
1377+++ git/interface/khronos/include/EGL/eglext.h
1378@@ -191,6 +191,29 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLG
1379 #endif
1380
1381
1382+#ifndef EGL_WL_bind_wayland_display
1383+#define EGL_WL_bind_wayland_display 1
1384+
1385+#define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */
1386+#define EGL_WAYLAND_PLANE_WL 0x31D6 /* eglCreateImageKHR target */
1387+#define EGL_TEXTURE_Y_U_V_WL 0x31D7
1388+#define EGL_TEXTURE_Y_UV_WL 0x31D8
1389+#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
1390+
1391+struct wl_display;
1392+struct wl_resource;
1393+#ifdef EGL_EGLEXT_PROTOTYPES
1394+EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
1395+EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
1396+EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
1397+#endif
1398+typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
1399+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
1400+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
1401+
1402+#endif
1403+
1404+
1405 #ifdef __cplusplus
1406 }
1407 #endif
1408Index: git/interface/khronos/wayland-egl/wayland-egl-priv.h
1409===================================================================
1410--- /dev/null
1411+++ git/interface/khronos/wayland-egl/wayland-egl-priv.h
1412@@ -0,0 +1,53 @@
1413+/* Copied from Mesa */
1414+
1415+#ifndef _WAYLAND_EGL_PRIV_H
1416+#define _WAYLAND_EGL_PRIV_H
1417+
1418+#ifdef __cplusplus
1419+extern "C" {
1420+#endif
1421+
1422+/* GCC visibility */
1423+#if defined(__GNUC__) && __GNUC__ >= 4
1424+#define WL_EGL_EXPORT __attribute__ ((visibility("default")))
1425+#else
1426+#define WL_EGL_EXPORT
1427+#endif
1428+
1429+#include "interface/vmcs_host/vc_dispmanx.h"
1430+#include "interface/khronos/egl/egl_client_surface.h"
1431+
1432+#include <wayland-client.h>
1433+
1434+struct wl_dispmanx_client_buffer {
1435+ struct wl_buffer *wl_buffer;
1436+ DISPMANX_RESOURCE_HANDLE_T resource;
1437+
1438+ int pending_allocation;
1439+ int in_use;
1440+ int width;
1441+ int height;
1442+};
1443+
1444+struct wl_egl_window {
1445+ struct wl_surface *wl_surface;
1446+
1447+ int width;
1448+ int height;
1449+ int dx;
1450+ int dy;
1451+
1452+ int attached_width;
1453+ int attached_height;
1454+
1455+ /* XXX: The VC side seems to expect a valid element handle to be
1456+ passed to eglIntCreateSurface_impl and/or eglIntSwapBuffers_impl,
1457+ even for host-managed surfaces. */
1458+ DISPMANX_ELEMENT_HANDLE_T dummy_element;
1459+};
1460+
1461+#ifdef __cplusplus
1462+}
1463+#endif
1464+
1465+#endif
1466Index: git/interface/khronos/wayland-egl/wayland-egl.c
1467===================================================================
1468--- /dev/null
1469+++ git/interface/khronos/wayland-egl/wayland-egl.c
1470@@ -0,0 +1,59 @@
1471+/* Copied from Mesa */
1472+
1473+#include <stdlib.h>
1474+
1475+#include <wayland-client.h>
1476+#include <wayland-egl.h>
1477+#include "wayland-egl-priv.h"
1478+
1479+WL_EGL_EXPORT void
1480+wl_egl_window_resize(struct wl_egl_window *egl_window,
1481+ int width, int height,
1482+ int dx, int dy)
1483+{
1484+ if (egl_window->width == width &&
1485+ egl_window->height == height &&
1486+ egl_window->dx == dx &&
1487+ egl_window->dy == dy)
1488+ return;
1489+
1490+ egl_window->width = width;
1491+ egl_window->height = height;
1492+ egl_window->dx = dx;
1493+ egl_window->dy = dy;
1494+}
1495+
1496+WL_EGL_EXPORT struct wl_egl_window *
1497+wl_egl_window_create(struct wl_surface *surface,
1498+ int width, int height)
1499+{
1500+ struct wl_egl_window *egl_window;
1501+
1502+ egl_window = calloc(1, sizeof *egl_window);
1503+ if (!egl_window)
1504+ return NULL;
1505+
1506+ egl_window->wl_surface = surface;
1507+ wl_egl_window_resize(egl_window, width, height, 0, 0);
1508+ egl_window->attached_width = 0;
1509+ egl_window->attached_height = 0;
1510+ egl_window->dummy_element = PLATFORM_WIN_NONE;
1511+
1512+ return egl_window;
1513+}
1514+
1515+WL_EGL_EXPORT void
1516+wl_egl_window_destroy(struct wl_egl_window *egl_window)
1517+{
1518+ free(egl_window);
1519+}
1520+
1521+WL_EGL_EXPORT void
1522+wl_egl_window_get_attached_size(struct wl_egl_window *egl_window,
1523+ int *width, int *height)
1524+{
1525+ if (width)
1526+ *width = egl_window->attached_width;
1527+ if (height)
1528+ *height = egl_window->attached_height;
1529+}
1530Index: git/interface/khronos/wayland-egl/wayland-egl.pc.in
1531===================================================================
1532--- /dev/null
1533+++ git/interface/khronos/wayland-egl/wayland-egl.pc.in
1534@@ -0,0 +1,10 @@
1535+prefix=@CMAKE_INSTALL_PREFIX@
1536+exec_prefix=${prefix}
1537+libdir=${exec_prefix}/lib
1538+includedir=${prefix}/include
1539+
1540+Name: wayland-egl
1541+Description: VideoCore wayland-egl library
1542+Version: @PROJECT_APIVER@
1543+Libs: -L${libdir} -lwayland-egl
1544+Cflags: -I${includedir}
1545Index: git/interface/vmcs_host/CMakeLists.txt
1546===================================================================
1547--- git.orig/interface/vmcs_host/CMakeLists.txt
1548+++ git/interface/vmcs_host/CMakeLists.txt
1549@@ -9,13 +9,24 @@ add_definitions(-fno-strict-aliasing)
1550
1551 include_directories(${VMCS_TARGET}/vcfiled)
1552
1553-add_library(vchostif
1554- ${VMCS_TARGET}/vcfilesys.c ${VMCS_TARGET}/vcmisc.c
1555- vc_vchi_gencmd.c vc_vchi_filesys.c vc_vchi_gpuserv.c
1556- vc_vchi_tvservice.c vc_vchi_cecservice.c
1557- vc_vchi_dispmanx.c vc_service_common.c)
1558+set(VCHOSTIF_SOURCE
1559+ ${VMCS_TARGET}/vcfilesys.c ${VMCS_TARGET}/vcmisc.c
1560+ vc_vchi_gencmd.c vc_vchi_filesys.c vc_vchi_gpuserv.c
1561+ vc_vchi_tvservice.c vc_vchi_cecservice.c
1562+ vc_vchi_dispmanx.c vc_service_common.c)
1563 # ${VMCS_TARGET}/vmcs_main.c
1564 # vc_vchi_haud.c
1565+
1566+if (BUILD_WAYLAND)
1567+wayland_add_protocol_server(
1568+ VCHOSTIF_SOURCE
1569+ ../../interface/wayland/dispmanx.xml
1570+ dispmanx
1571+)
1572+endif ()
1573+
1574+add_library(vchostif ${VCHOSTIF_SOURCE})
1575+
1576 #add_library(bufman vc_vchi_bufman.c )
1577
1578 # OpenMAX/IL component service
1579Index: git/interface/vmcs_host/vc_dispmanx.h
1580===================================================================
1581--- git.orig/interface/vmcs_host/vc_dispmanx.h
1582+++ git/interface/vmcs_host/vc_dispmanx.h
1583@@ -39,6 +39,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
1584 #ifdef __cplusplus
1585 extern "C" {
1586 #endif
1587+
1588+#ifdef BUILD_WAYLAND
1589+struct wl_resource;
1590+#endif
1591+
1592 // Same function as above, to aid migration of code.
1593 VCHPRE_ int VCHPOST_ vc_dispman_init( void );
1594 // Stop the service from being used
1595@@ -135,6 +140,11 @@ VCHPRE_ int VCHPOST_ vc_dispmanx_resourc
1596 // Start triggering callbacks synced to vsync
1597 VCHPRE_ int VCHPOST_ vc_dispmanx_vsync_callback( DISPMANX_DISPLAY_HANDLE_T display, DISPMANX_CALLBACK_FUNC_T cb_func, void *cb_arg );
1598
1599+#ifdef BUILD_WAYLAND
1600+VCHPRE_ DISPMANX_RESOURCE_HANDLE_T VCHPOST_ vc_dispmanx_get_handle_from_wl_buffer( struct wl_resource *_buffer );
1601+
1602+VCHPRE_ void VCHPOST_ vc_dispmanx_set_wl_buffer_in_use( struct wl_resource *_buffer, int in_use );
1603+#endif
1604 #ifdef __cplusplus
1605 }
1606 #endif
1607Index: git/interface/vmcs_host/vc_vchi_dispmanx.c
1608===================================================================
1609--- git.orig/interface/vmcs_host/vc_vchi_dispmanx.c
1610+++ git/interface/vmcs_host/vc_vchi_dispmanx.c
1611@@ -1319,3 +1319,45 @@ static void *dispmanx_notify_func( void
1612 }
1613 return 0;
1614 }
1615+
1616+
1617+#ifdef BUILD_WAYLAND
1618+/***********************************************************
1619+ * Name: vc_dispmanx_get_handle_from_wl_buffer
1620+ *
1621+ * Arguments:
1622+ * struct wl_resource *_buffer
1623+ *
1624+ * Description: Return the handle of the resource associated to this Wayland buffer
1625+ *
1626+ * Returns: A resource handle
1627+ *
1628+ ***********************************************************/
1629+VCHPRE_ DISPMANX_RESOURCE_HANDLE_T VCHPOST_ vc_dispmanx_get_handle_from_wl_buffer( struct wl_resource *_buffer )
1630+{
1631+ struct wl_dispmanx_server_buffer *buffer = (struct wl_dispmanx_server_buffer*)_buffer->data;
1632+ if (!buffer)
1633+ return DISPMANX_NO_HANDLE;
1634+
1635+ return buffer->handle;
1636+}
1637+
1638+/***********************************************************
1639+ * Name: vc_dispmanx_set_wl_buffer_in_use
1640+ *
1641+ * Arguments:
1642+ * struct wl_resource *_buffer
1643+ * int in_use
1644+ *
1645+ * Description: Mark this Wayland buffer as being in use by the compositor
1646+ *
1647+ ***********************************************************/
1648+VCHPRE_ void VCHPOST_ vc_dispmanx_set_wl_buffer_in_use( struct wl_resource *_buffer, int in_use )
1649+{
1650+ struct wl_dispmanx_server_buffer *buffer = (struct wl_dispmanx_server_buffer*)_buffer->data;
1651+ if (!buffer)
1652+ return;
1653+
1654+ buffer->in_use = in_use;
1655+}
1656+#endif
1657Index: git/interface/wayland/dispmanx.xml
1658===================================================================
1659--- /dev/null
1660+++ git/interface/wayland/dispmanx.xml
1661@@ -0,0 +1,123 @@
1662+<?xml version="1.0" encoding="UTF-8"?>
1663+<protocol name="dispmanx">
1664+
1665+ <copyright>
1666+ Copyright © 2008-2011 Kristian Høgsberg
1667+ Copyright © 2010-2011 Intel Corporation
1668+ Copyright © 2013 Raspberry Pi Foundation
1669+
1670+ Permission to use, copy, modify, distribute, and sell this
1671+ software and its documentation for any purpose is hereby granted
1672+ without fee, provided that\n the above copyright notice appear in
1673+ all copies and that both that copyright notice and this permission
1674+ notice appear in supporting documentation, and that the name of
1675+ the copyright holders not be used in advertising or publicity
1676+ pertaining to distribution of the software without specific,
1677+ written prior permission. The copyright holders make no
1678+ representations about the suitability of this software for any
1679+ purpose. It is provided "as is" without express or implied
1680+ warranty.
1681+
1682+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
1683+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
1684+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
1685+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1686+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
1687+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1688+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
1689+ THIS SOFTWARE.
1690+ </copyright>
1691+
1692+ <!-- DispManX support. This object is created by the server and published
1693+ using the display's global event. -->
1694+ <interface name="wl_dispmanx" version="1">
1695+ <enum name="error">
1696+ <entry name="alloc_failed" value="0"/>
1697+ <entry name="invalid_format" value="1"/>
1698+ </enum>
1699+
1700+ <enum name="format">
1701+ <!-- The pixel format codes match the #defines in drm_fourcc.h.
1702+ The formats actually supported by the compositor will be
1703+ reported by the format event. -->
1704+ <entry name="c8" value="0x20203843"/>
1705+ <entry name="rgb332" value="0x38424752"/>
1706+ <entry name="bgr233" value="0x38524742"/>
1707+ <entry name="xrgb4444" value="0x32315258"/>
1708+ <entry name="xbgr4444" value="0x32314258"/>
1709+ <entry name="rgbx4444" value="0x32315852"/>
1710+ <entry name="bgrx4444" value="0x32315842"/>
1711+ <entry name="argb4444" value="0x32315241"/>
1712+ <entry name="abgr4444" value="0x32314241"/>
1713+ <entry name="rgba4444" value="0x32314152"/>
1714+ <entry name="bgra4444" value="0x32314142"/>
1715+ <entry name="xrgb1555" value="0x35315258"/>
1716+ <entry name="xbgr1555" value="0x35314258"/>
1717+ <entry name="rgbx5551" value="0x35315852"/>
1718+ <entry name="bgrx5551" value="0x35315842"/>
1719+ <entry name="argb1555" value="0x35315241"/>
1720+ <entry name="abgr1555" value="0x35314241"/>
1721+ <entry name="rgba5551" value="0x35314152"/>
1722+ <entry name="bgra5551" value="0x35314142"/>
1723+ <entry name="rgb565" value="0x36314752"/>
1724+ <entry name="bgr565" value="0x36314742"/>
1725+ <entry name="rgb888" value="0x34324752"/>
1726+ <entry name="bgr888" value="0x34324742"/>
1727+ <entry name="xrgb8888" value="0x34325258"/>
1728+ <entry name="xbgr8888" value="0x34324258"/>
1729+ <entry name="rgbx8888" value="0x34325852"/>
1730+ <entry name="bgrx8888" value="0x34325842"/>
1731+ <entry name="argb8888" value="0x34325241"/>
1732+ <entry name="abgr8888" value="0x34324241"/>
1733+ <entry name="rgba8888" value="0x34324152"/>
1734+ <entry name="bgra8888" value="0x34324142"/>
1735+ <entry name="xrgb2101010" value="0x30335258"/>
1736+ <entry name="xbgr2101010" value="0x30334258"/>
1737+ <entry name="rgbx1010102" value="0x30335852"/>
1738+ <entry name="bgrx1010102" value="0x30335842"/>
1739+ <entry name="argb2101010" value="0x30335241"/>
1740+ <entry name="abgr2101010" value="0x30334241"/>
1741+ <entry name="rgba1010102" value="0x30334152"/>
1742+ <entry name="bgra1010102" value="0x30334142"/>
1743+ <entry name="yuyv" value="0x56595559"/>
1744+ <entry name="yvyu" value="0x55595659"/>
1745+ <entry name="uyvy" value="0x59565955"/>
1746+ <entry name="vyuy" value="0x59555956"/>
1747+ <entry name="ayuv" value="0x56555941"/>
1748+ <entry name="nv12" value="0x3231564e"/>
1749+ <entry name="nv21" value="0x3132564e"/>
1750+ <entry name="nv16" value="0x3631564e"/>
1751+ <entry name="nv61" value="0x3136564e"/>
1752+ <entry name="yuv410" value="0x39565559"/>
1753+ <entry name="yvu410" value="0x39555659"/>
1754+ <entry name="yuv411" value="0x31315559"/>
1755+ <entry name="yvu411" value="0x31315659"/>
1756+ <entry name="yuv420" value="0x32315559"/>
1757+ <entry name="yvu420" value="0x32315659"/>
1758+ <entry name="yuv422" value="0x36315559"/>
1759+ <entry name="yvu422" value="0x36315659"/>
1760+ <entry name="yuv444" value="0x34325559"/>
1761+ <entry name="yvu444" value="0x34325659"/>
1762+ </enum>
1763+
1764+ <event name="format">
1765+ <arg name="format" type="uint"/>
1766+ </event>
1767+
1768+ <!-- Create a wayland buffer for the DispManX resource. -->
1769+ <request name="create_buffer">
1770+ <arg name="id" type="new_id" interface="wl_buffer"/>
1771+ <arg name="width" type="int"/>
1772+ <arg name="height" type="int"/>
1773+ <arg name="stride" type="uint"/>
1774+ <arg name="buffer_height" type="uint"/>
1775+ <arg name="format" type="uint"/>
1776+ </request>
1777+
1778+ <event name="buffer_allocated">
1779+ <arg name="buffer" type="object" interface="wl_buffer"/>
1780+ <arg name="handle" type="uint"/>
1781+ </event>
1782+ </interface>
1783+
1784+</protocol>
1785Index: git/makefiles/cmake/Wayland.cmake
1786===================================================================
1787--- /dev/null
1788+++ git/makefiles/cmake/Wayland.cmake
1789@@ -0,0 +1,72 @@
1790+#=============================================================================
1791+# Copyright (C) 2012-2013 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
1792+# All rights reserved.
1793+#
1794+# Redistribution and use in source and binary forms, with or without
1795+# modification, are permitted provided that the following conditions
1796+# are met:
1797+#
1798+# * Redistributions of source code must retain the above copyright
1799+# notice, this list of conditions and the following disclaimer.
1800+#
1801+# * Redistributions in binary form must reproduce the above copyright
1802+# notice, this list of conditions and the following disclaimer in the
1803+# documentation and/or other materials provided with the distribution.
1804+#
1805+# * Neither the name of Pier Luigi Fiorini nor the names of his
1806+# contributors may be used to endorse or promote products derived
1807+# from this software without specific prior written permission.
1808+#
1809+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1810+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1812+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1813+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1814+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1815+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1816+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1817+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1818+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1819+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1820+#=============================================================================
1821+
1822+find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
1823+
1824+# wayland_add_protocol_client(outfiles inputfile basename)
1825+function(WAYLAND_ADD_PROTOCOL_CLIENT _sources _protocol _basename)
1826+ if(NOT WAYLAND_SCANNER_EXECUTABLE)
1827+ message(FATAL "The wayland-scanner executable has nto been found on your system. You must install it.")
1828+ endif()
1829+
1830+ get_filename_component(_infile ${_protocol} ABSOLUTE)
1831+ set(_client_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-client-protocol.h")
1832+ set(_code "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-protocol.c")
1833+
1834+ add_custom_command(OUTPUT "${_client_header}"
1835+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} client-header < ${_infile} > ${_client_header}
1836+ DEPENDS ${_infile} VERBATIM)
1837+
1838+ add_custom_command(OUTPUT "${_code}"
1839+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} code < ${_infile} > ${_code}
1840+ DEPENDS ${_infile} VERBATIM)
1841+
1842+ list(APPEND ${_sources} "${_client_header}" "${_code}")
1843+ set(${_sources} ${${_sources}} PARENT_SCOPE)
1844+endfunction()
1845+
1846+# wayland_add_protocol_server(outfiles inputfile basename)
1847+function(WAYLAND_ADD_PROTOCOL_SERVER _sources _protocol _basename)
1848+ if(NOT WAYLAND_SCANNER_EXECUTABLE)
1849+ message(FATAL "The wayland-scanner executable has nto been found on your system. You must install it.")
1850+ endif()
1851+
1852+ get_filename_component(_infile ${_protocol} ABSOLUTE)
1853+ set(_server_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-server-protocol.h")
1854+
1855+ add_custom_command(OUTPUT "${_server_header}"
1856+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} server-header < ${_infile} > ${_server_header}
1857+ DEPENDS ${_infile} VERBATIM)
1858+
1859+ list(APPEND ${_sources} "${_server_header}")
1860+ set(${_sources} ${${_sources}} PARENT_SCOPE)
1861+endfunction()
diff --git a/recipes-graphics/userland/files/0003-wayland-Add-Wayland-example.patch b/recipes-graphics/userland/files/0003-wayland-Add-Wayland-example.patch
new file mode 100644
index 0000000..e3a0cf2
--- /dev/null
+++ b/recipes-graphics/userland/files/0003-wayland-Add-Wayland-example.patch
@@ -0,0 +1,866 @@
1From 20ac7c6af4e826b5c536b6a7c8b2d1d266ced81e Mon Sep 17 00:00:00 2001
2From: Tomeu Vizoso <tomeu.vizoso@collabora.com>
3Date: Tue, 1 Oct 2013 13:19:20 +0200
4Subject: [PATCH 03/16] wayland: Add Wayland example
5
6---
7 .../linux/apps/hello_pi/CMakeLists.txt | 1 +
8 .../apps/hello_pi/hello_wayland/CMakeLists.txt | 8 +
9 .../apps/hello_pi/hello_wayland/Djenne_128_128.raw | 3 +
10 .../linux/apps/hello_pi/hello_wayland/Makefile | 5 +
11 .../hello_wayland/cube_texture_and_coords.h | 100 ++++
12 .../linux/apps/hello_pi/hello_wayland/triangle.c | 666 +++++++++++++++++++++
13 host_applications/linux/apps/hello_pi/rebuild.sh | 3 +-
14 7 files changed, 785 insertions(+), 1 deletion(-)
15 create mode 100644 host_applications/linux/apps/hello_pi/hello_wayland/CMakeLists.txt
16 create mode 100644 host_applications/linux/apps/hello_pi/hello_wayland/Djenne_128_128.raw
17 create mode 100644 host_applications/linux/apps/hello_pi/hello_wayland/Makefile
18 create mode 100644 host_applications/linux/apps/hello_pi/hello_wayland/cube_texture_and_coords.h
19 create mode 100644 host_applications/linux/apps/hello_pi/hello_wayland/triangle.c
20
21diff --git a/host_applications/linux/apps/hello_pi/CMakeLists.txt b/host_applications/linux/apps/hello_pi/CMakeLists.txt
22index f2c6aef..0df78f7 100644
23--- a/host_applications/linux/apps/hello_pi/CMakeLists.txt
24+++ b/host_applications/linux/apps/hello_pi/CMakeLists.txt
25@@ -21,6 +21,7 @@ add_subdirectory(hello_encode)
26 add_subdirectory(hello_jpeg)
27 add_subdirectory(hello_videocube)
28 add_subdirectory(hello_teapot)
29+add_subdirectory(hello_wayland)
30
31 if(BUILD_FONT)
32 set(VGFONT_SRCS libs/vgfont/font.c libs/vgfont/vgft.c libs/vgfont/graphics.c)
33diff --git a/host_applications/linux/apps/hello_pi/hello_wayland/CMakeLists.txt b/host_applications/linux/apps/hello_pi/hello_wayland/CMakeLists.txt
34new file mode 100644
35index 0000000..9a2f75c
36--- /dev/null
37+++ b/host_applications/linux/apps/hello_pi/hello_wayland/CMakeLists.txt
38@@ -0,0 +1,8 @@
39+set(EXEC hello_wayland.bin)
40+set(SRCS triangle.c)
41+
42+add_executable(${EXEC} ${SRCS})
43+target_link_libraries(${EXEC} ${HELLO_PI_LIBS} -lwayland-client -lwayland-egl)
44+
45+install(TARGETS ${EXEC}
46+ RUNTIME DESTINATION bin)
47diff --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
48new file mode 100644
49index 0000000..de9173c
50--- /dev/null
51+++ b/host_applications/linux/apps/hello_pi/hello_wayland/Djenne_128_128.raw
52@@ -0,0 +1,3 @@
53+öÖ¿÷×À÷×ÀøØÁúÚÃúÚÃúÚÃúÚÃùÙÂùÙÂùÙÂùÙÂùÙÂùÙÂùÙÂùÙÂûÙÂûÙÂûÙÂûÙÂúØÁúØÁúØÁúØÁøÖ¿ù×Àù×ÀúØÁúØÁúØÁúØÁúØÁù×Àù×Àù×Àù×À÷Õ¾øÖ¿ù×Àù×À÷Õ¾÷Õ¾÷Õ¾÷Õ¾÷Õ¾÷Õ¾÷Õ¾÷Õ¾÷Õ¾÷Õ¾öÔ½öÔ½÷Õ¾÷Õ¾÷Õ¾÷Õ¾õÓ¼öÔ½öÔ½õÓ¼ôÒ»ôÒ»ôÒ»ôÒ»õкõкõкõкõкõкõкõкôиõѹôиôиòζóÏ·óÏ·õѹñ͵óÏ·óÏ·ñ͵òζñ͵ñ͵ñ͵ñ͵ñ͵ðÌ´ðÌ´ðÌ´ï˳ï˳ï˳î˱î˱î˱î˱î˱î˱î˱íʰïʰïʰîɯîɯíÈ®ìÇ­ìÇ­ìÇ­ëÆ¬ëÆ¬ëÆ¬êÅ«êÅ«êÅ«ëÆ¬ëÆ¬èééĪéĪèéèéèéèéç¨ùÙÂúÚÃúÚÃûÛÄüÜÅüÜÅüÜÅüÜÅûÛÄûÛÄûÛÄûÛÄûÛÄûÛÄûÛÄûÛÄýÛÄýÛÄýÛÄýÛÄýÛÄýÛÄýÛÄýÛÄüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃûÙÂûÙÂûÙÂûÙÂúØÁúØÁúØÁúØÁù×Àù×Àù×Àù×ÀúØÁù×Àù×Àù×ÀøÖ¿øÖ¿øÖ¿øÖ¿øÖ¿øÖ¿øÖ¿÷Õ¾÷Õ¾÷Õ¾÷Õ¾÷Õ¾øÓ½øÓ½øÓ½øÓ½÷Ò¼÷Ò¼÷Ò¼÷Ò¼öÓº÷Ó»÷Ó»÷Ó»õѹöÒºöÒºöÒºôиõѹõѹôиôиôиôиóÏ·ôиóÏ·óÏ·óÏ·óÏ·òζòζòζñδñδñδñδñδñδðͳðͳòͳñ̲ñ̲ñ̲ð˱ïʰïʰïʰîɯîɯîɯíÈ®îɯíÈ®íÈ®ìÇ­ìÇ­íÈ®íÈ®ìÇ­ëÆ¬ëÆ¬êÅ«êÅ«ûÛÄûÛÄûÛÄûÛÄüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅûÛÄûÛÄûÛÄûÛÄýÛÄýÛÄüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃûÙÂúØÁûÙÂûÙÂûÙÂûÙÂúØÁúØÁúØÁúØÁúØÁúØÁù×Àù×ÀøÖ¿øÖ¿øÖ¿øÖ¿øÖ¿ù×ÀøÖ¿÷Õ¾÷Õ¾÷Õ¾÷Õ¾÷Õ¾øÓ½øÓ½øÓ½øÓ½÷Ò¼÷Ò¼÷Ò¼÷Ò¼öÓº÷Ó»÷Ó»öÒºöÒºöÒºöÒºöÒºõѹõѹõѹõѹõѹõѹôиôиôиôиôиóÏ·óÏ·óÏ·òζòζñδñδñδñδñδñδðͳðͳòͳñ̲ñ̲ñ̲ð˱ð˱ïʰïʰïʰîɯîɯîɯïʰîɯíÈ®ìÇ­ìÇ­ìÇ­ìÇ­ëÆ¬ìÇ­ëÆ¬ëÆ¬ëÆ¬üÜÅüÜÅüÜÅüÜÅýÝÆýÝÆýÝÆýÝÆüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅûÛÄûÛÄûÛÄûÛÄüÚÃýÛÄýÛÄýÛÄüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃüÚÃûÙÂûÙÂûÙÂûÙÂûÙÂûÙÂûÙÂûÙÂúØÁúØÁúØÁúØÁúØÁúØÁù×Àù×Àù×Àù×Àù×Àù×ÀøÖ¿ù×ÀøÖ¿÷Õ¾÷Õ¾÷Õ¾÷Õ¾÷Õ¾øÓ½øÓ½øÓ½øÓ½÷Ò¼÷Ò¼÷Ò¼÷Ò¼öÓº÷Ó»÷Ó»öÒº÷Ó»÷Ó»öÒºöÒºõѹôиõѹöÒºõѹõѹôиôиõѹôиôиôиóÏ·óÏ·óÏ·òζòϵòϵòϵòϵñδñδðͳðͳòͳñ̲ñ̲ñ̲ð˱ð˱ð˱ïʰïʰïʰîɯîɯîɯîɯîɯîɯíÈ®îɯîɯíÈ®ìÇ­ìÇ­ëÆ¬ëÆ¬ûÜÅüÝÆýÞÇüÝÆüÝÆüÝÆüÝÆüÝÆûÜÅûÜÅûÜÅûÜÅûÜÅûÜÅûÜÅûÜÅûÛÄûÛÄûÛÄûÛÄüÜÅüÜÅüÜÅüÜÅûÛÄûÛÄûÛÄûÛÄúÚÃûÛÄûÛÄûÛÄýÛÃýÛÃýÛÃýÛÃüÚÂüÚÂüÚÂüÚÂüÚÃüÚÃüÚÃüÚÃûÙÂûÙÂûÙÂûÙÂúØÀúØÀúØÀù׿÷Õ½úØÀúØÀù׿øÖ¿øÖ¿øÖ¿÷Õ¾÷Õ¾ù×Àù×ÀöÔ¾øÔ¼øÔ¼ùÕ½úÖ¾õѹøÔ¼ùÕ½ùÕ½÷Ó»÷Ó»÷Ó»÷Ó»öÒºöÒºöÒºöÒºõѹõѹõѹõѹõѹõѹõѹõѹõѹõѹõѹõѹôиôиóÏ·óÏ·óжòϵòϵòϵñδñδðͳðͳñ̲ñ̲ñ̲ñ̲ñ̲ñ̲ð˱ð˱ð˱ð˱ð˱ïʰïʰîɯîɯîɯïʰîɯîɯîɯìÇ­ìÇ­ìÇ­ëÆ¬ûÜÅüÝÆýÞÇýÞÇüÝÆüÝÆüÝÆüÝÆûÜÅûÜÅûÜÅûÜÅûÜÅûÜÅûÜÅûÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅûÛÄûÛÄüÜÅûÛÄýÛÃýÛÃýÛÃýÛÃýÛÃýÛÃýÛÃýÛÃýÛÄýÛÄýÛÄýÛÄüÚÃüÚÃüÚÃüÚÃüÚÂüÚÂüÚÂûÙÁúØÀúØÀúØÀù׿ù×Àù×Àù×ÀøÖ¿ù×Àù×Àù×À÷Õ¿úÖ¾úÖ¾û׿û׿øÔ¼ùÕ½ùÕ½øÔ¼ùÕ½ùÕ½ùÕ½ùÕ½øÔ¼øÔ¼øÔ¼øÔ¼÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»õѹõѹõѹõѹõѹôиôиôиóжóжóжòϵóжóжòϵòϵóδóδóδóδòͳñ̲ñ̲ñ̲ñ̲ñ̲ð˱ð˱ð˱ïʰïʰïʰïʰïʰîɯîɯîɯîɯîɯíÈ®üÝÆýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆûÜÅûÜÅûÜÅûÜÅýÝÆýÝÆýÝÆýÝÆûÛÄüÜÅüÜÅüÜÅþÜÄþÜÄþÜÄþÜÄýÛÃýÛÃýÛÃýÛÃýÛÄýÛÄýÛÄýÛÄýÛÄýÛÄýÛÄýÛÄüÚÂüÚÂüÚÂûÙÁüÚÂûÙÁûÙÁúØÀûÙÂûÙÂúØÁúØÁúØÁúØÁù×Àù×Àû׿û׿û׿û׿û׿úÖ¾ùÕ½ùÕ½ùÕ½ùÕ½ùÕ½ùÕ½øÔ¼øÔ¼øÔ¼øÔ¼øÔ¼øÔ¼øÔ¼øÔ¼÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»÷Ó»öÒºöÒºõѹõѹõÒ¸ôÑ·ôÑ·ôÑ·óжóжòϵòϵõжôϵôϵôϵóδóδòͳòͳòͳòͳòͳñ̲ñ̲ñ̲ð˱ð˱ð˱ð˱ð˱ïʰïʰïʰîɯíÈ®üÝÆýÞÇþßÈýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆýÝÆýÝÆýÝÆýÝÆüÜÅýÝÆýÝÆüÜÅÿÝÅÿÝÅÿÝÅÿÝÅþÜÄþÜÄþÜÄþÜÄþÜÅþÜÅþÜÅþÜÅýÛÄýÛÄýÛÄýÛÄþÜÄýÛÃýÛÃýÛÃüÚÂûÙÁûÙÁýÛÃüÚÃüÚÃüÚÃûÙÂüÚÃûÙÂúØÁûÙÂýÙÀüØÀüØÀû׿üØÀúÖ¾úÖ¾û׿úÖ¾úÖ¾úÖ¾úÖ¾ùÕ½ùÕ½ùÕ½ùÕ½ùÕ½ùÕ½ùÕ½ùÕ½øÔ¼øÔ¼øÔ¼øÔ¼øÔ¼øÔ¼øÔ¼øÔ¼÷Ó»÷Ó»öÒºöÒºöÓ¹õÒ¸õÒ¸õÒ¸ôÑ·ôÑ·ôÑ·óжõжõжôϵóδôϵôϵóδóδóδóδóδòͳòͳòͳòͳñ̲ñ̲ñ̲ñ̲ð˱ð˱ñ̲ð˱ïʰýÞÇýÞÇýÞÇýÞÇüÝÆüÝÆüÝÆüÝÆýÞÇýÞÇýÞÇýÞÇüÝÆýÞÇýÞÇýÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇýÞÇýÞÇýÞÇýÞÇüÝÆüÝÆüÝÆüÝÆýÝÆýÝÆýÝÆýÝÆüÜÅüÜÅüÜÅüÜÅûÜÂüÝÄüÝÄûÜÃûÜÃûÜÃûÜÃûÜÃýÜÂýÜÂýÜÂýÜÂýÜÂýÜÂýÜÂýÜÂüÚÂüÚÂüÚÂüÚÂüÚÂüÚÂüÚÂüÚÂúÙ¿úÙ¿úÙ¿úÙ¿úÙ¿úÙ¿úÙ¿ùؾúØÁúØÁúØÁúØÁøÖ¿øÖ¿øÖ¿øÖ¿øÖ¾÷Õ½÷Õ½÷Õ½÷Õ½÷Õ½÷Õ½÷Õ½öÔ¼÷Õ½öÔ¼õÓ»õÓ»õÓ»õÓ»ôÒºóѹôÒºóѹòиóѹòиòиòиôиóÏ·óÏ·óÏ·ôиôиôиôиñÏ·ñÏ·ñÏ·ðζðζðζï͵ï͵ðͳðͳðͳï̲ï̲ï̲î˱î˱þßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈýÞÇýÞÇþßÈýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÝÆýÝÆýÝÆýÝÆüÜÅüÜÅüÜÅüÜÅûÜÃüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄþÝÃþÝÃþÝÃþÝÃýÜÂýÜÂýÜÂýÜÂýÛÃýÛÃýÛÃýÛÃýÛÃýÛÃýÛÃýÛÃüÛÁüÛÁüÛÁüÛÁýÜÂýÜÂüÛÁüÜÁúØÁúØÁúØÁúØÁúØÁúØÁúØÁúØÁúØÀúØÀù׿ù׿øÖ¾øÖ¾øÖ¾øÖ¾÷Õ½øÖ¾÷Õ½öÔ¼øÖ¾÷Õ½÷Õ½öÔ¼öÔ¼öÔ¼õÓ»ôÒºõÓ»õÓ»ôÒºôÒºöÒºõѹõѹõѹóÏ·óÏ·óÏ·óÏ·ñÏ·ñÏ·ðζðζñÏ·ðζðζðζòϵòϵòϵñδñδñδðͳðͳþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈÿàÉþßÈýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇüÝÆüÝÆüÝÆüÝÆþÞÇþÞÇþÞÇþÞÇýÝÆýÝÆýÝÆýÝÆüÝÄýÞÅýÞÅüÝÄýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅüÝÄüÝÄüÝÄüÝÄûÜÃûÜÃûÜÃûÜÃûÜÃûÜÃûÜÃûÜÃûÜÃûÜÃûÜÃûÜÃûÜÃûÜÃûÜÃûÜÃúÚÃúÚÃúÚÃúÚÃùÙÂùÙÂùÙÂùÙÂøÚÀøÙÀøÙÀøÙÀ÷Ø¿÷Ø¿÷Ø¿÷Ø¿ù׿ù׿øÖ¾øÖ¾øÖ¾øÖ¾÷Õ½÷Õ½÷Õ½÷Õ½öÔ¼õÓ»õÓ»õÓ»õÓ»õÓ»öÒºöÒºõѹõѹôиôиôиôиòиòиñÏ·ñÏ·òиòиñÏ·ñÏ·òϵòϵòϵñδñδñδðͳðͳüàÈüàÈüàÈüàÈýáÉýáÉýáÉýáÉüàÈüàÈüàÈüàÈüàÈýáÉýáÉýáÉþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈýÞÇýÞÇýÞÇýÞÇÿßÈÿßÈÿßÈÿßÈþÞÇþÞÇþÞÇþÞÇýÞÅýÞÅþ߯ýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄûÜÃûÜÃüÝÄüÝÄûÛÄûÛÄûÛÄûÛÄúÚÃúÚÃúÚÃúÚÃúÛÂúÛÂúÛÂùÚÁùÚÁùÚÁùÚÁùÚÁúØÀúØÀúØÀù׿úØÀù׿ù׿ù׿ù׿ù׿øÖ¾÷Õ½÷Õ½÷Õ½öÔ¼öÔ¼öÔ¼õÓ»õÓ»õÓ»ôÒºôÒºôÒºôÒºôÒºôÒºóѹóѹóѹóѹòиòиòÑ·ñжñжñжðϵðϵðϵïδüàÈüàÈýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈýÞÇþßÈþßÈýÞÇýÞÇýÞÇýÞÇýÞÇüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄüÝÄýÞÅýÞÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅýÜÆùÚÁùÚÁùÚÁùÚÁùÚÁùÚÁùÚÁùÚÁùÙÂùÙÂùÙÂùÙÂùÙÂùÙÂùÙÂùÙÂ÷Ø¿÷Ø¿÷Ø¿÷Ø¿ö×¾ö×¾ö×¾õÖ½øÖ¾÷Õ½÷Õ½÷Õ½öÔ¼öÔ¼öÔ¼÷Ô¼òÓºòÓºòÓºòÓºòÓºòÓºñÒ¹ñÒ¹òиòиñÏ·ñÏ·ñÏ·ñÏ·ñÏ·ðζüàÈýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈýÞÇþßÈþßÈýÞÇþßÈþßÈþßÈþßÈÿàÉÿàÉÿàÉÿàÉýÞÇýÞÇýÞÇýÞÇýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅýÞÅüÝÄýÞÅýÞÅýÞÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÝÄüÝÄüÝÄüÝÄûÜÃûÜÃûÜÃûÜÃûÛÄûÛÄûÛÄûÛÄúÚÃúÚÃúÚÃúÚÃùÚÁùÚÁøÙÀøÙÀùÚÁøÙÀøÙÀøÙÀù׿øÖ¾øÖ¾øÖ¾÷Õ½÷Õ½÷Õ½öÔ¼ôÕ¼ôÕ¼ôÕ¼ôÕ¼óÔ»óÔ»óÔ»òÓºôÒºóѹóѹóѹòиòиñÏ·ñÏ·ûáÉûáÉûáÉüâÊûáÉûáÉûáÉûáÉûáÉûáÉûáÉûáÉûáÉûáÉûáÉûáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉýÞÇþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇý߯ý߯ý߯ý߯üÞÅüÞÅüÞÅüÞÅüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆûÜÅûÜÅûÜÅûÜÅûÜÅûÜÅûÜÅûÜÅûÝÄûÝÄûÝÄûÝÄûÝÄûÝÄûÝÄûÝÄüÜÅüÜÅüÜÅüÜÅûÛÄûÛÄûÛÄûÛÄûÜÃúÛÂúÛÂúÛÂùÚÁùÚÁøÙÀøÙÀúØÀúØÀù׿ù׿ù׿ù׿øÖ¾øÖ¾ö×¾ö×¾ö×¾õÖ½õÖ½õÖ½ôÕ¼ôÕ¼õÓ»õÓ»ôÒºôÒºóѹóѹóѹòиûáÉûáÉüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉþßÈÿàÉÿàÉþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈý߯ý߯ý߯ý߯üÞÅüÞÅüÞÅüÞÅüÝÆüÝÆüÝÆüÝÆýÞÇýÞÇüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆûÝÄûÝÄûÝÄûÝÄûÝÄûÝÄûÝÄûÝÄüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅüÜÅûÜÃúÛÂúÛÂúÛÂûÜÃúÛÂúÛÂúÛÂúÛÂùÚÁùÚÁùÚÁøÙÀøÙÀøÙÀ÷Ø¿÷Ø¿÷Ø¿ö×¾õÖ½õÖ½õÖ½ôÕ¼ôÕ¼óÔ»óÔ»óÔ»òÓºòÓºòÓºòÓºñÒ¹ùâÈùâÈùáÉùáÉüáÌüáÌüáÍüáÍûáÉûáÉûáÉûáÉüâÊüâÊüâÊüâÊüâÊüâÊüâÊþâÊýáÉýáÉýáÉÿàÉýãÈýâÈýâÈýâÈýâÈýâÈýâÈýâÈÿáÈÿáÈÿáÈÿáÈÿáÈÿáÈÿáÈÿáÈþáÀúàÆøÞÊþÞÇÿãÄÿâÃûÝÃöÚÆúÞÅÿãÈúÝÂ÷äÊùÝÎÿÛÎÿÞÈñåÃÿÞÉÿßÈÿßÈÿßÈþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇþÞÇýÝÆýÝÆýÝÆýÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆûÜÅûÜÅûÜÅûÜÅúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÅøÙÂ÷ØÁ÷ØÁ÷ØÁ÷Ø¿÷Ø¿÷Ø¿ö×¾õÖ½ö×¾õÖ½ôÕ¼ôÕ¼ôÕ¼ôÕ¼óÔ»óÔ»óÔ»òÓºòÓºùãÊúâÊúâÊúâÌüáÌüáÌüáÍüáÍüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉýáÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉÿâÄýâÈûàÌÿàÉÿÞÅÿæÈúÜÃöàÍþéÖÿãÉûÝÁùæÊúßËÿÛÎÿÞÈõäÃÿÞÉþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈþßÈýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆüÝÆûÜÅûÜÅûÜÅûÜÅüÝÆüÝÆüÝÆüÝÆûÜÅûÜÅûÜÅûÜÅúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄúÛÄøÙÂøÙÂ÷ØÁ÷ØÁøÙÀøÙÀ÷Ø¿÷Ø¿ö×¾ö×¾õÖ½õÖ½õÖ½ôÕ¼ôÕ¼ôÕ¼óÔ»óÔ»óÔ»óÔ»úäËúäËûãÍûãÍûãÍýâÍýâÎýâÎýãËýãËýãËýãËüâÊüâÊüâÊüâÊüâÊüâÊüâÊüâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉÿàÉþâÃùàÈúßÊþßÈþàÆÿãÇ÷ßÌìÜÑóãÒÿãÏÿáÅøâÈûàÍÿÞÌÿàÉöäÇÿàÉÿàÉÿàÉÿàÉþßÈþßÈþßÈþßÈÿàÉÿàÉÿàÉÿàÉýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇýÞÇüÝÆüÝÆüÝÆüÝÆýÞÇýÞÇýÞÇýÞÇüÝÆüÝÆüÝÆüÝÆûÜÅûÜÅûÜÅûÜÅúÛÄúÛÄúÛÄúÛÄùÚÃùÚÃøÙÂøÙÂùÚÁøÙÀøÙÀøÙÀ÷Ø¿ö×¾ö×¾ö×¾ö×¾õÖ½õÖ½õÖ½ôÕ¼ôÕ¼ôÕ¼óÔ»úãÍúãÍúãÍûãÍüäÎüäÎþãÏþãÏûãÍûãÍûãÍûãÍûãÍûãÍûãÍûãÍûãÍûãÍýâÍýâÍüáÌþáÌþáÌþáÌþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊþâÊýâÇûáÉûàÌÿàÉÿåÉøÝÅúíÞ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‚”ua}Š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`wˆd}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^rƒgz‹{Ž 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*.sƒJW^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<MRjzˆDXeat€zViwCUfi{Œ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„—{‰}‹Ÿfwˆhwˆdq‚(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
54+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/DN6HR8IV6GTlH^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~huivƒlu|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€‰xˆn}…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{TlƒUm„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_tFcwFbzMgSiƒNk„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~MlƒHg~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†NoˆSuKk‚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–®„µXsˆuާ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„JhˆPm…PrˆXz“Vz“Tx”JoŠVz˜l«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‰GkCjŒ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|oCxiCxjEzlLƒrcˆ|h…”ƾ‰Å½ƒÆ¿„½¹Š°«ˆ›—pŽ¡e€”>Xi5N^8Qa;SeB[oLeys•¨l‡œv£Uq‚<^m0Qd.DZ 0G/FP2H[Œ¥À ¹†¨»}Ÿ¯|›°†¡¼§ÈÚ­À{™¬rŠž_xŒD]r:Sh7Sd7Vi@^qGbwOf}Wo…t¦t¨t”«y˜­w–­†¤½‰§À‰§ÁŸµŠ©¾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|rHqKƒv?€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}Xsˆw”©}š¯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‘€DƒxEvM‹rº°o¿¶}ÍÄ5‚zu¤m‰BZl?XhCYi@VhMeyc|v–«sŽ¢~•§\v‡<Zk2Pa&>R$1IAXb8Na£½×‰§Àt•©£²Ÿµ‘«ÆÁÔˆ¨»}›®§¸Wn~L`o<R^=S_8PhBYpIdyPm‚^zw”¨w”¨z—«y˜­t”«ƒ¡»Š¨ÁŒªÄ¡·ž³~ž±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Ž¢^vˆRiyj‘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…–^xˆOhx@WgCWfMap‡¡²›µÆ‰¥¶›¯™¸Ê’²Ç•´É›½Ð•¶É‚¢µ~š«azŠEZi6FSARZ8GP/BM/CRJ_u\ty•¯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‘®¹”®¹›©LguwNfr=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$."'$), ! !#()
55+!" &'%&$$ /(%$OD=k•ºy¡Ä‹±Ó€¤Â‰§Â’®Æ‘«À•¬Ã‹©Â‚ ¹­È°Ê¯Í²Î{¡¿ƒ©Ç…¤È{›¾r“´o“´„¨Å„¨ÆgŒ¨|¡½†£¾¯Æœªw’œE\dCV]7FT>K[9FM3CP*<M$<R–²Ì€ž¹Œ¯Æ‹­Åˆ§À¢¸¡¸Œ¬Ã€ž¶{š¯|›°s’§r£m‹žk‰œ>Ym=Yj:Te8Rc6Pb1KQ/FO9IR>KX…“Ÿœ­º}–¢^x†[vƒf}ŒOct:L]BQbAN\;GSDMW;MV5GO1AM5EQ5EQ5ER9IV3BO1BO/@M3DQ/@L3CS/?O0@P2BR0@P0@P2BR3CS0@P1AQ1AQ1AQ,9I0=M1>N'4D+5F1;L'1B'1C"-;!*7$.$*&+/&*+"'((,-".+%-,#"%$#!!,+'/+*=98%-&
56\ No newline at end of file
57diff --git a/host_applications/linux/apps/hello_pi/hello_wayland/Makefile b/host_applications/linux/apps/hello_pi/hello_wayland/Makefile
58new file mode 100644
59index 0000000..c9ddf23
60--- /dev/null
61+++ b/host_applications/linux/apps/hello_pi/hello_wayland/Makefile
62@@ -0,0 +1,5 @@
63+OBJS=triangle.o
64+BIN=hello_wayland.bin
65+LDFLAGS+=-lwayland-client -lwayland-egl
66+
67+include ../Makefile.include
68diff --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
69new file mode 100644
70index 0000000..663e23b
71--- /dev/null
72+++ b/host_applications/linux/apps/hello_pi/hello_wayland/cube_texture_and_coords.h
73@@ -0,0 +1,100 @@
74+/*
75+Copyright (c) 2012, Broadcom Europe Ltd
76+All rights reserved.
77+
78+Redistribution and use in source and binary forms, with or without
79+modification, are permitted provided that the following conditions are met:
80+ * Redistributions of source code must retain the above copyright
81+ notice, this list of conditions and the following disclaimer.
82+ * Redistributions in binary form must reproduce the above copyright
83+ notice, this list of conditions and the following disclaimer in the
84+ documentation and/or other materials provided with the distribution.
85+ * Neither the name of the copyright holder nor the
86+ names of its contributors may be used to endorse or promote products
87+ derived from this software without specific prior written permission.
88+
89+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
90+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
93+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99+*/
100+
101+// Spatial coordinates for the cube
102+
103+static const GLbyte quadx[6*4*3] = {
104+ /* FRONT */
105+ -10, -10, 10,
106+ 10, -10, 10,
107+ -10, 10, 10,
108+ 10, 10, 10,
109+
110+ /* BACK */
111+ -10, -10, -10,
112+ -10, 10, -10,
113+ 10, -10, -10,
114+ 10, 10, -10,
115+
116+ /* LEFT */
117+ -10, -10, 10,
118+ -10, 10, 10,
119+ -10, -10, -10,
120+ -10, 10, -10,
121+
122+ /* RIGHT */
123+ 10, -10, -10,
124+ 10, 10, -10,
125+ 10, -10, 10,
126+ 10, 10, 10,
127+
128+ /* TOP */
129+ -10, 10, 10,
130+ 10, 10, 10,
131+ -10, 10, -10,
132+ 10, 10, -10,
133+
134+ /* BOTTOM */
135+ -10, -10, 10,
136+ -10, -10, -10,
137+ 10, -10, 10,
138+ 10, -10, -10,
139+};
140+
141+/** Texture coordinates for the quad. */
142+static const GLfloat texCoords[6 * 4 * 2] = {
143+ 0.f, 0.f,
144+ 1.f, 0.f,
145+ 0.f, 1.f,
146+ 1.f, 1.f,
147+
148+ 0.f, 0.f,
149+ 1.f, 0.f,
150+ 0.f, 1.f,
151+ 1.f, 1.f,
152+
153+ 0.f, 0.f,
154+ 1.f, 0.f,
155+ 0.f, 1.f,
156+ 1.f, 1.f,
157+
158+ 0.f, 0.f,
159+ 1.f, 0.f,
160+ 0.f, 1.f,
161+ 1.f, 1.f,
162+
163+ 0.f, 0.f,
164+ 1.f, 0.f,
165+ 0.f, 1.f,
166+ 1.f, 1.f,
167+
168+ 0.f, 0.f,
169+ 1.f, 0.f,
170+ 0.f, 1.f,
171+ 1.f, 1.f,
172+};
173+
174diff --git a/host_applications/linux/apps/hello_pi/hello_wayland/triangle.c b/host_applications/linux/apps/hello_pi/hello_wayland/triangle.c
175new file mode 100644
176index 0000000..1a7bfc4
177--- /dev/null
178+++ b/host_applications/linux/apps/hello_pi/hello_wayland/triangle.c
179@@ -0,0 +1,666 @@
180+/*
181+Copyright (c) 2012, Broadcom Europe Ltd
182+All rights reserved.
183+
184+Redistribution and use in source and binary forms, with or without
185+modification, are permitted provided that the following conditions are met:
186+ * Redistributions of source code must retain the above copyright
187+ notice, this list of conditions and the following disclaimer.
188+ * Redistributions in binary form must reproduce the above copyright
189+ notice, this list of conditions and the following disclaimer in the
190+ documentation and/or other materials provided with the distribution.
191+ * Neither the name of the copyright holder nor the
192+ names of its contributors may be used to endorse or promote products
193+ derived from this software without specific prior written permission.
194+
195+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
196+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
197+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
198+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
199+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
200+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
201+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
202+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
203+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
204+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
205+*/
206+
207+// A rotating cube rendered with OpenGL|ES. Three images used as textures on the cube faces.
208+
209+#define _GNU_SOURCE
210+
211+#include <stdio.h>
212+#include <stdlib.h>
213+#include <string.h>
214+#include <math.h>
215+#include <assert.h>
216+#include <unistd.h>
217+#include <sys/socket.h>
218+#include <sys/un.h>
219+
220+#include <wayland-egl.h>
221+#include <wayland-client.h>
222+
223+#include "GLES/gl.h"
224+#include "EGL/egl.h"
225+#include "EGL/eglext.h"
226+
227+#include "cube_texture_and_coords.h"
228+
229+#define PATH "./"
230+
231+#define IMAGE_SIZE 128
232+
233+#ifndef M_PI
234+ #define M_PI 3.141592654
235+#endif
236+
237+
238+typedef struct
239+{
240+ uint32_t screen_width;
241+ uint32_t screen_height;
242+// OpenGL|ES objects
243+ EGLDisplay display;
244+ EGLSurface surface;
245+ EGLContext context;
246+ GLuint tex[6];
247+// model rotation vector and direction
248+ GLfloat rot_angle_x_inc;
249+ GLfloat rot_angle_y_inc;
250+ GLfloat rot_angle_z_inc;
251+// current model rotation angles
252+ GLfloat rot_angle_x;
253+ GLfloat rot_angle_y;
254+ GLfloat rot_angle_z;
255+// current distance from camera
256+ GLfloat distance;
257+ GLfloat distance_inc;
258+// pointers to texture buffers
259+ char *tex_buf1;
260+ char *tex_buf2;
261+ char *tex_buf3;
262+ struct wl_display *wl_display;
263+ struct wl_registry *wl_registry;
264+ struct wl_shell *wl_shell;
265+ struct wl_shell_surface *wl_shell_surface;
266+ struct wl_compositor *wl_compositor;
267+ struct wl_surface *wl_surface;
268+ struct wl_callback *wl_callback;
269+ struct wl_egl_window *wl_egl_window;
270+ int needs_update;
271+ int ellapsed_frames;
272+ int kill_compositor;
273+ int single_frame;
274+ int terminate_abruptly;
275+} CUBE_STATE_T;
276+
277+static void init_ogl(CUBE_STATE_T *state);
278+static void init_model_proj(CUBE_STATE_T *state);
279+static void reset_model(CUBE_STATE_T *state);
280+static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc);
281+static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc);
282+static void redraw_scene(CUBE_STATE_T *state);
283+static void update_model(CUBE_STATE_T *state);
284+static void init_textures(CUBE_STATE_T *state);
285+static void load_tex_images(CUBE_STATE_T *state);
286+static void exit_func(CUBE_STATE_T *state);
287+
288+static void
289+registry_handle_global(void *data, struct wl_registry *registry,
290+ uint32_t name, const char *interface, uint32_t version)
291+{
292+ CUBE_STATE_T *state = data;
293+
294+ if (strcmp(interface, "wl_compositor") == 0) {
295+ state->wl_compositor =
296+ wl_registry_bind(registry, name,
297+ &wl_compositor_interface, 1);
298+ } else if (strcmp(interface, "wl_shell") == 0) {
299+ state->wl_shell = wl_registry_bind(registry, name,
300+ &wl_shell_interface, 1);
301+ }
302+}
303+
304+static void
305+registry_handle_global_remove(void *data, struct wl_registry *registry,
306+ uint32_t name)
307+{
308+}
309+
310+static const struct wl_registry_listener registry_listener = {
311+ registry_handle_global,
312+ registry_handle_global_remove
313+};
314+
315+/***********************************************************
316+ * Name: init_ogl
317+ *
318+ * Arguments:
319+ * CUBE_STATE_T *state - holds OGLES model info
320+ *
321+ * Description: Sets the display, OpenGL|ES context and screen stuff
322+ *
323+ * Returns: void
324+ *
325+ ***********************************************************/
326+static void init_ogl(CUBE_STATE_T *state)
327+{
328+ EGLBoolean result;
329+ EGLint num_config;
330+
331+ static const EGLint attribute_list[] =
332+ {
333+ EGL_RED_SIZE, 8,
334+ EGL_GREEN_SIZE, 8,
335+ EGL_BLUE_SIZE, 8,
336+ EGL_ALPHA_SIZE, 8,
337+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
338+ EGL_NONE
339+ };
340+
341+ EGLConfig config;
342+
343+ state->wl_display = wl_display_connect(NULL);
344+
345+ state->wl_registry = wl_display_get_registry(state->wl_display);
346+ wl_registry_add_listener(state->wl_registry, &registry_listener, state);
347+
348+ wl_display_dispatch(state->wl_display);
349+
350+ // get an EGL display connection
351+ state->display = eglGetDisplay(state->wl_display);
352+ assert(state->display!=EGL_NO_DISPLAY);
353+
354+ // initialize the EGL display connection
355+ result = eglInitialize(state->display, NULL, NULL);
356+ assert(EGL_FALSE != result);
357+
358+ // get an appropriate EGL frame buffer configuration
359+ result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
360+ assert(EGL_FALSE != result);
361+
362+ // create an EGL rendering context
363+ state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, NULL);
364+ assert(state->context!=EGL_NO_CONTEXT);
365+
366+ // create an EGL window surface
367+ state->screen_width = 1024;
368+ state->screen_height = 860;
369+
370+ state->wl_surface = wl_compositor_create_surface(state->wl_compositor);
371+ state->wl_shell_surface = wl_shell_get_shell_surface(state->wl_shell, state->wl_surface);
372+
373+ wl_shell_surface_set_toplevel(state->wl_shell_surface);
374+ wl_shell_surface_set_title(state->wl_shell_surface, "triangle.c");
375+
376+ state->wl_egl_window = wl_egl_window_create(state->wl_surface, state->screen_width, state->screen_height);
377+
378+ state->surface = eglCreateWindowSurface( state->display, config, state->wl_egl_window, NULL );
379+ assert(state->surface != EGL_NO_SURFACE);
380+
381+ // connect the context to the surface
382+ result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
383+ assert(EGL_FALSE != result);
384+
385+ // Set background color and clear buffers
386+ glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
387+
388+ // Enable back face culling.
389+ glEnable(GL_CULL_FACE);
390+
391+ glMatrixMode(GL_MODELVIEW);
392+}
393+
394+/***********************************************************
395+ * Name: init_model_proj
396+ *
397+ * Arguments:
398+ * CUBE_STATE_T *state - holds OGLES model info
399+ *
400+ * Description: Sets the OpenGL|ES model to default values
401+ *
402+ * Returns: void
403+ *
404+ ***********************************************************/
405+static void init_model_proj(CUBE_STATE_T *state)
406+{
407+ float nearp = 1.0f;
408+ float farp = 500.0f;
409+ float hht;
410+ float hwd;
411+
412+ glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
413+
414+ glViewport(0, 0, (GLsizei)state->screen_width, (GLsizei)state->screen_height);
415+
416+ glMatrixMode(GL_PROJECTION);
417+ glLoadIdentity();
418+
419+ hht = nearp * (float)tan(45.0 / 2.0 / 180.0 * M_PI);
420+ hwd = hht * (float)state->screen_width / (float)state->screen_height;
421+
422+ glFrustumf(-hwd, hwd, -hht, hht, nearp, farp);
423+
424+ glEnableClientState( GL_VERTEX_ARRAY );
425+ glVertexPointer( 3, GL_BYTE, 0, quadx );
426+
427+ reset_model(state);
428+}
429+
430+/***********************************************************
431+ * Name: reset_model
432+ *
433+ * Arguments:
434+ * CUBE_STATE_T *state - holds OGLES model info
435+ *
436+ * Description: Resets the Model projection and rotation direction
437+ *
438+ * Returns: void
439+ *
440+ ***********************************************************/
441+static void reset_model(CUBE_STATE_T *state)
442+{
443+ // reset model position
444+ glMatrixMode(GL_MODELVIEW);
445+ glLoadIdentity();
446+ glTranslatef(0.f, 0.f, -50.f);
447+
448+ // reset model rotation
449+ state->rot_angle_x = 45.f; state->rot_angle_y = 30.f; state->rot_angle_z = 0.f;
450+ state->rot_angle_x_inc = 0.5f; state->rot_angle_y_inc = 0.5f; state->rot_angle_z_inc = 0.f;
451+ state->distance = 40.f;
452+}
453+
454+/***********************************************************
455+ * Name: update_model
456+ *
457+ * Arguments:
458+ * CUBE_STATE_T *state - holds OGLES model info
459+ *
460+ * Description: Updates model projection to current position/rotation
461+ *
462+ * Returns: void
463+ *
464+ ***********************************************************/
465+static void update_model(CUBE_STATE_T *state)
466+{
467+ // update position
468+ state->rot_angle_x = inc_and_wrap_angle(state->rot_angle_x, state->rot_angle_x_inc);
469+ state->rot_angle_y = inc_and_wrap_angle(state->rot_angle_y, state->rot_angle_y_inc);
470+ state->rot_angle_z = inc_and_wrap_angle(state->rot_angle_z, state->rot_angle_z_inc);
471+ state->distance = inc_and_clip_distance(state->distance, state->distance_inc);
472+
473+ glLoadIdentity();
474+ // move camera back to see the cube
475+ glTranslatef(0.f, 0.f, -state->distance);
476+
477+ // Rotate model to new position
478+ glRotatef(state->rot_angle_x, 1.f, 0.f, 0.f);
479+ glRotatef(state->rot_angle_y, 0.f, 1.f, 0.f);
480+ glRotatef(state->rot_angle_z, 0.f, 0.f, 1.f);
481+}
482+
483+/***********************************************************
484+ * Name: inc_and_wrap_angle
485+ *
486+ * Arguments:
487+ * GLfloat angle current angle
488+ * GLfloat angle_inc angle increment
489+ *
490+ * Description: Increments or decrements angle by angle_inc degrees
491+ * Wraps to 0 at 360 deg.
492+ *
493+ * Returns: new value of angle
494+ *
495+ ***********************************************************/
496+static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc)
497+{
498+ angle += angle_inc;
499+
500+ if (angle >= 360.0)
501+ angle -= 360.f;
502+ else if (angle <=0)
503+ angle += 360.f;
504+
505+ return angle;
506+}
507+
508+/***********************************************************
509+ * Name: inc_and_clip_distance
510+ *
511+ * Arguments:
512+ * GLfloat distance current distance
513+ * GLfloat distance_inc distance increment
514+ *
515+ * Description: Increments or decrements distance by distance_inc units
516+ * Clips to range
517+ *
518+ * Returns: new value of angle
519+ *
520+ ***********************************************************/
521+static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc)
522+{
523+ distance += distance_inc;
524+
525+ if (distance >= 120.0f)
526+ distance = 120.f;
527+ else if (distance <= 40.0f)
528+ distance = 40.0f;
529+
530+ return distance;
531+}
532+
533+static pid_t get_server_pid(CUBE_STATE_T *state)
534+{
535+ struct ucred ucred;
536+ socklen_t len;
537+ int fd;
538+
539+ fd = wl_display_get_fd(state->wl_display);
540+ len = sizeof ucred;
541+ getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len);
542+
543+ return ucred.pid;
544+}
545+
546+static void
547+frame(void *data, struct wl_callback *callback, uint32_t time)
548+{
549+ CUBE_STATE_T *state = (CUBE_STATE_T *) data;
550+
551+ state->needs_update = 1;
552+}
553+
554+static const struct wl_callback_listener frame_listener = {
555+ frame
556+};
557+
558+static void
559+update(CUBE_STATE_T *state)
560+{
561+ if (!state->single_frame || state->ellapsed_frames == 0) {
562+ update_model(state);
563+ redraw_scene(state);
564+ }
565+
566+ state->wl_callback = wl_surface_frame(state->wl_surface);
567+ wl_callback_add_listener(state->wl_callback, &frame_listener, state);
568+
569+ if (state->ellapsed_frames == 100) {
570+ if (state->kill_compositor) {
571+ fprintf(stderr, "reached frame 100, killing compositor\n");
572+ pid_t pid = get_server_pid(state);
573+ kill(pid, SIGTERM);
574+ } else if (state->terminate_abruptly) {
575+ fprintf(stderr, "reached frame 100, terminating right away\n");
576+ exit_func(state);
577+ exit(0);
578+ }
579+ }
580+
581+ if (!state->single_frame || state->ellapsed_frames == 0)
582+ eglSwapBuffers(state->display, state->surface);
583+ else {
584+ wl_surface_damage(state->wl_surface, 0, 0, state->screen_width,
585+ state->screen_height);
586+ wl_surface_commit(state->wl_surface);
587+ }
588+
589+ state->ellapsed_frames++;
590+}
591+
592+/***********************************************************
593+ * Name: redraw_scene
594+ *
595+ * Arguments:
596+ * CUBE_STATE_T *state - holds OGLES model info
597+ *
598+ * Description: Draws the model and calls eglSwapBuffers
599+ * to render to screen
600+ *
601+ * Returns: void
602+ *
603+ ***********************************************************/
604+static void redraw_scene(CUBE_STATE_T *state)
605+{
606+ // Start with a clear screen
607+ glClear( GL_COLOR_BUFFER_BIT );
608+
609+ // Draw first (front) face:
610+ // Bind texture surface to current vertices
611+ glBindTexture(GL_TEXTURE_2D, state->tex[0]);
612+
613+ // Need to rotate textures - do this by rotating each cube face
614+ glRotatef(270.f, 0.f, 0.f, 1.f ); // front face normal along z axis
615+
616+ // draw first 4 vertices
617+ glDrawArrays( GL_TRIANGLE_STRIP, 0, 4);
618+
619+ // same pattern for other 5 faces - rotation chosen to make image orientation 'nice'
620+ glBindTexture(GL_TEXTURE_2D, state->tex[1]);
621+ glRotatef(90.f, 0.f, 0.f, 1.f ); // back face normal along z axis
622+ glDrawArrays( GL_TRIANGLE_STRIP, 4, 4);
623+
624+ glBindTexture(GL_TEXTURE_2D, state->tex[2]);
625+ glRotatef(90.f, 1.f, 0.f, 0.f ); // left face normal along x axis
626+ glDrawArrays( GL_TRIANGLE_STRIP, 8, 4);
627+
628+ glBindTexture(GL_TEXTURE_2D, state->tex[3]);
629+ glRotatef(90.f, 1.f, 0.f, 0.f ); // right face normal along x axis
630+ glDrawArrays( GL_TRIANGLE_STRIP, 12, 4);
631+
632+ glBindTexture(GL_TEXTURE_2D, state->tex[4]);
633+ glRotatef(270.f, 0.f, 1.f, 0.f ); // top face normal along y axis
634+ glDrawArrays( GL_TRIANGLE_STRIP, 16, 4);
635+
636+ glBindTexture(GL_TEXTURE_2D, state->tex[5]);
637+ glRotatef(90.f, 0.f, 1.f, 0.f ); // bottom face normal along y axis
638+ glDrawArrays( GL_TRIANGLE_STRIP, 20, 4);
639+}
640+
641+/***********************************************************
642+ * Name: init_textures
643+ *
644+ * Arguments:
645+ * CUBE_STATE_T *state - holds OGLES model info
646+ *
647+ * Description: Initialise OGL|ES texture surfaces to use image
648+ * buffers
649+ *
650+ * Returns: void
651+ *
652+ ***********************************************************/
653+static void init_textures(CUBE_STATE_T *state)
654+{
655+ // load three texture buffers but use them on six OGL|ES texture surfaces
656+ load_tex_images(state);
657+ glGenTextures(6, &state->tex[0]);
658+
659+ // setup first texture
660+ glBindTexture(GL_TEXTURE_2D, state->tex[0]);
661+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
662+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
663+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
664+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
665+
666+ // setup second texture - reuse first image
667+ glBindTexture(GL_TEXTURE_2D, state->tex[1]);
668+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
669+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
670+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
671+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
672+
673+ // third texture
674+ glBindTexture(GL_TEXTURE_2D, state->tex[2]);
675+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
676+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
677+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
678+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
679+
680+ // fourth texture - reuse second image
681+ glBindTexture(GL_TEXTURE_2D, state->tex[3]);
682+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
683+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
684+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
685+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
686+
687+ //fifth texture
688+ glBindTexture(GL_TEXTURE_2D, state->tex[4]);
689+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
690+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
691+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
692+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
693+
694+ // sixth texture - reuse third image
695+ glBindTexture(GL_TEXTURE_2D, state->tex[5]);
696+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
697+ GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
698+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
699+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
700+
701+ // setup overall texture environment
702+ glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
703+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
704+
705+ glEnable(GL_TEXTURE_2D);
706+}
707+
708+/***********************************************************
709+ * Name: load_tex_images
710+ *
711+ * Arguments:
712+ * void
713+ *
714+ * Description: Loads three raw images to use as textures on faces
715+ *
716+ * Returns: void
717+ *
718+ ***********************************************************/
719+static void load_tex_images(CUBE_STATE_T *state)
720+{
721+ FILE *tex_file1 = NULL, *tex_file2=NULL, *tex_file3 = NULL;
722+ int bytes_read, image_sz = IMAGE_SIZE*IMAGE_SIZE*3;
723+
724+ state->tex_buf1 = malloc(image_sz);
725+ state->tex_buf2 = malloc(image_sz);
726+ state->tex_buf3 = malloc(image_sz);
727+
728+ tex_file1 = fopen(PATH "Lucca_128_128.raw", "rb");
729+ if (tex_file1 && state->tex_buf1)
730+ {
731+ bytes_read=fread(state->tex_buf1, 1, image_sz, tex_file1);
732+ assert(bytes_read == image_sz); // some problem with file?
733+ fclose(tex_file1);
734+ }
735+
736+ tex_file2 = fopen(PATH "Djenne_128_128.raw", "rb");
737+ if (tex_file2 && state->tex_buf2)
738+ {
739+ bytes_read=fread(state->tex_buf2, 1, image_sz, tex_file2);
740+ assert(bytes_read == image_sz); // some problem with file?
741+ fclose(tex_file2);
742+ }
743+
744+ tex_file3 = fopen(PATH "Gaudi_128_128.raw", "rb");
745+ if (tex_file3 && state->tex_buf3)
746+ {
747+ bytes_read=fread(state->tex_buf3, 1, image_sz, tex_file3);
748+ assert(bytes_read == image_sz); // some problem with file?
749+ fclose(tex_file3);
750+ }
751+}
752+
753+//------------------------------------------------------------------------------
754+
755+static void exit_func(CUBE_STATE_T *state)
756+{
757+ // clear screen
758+ glClear( GL_COLOR_BUFFER_BIT );
759+ eglSwapBuffers(state->display, state->surface);
760+
761+ // Release OpenGL resources
762+ eglMakeCurrent( state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
763+
764+ wl_egl_window_destroy(state->wl_egl_window);
765+ wl_shell_surface_destroy(state->wl_shell_surface);
766+ wl_surface_destroy(state->wl_surface);
767+
768+ eglDestroySurface( state->display, state->surface );
769+ eglDestroyContext( state->display, state->context );
770+ eglTerminate( state->display );
771+
772+ wl_display_flush(state->wl_display);
773+
774+ // release texture buffers
775+ free(state->tex_buf1);
776+ free(state->tex_buf2);
777+ free(state->tex_buf3);
778+
779+ printf("\ncube closed\n");
780+} // exit_func()
781+
782+static int running = 1;
783+
784+static void
785+signal_int(int signum)
786+{
787+ running = 0;
788+}
789+
790+//==============================================================================
791+
792+int main (int argc, char *argv[])
793+{
794+ struct sigaction sigint;
795+ CUBE_STATE_T state = {0,};
796+ int ret = 0;
797+ int i;
798+
799+ for (i = 0; i < argc; i++) {
800+ if (strcmp(argv[i], "--kill-compositor") == 0)
801+ state.kill_compositor = 1;
802+ if (strcmp(argv[i], "--single-frame") == 0)
803+ state.single_frame = 1;
804+ if (strcmp(argv[i], "--terminate-abruptly") == 0)
805+ state.terminate_abruptly = 1;
806+ else if (strcmp(argv[i], "--help") == 0 ||
807+ strcmp(argv[i], "-h") == 0) {
808+ printf("Usage: hello_wayland.bin [OPTION]\n\n");
809+ printf("\t--kill-compositor\tkill the Wayland compositor after 100 frames\n");
810+ printf("\t-h, --help\t\tshow this text\n");
811+ printf("\t--single-frame\t\tupdate the display only once\n");
812+ printf("\t--terminate-abruptly\texit right after rendering the 100th frame\n");
813+ return 0;
814+ }
815+ }
816+
817+ // Start OGLES
818+ init_ogl(&state);
819+
820+ // Setup the model world
821+ init_model_proj(&state);
822+
823+ // initialise the OGLES texture(s)
824+ init_textures(&state);
825+
826+ sigint.sa_handler = signal_int;
827+ sigemptyset(&sigint.sa_mask);
828+ sigint.sa_flags = SA_RESETHAND;
829+ sigaction(SIGINT, &sigint, NULL);
830+
831+ state.needs_update = 1;
832+ while (running && ret != -1) {
833+ if (state.needs_update) {
834+ update(&state);
835+ state.needs_update = 0;
836+ }
837+
838+ ret = wl_display_dispatch(state.wl_display);
839+ }
840+
841+ exit_func(&state);
842+
843+ return 0;
844+}
845+
846diff --git a/host_applications/linux/apps/hello_pi/rebuild.sh b/host_applications/linux/apps/hello_pi/rebuild.sh
847index 8225dd5..0be6ce7 100755
848--- a/host_applications/linux/apps/hello_pi/rebuild.sh
849+++ b/host_applications/linux/apps/hello_pi/rebuild.sh
850@@ -14,6 +14,7 @@ make -C hello_videocube clean
851 make -C hello_teapot clean
852 make -C hello_fft clean
853 make -C hello_mmal_encode clean
854+make -C hello_wayland clean
855
856 make -C libs/ilclient
857 make -C libs/vgfont
858@@ -31,4 +32,4 @@ make -C hello_videocube
859 make -C hello_teapot
860 make -C hello_fft
861 make -C hello_mmal_encode
862-
863+make -C hello_wayland
864--
8652.16.1
866
diff --git a/recipes-graphics/userland/files/0004-wayland-egl-Add-bcm_host-to-dependencies.patch b/recipes-graphics/userland/files/0004-wayland-egl-Add-bcm_host-to-dependencies.patch
new file mode 100644
index 0000000..713fc3e
--- /dev/null
+++ b/recipes-graphics/userland/files/0004-wayland-egl-Add-bcm_host-to-dependencies.patch
@@ -0,0 +1,28 @@
1From f17879b691984b5c4950e4b94ebf102c78797ede Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Mon, 10 Aug 2015 02:38:27 -0700
4Subject: [PATCH 04/16] wayland-egl: Add bcm_host to dependencies
5
6It uses headers like vcos_platform_types.h but does not
7depend on module which should add the required include paths
8lets add the dependency on bcm_host module which should do it
9
10Signed-off-by: Khem Raj <raj.khem@gmail.com>
11---
12 interface/khronos/wayland-egl/wayland-egl.pc.in | 1 +
13 1 file changed, 1 insertion(+)
14
15diff --git a/interface/khronos/wayland-egl/wayland-egl.pc.in b/interface/khronos/wayland-egl/wayland-egl.pc.in
16index 8bafc15..fd259c9 100644
17--- a/interface/khronos/wayland-egl/wayland-egl.pc.in
18+++ b/interface/khronos/wayland-egl/wayland-egl.pc.in
19@@ -6,5 +6,6 @@ includedir=${prefix}/include
20 Name: wayland-egl
21 Description: VideoCore wayland-egl library
22 Version: @PROJECT_APIVER@
23+Requires: bcm_host
24 Libs: -L${libdir} -lwayland-egl
25 Cflags: -I${includedir}
26--
272.16.1
28
diff --git a/recipes-graphics/userland/files/0005-interface-remove-faulty-assert-to-make-weston-happy-.patch b/recipes-graphics/userland/files/0005-interface-remove-faulty-assert-to-make-weston-happy-.patch
new file mode 100644
index 0000000..8d78333
--- /dev/null
+++ b/recipes-graphics/userland/files/0005-interface-remove-faulty-assert-to-make-weston-happy-.patch
@@ -0,0 +1,29 @@
1From 0273b7b9d7a27d8fe7d3ad8680b799f997e75dca Mon Sep 17 00:00:00 2001
2From: "Yann E. MORIN" <yann.morin.1998@free.fr>
3Date: Sat, 24 Jan 2015 22:07:19 +0100
4Subject: [PATCH 05/16] interface: remove faulty assert() to make weston happy
5 at runtime
6
7This was removed after a discussion on IRC with the weston guys
8('daniels' on irc.freenode.net/#wayland).
9
10Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
11---
12 interface/vmcs_host/vc_vchi_dispmanx.c | 1 -
13 1 file changed, 1 deletion(-)
14
15diff --git a/interface/vmcs_host/vc_vchi_dispmanx.c b/interface/vmcs_host/vc_vchi_dispmanx.c
16index eab146e..29e0dee 100755
17--- a/interface/vmcs_host/vc_vchi_dispmanx.c
18+++ b/interface/vmcs_host/vc_vchi_dispmanx.c
19@@ -1306,7 +1306,6 @@ static void *dispmanx_notify_func( void *arg ) {
20 // Decrement the use count - the corresponding "use" is in vc_dispmanx_update_submit.
21 vchi_service_release(dispmanx_client.notify_handle[0]);
22 if (dispmanx_client.update_callback ) {
23- vcos_assert( dispmanx_client.pending_update_handle == handle);
24 dispmanx_client.update_callback(handle, dispmanx_client.update_callback_param);
25 }
26 } else {
27--
282.16.1
29
diff --git a/recipes-graphics/userland/files/0006-zero-out-wl-buffers-in-egl_surface_free.patch b/recipes-graphics/userland/files/0006-zero-out-wl-buffers-in-egl_surface_free.patch
new file mode 100644
index 0000000..43eb7f0
--- /dev/null
+++ b/recipes-graphics/userland/files/0006-zero-out-wl-buffers-in-egl_surface_free.patch
@@ -0,0 +1,33 @@
1From 0d678cd2042551cc4e26ec42fa3aba7c72d033b4 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Sat, 6 Feb 2016 11:10:47 -0800
4Subject: [PATCH 06/16] zero-out wl buffers in egl_surface_free
5
6origins from buildroot
7
8Signed-off-by: Khem Raj <raj.khem@gmail.com>
9---
10 interface/khronos/egl/egl_client_surface.c | 2 ++
11 1 file changed, 2 insertions(+)
12
13diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c
14index 42350bf..1f923d9 100644
15--- a/interface/khronos/egl/egl_client_surface.c
16+++ b/interface/khronos/egl/egl_client_surface.c
17@@ -690,11 +690,13 @@ void egl_surface_free(EGL_SURFACE_T *surface)
18 if (surface->back_wl_buffer) {
19 wl_buffer_destroy(surface->back_wl_buffer->wl_buffer);
20 free(surface->back_wl_buffer);
21+ surface->back_wl_buffer = 0;
22 }
23
24 if (surface->front_wl_buffer) {
25 wl_buffer_destroy(surface->front_wl_buffer->wl_buffer);
26 free(surface->front_wl_buffer);
27+ surface->front_wl_buffer = 0;
28 }
29 #endif
30 }
31--
322.16.1
33
diff --git a/recipes-graphics/userland/files/0007-initialize-front-back-wayland-buffers.patch b/recipes-graphics/userland/files/0007-initialize-front-back-wayland-buffers.patch
new file mode 100644
index 0000000..987740b
--- /dev/null
+++ b/recipes-graphics/userland/files/0007-initialize-front-back-wayland-buffers.patch
@@ -0,0 +1,34 @@
1From ec2e00989bf614b259bc9a47b5035f8586e8a214 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Sat, 6 Feb 2016 11:11:41 -0800
4Subject: [PATCH 07/16] initialize front back wayland buffers
5
6origins from metrological wayland support
7
8Signed-off-by: Khem Raj <raj.khem@gmail.com>
9---
10 interface/khronos/egl/egl_client_surface.c | 3 +++
11 1 file changed, 3 insertions(+)
12
13diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c
14index 1f923d9..9a9582c 100644
15--- a/interface/khronos/egl/egl_client_surface.c
16+++ b/interface/khronos/egl/egl_client_surface.c
17@@ -401,11 +401,14 @@ EGL_SURFACE_T *egl_surface_create(
18 #ifdef BUILD_WAYLAND
19 if (type == WINDOW && wl_display) {
20 surface->wl_egl_window = (struct wl_egl_window*)win;
21+ surface->front_wl_buffer = NULL;
22 surface->back_wl_buffer = allocate_wl_buffer(
23 surface->wl_egl_window, color);
24 resource = surface->back_wl_buffer->resource;
25 } else {
26 surface->wl_egl_window = NULL;
27+ surface->front_wl_buffer = NULL;
28+ surface->back_wl_buffer = NULL;
29 resource = DISPMANX_NO_HANDLE;
30 }
31 #endif
32--
332.16.1
34
diff --git a/recipes-graphics/userland/files/0008-Remove-RPC_FLUSH.patch b/recipes-graphics/userland/files/0008-Remove-RPC_FLUSH.patch
new file mode 100644
index 0000000..4bf05c1
--- /dev/null
+++ b/recipes-graphics/userland/files/0008-Remove-RPC_FLUSH.patch
@@ -0,0 +1,27 @@
1From 59ba66c2ea17f7a57124b9fd6c9bdff4325ff5c9 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Sat, 6 Feb 2016 11:09:18 -0800
4Subject: [PATCH 08/16] Remove RPC_FLUSH
5
6Origins from buildroot
7
8Signed-off-by: Khem Raj <raj.khem@gmail.com>
9---
10 interface/khronos/ext/gl_oes_egl_image_client.c | 1 -
11 1 file changed, 1 deletion(-)
12
13diff --git a/interface/khronos/ext/gl_oes_egl_image_client.c b/interface/khronos/ext/gl_oes_egl_image_client.c
14index f9b7287..b04ffef 100644
15--- a/interface/khronos/ext/gl_oes_egl_image_client.c
16+++ b/interface/khronos/ext/gl_oes_egl_image_client.c
17@@ -107,7 +107,6 @@ GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageO
18 GLEGLIMAGETARGETTEXTURE2DOES_ID,
19 RPC_ENUM(target),
20 RPC_EGLID(image));
21- RPC_FLUSH(thread);
22 #if EGL_BRCM_global_image
23 }
24 #endif
25--
262.16.1
27
diff --git a/recipes-graphics/userland/files/0009-fix-cmake-dependency-race.patch b/recipes-graphics/userland/files/0009-fix-cmake-dependency-race.patch
new file mode 100644
index 0000000..a2c1df5
--- /dev/null
+++ b/recipes-graphics/userland/files/0009-fix-cmake-dependency-race.patch
@@ -0,0 +1,78 @@
1From 264d82387ea1e607b2e5c899ff6bd46807c7b185 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Sat, 6 Feb 2016 13:12:47 -0800
4Subject: [PATCH 09/16] fix cmake dependency race
5
6Fixes errors like
7
8/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:
9fatal error: interface/vmcs_host/wayland-dispmanx-server-protocol.h: No
10such file or directory
11compilation terminated.
12interface/khronos/CMakeFiles/EGL_static.dir/build.make:773: recipe for
13target 'interface/khronos/CMakeFiles/EGL_static.dir/ext/egl_wayland.c.o'
14failed
15make[2]: ***
16[interface/khronos/CMakeFiles/EGL_static.dir/ext/egl_wayland.c.o] Error 1
17
18Signed-off-by: Khem Raj <raj.khem@gmail.com>
19---
20 interface/vcos/pthreads/CMakeLists.txt | 8 ++++++++
21 interface/vmcs_host/CMakeLists.txt | 8 --------
22 interface/vmcs_host/vc_vchi_dispmanx.h | 2 +-
23 3 files changed, 9 insertions(+), 9 deletions(-)
24
25diff --git a/interface/vcos/pthreads/CMakeLists.txt b/interface/vcos/pthreads/CMakeLists.txt
26index 1d81ca3..d6cd415 100644
27--- a/interface/vcos/pthreads/CMakeLists.txt
28+++ b/interface/vcos/pthreads/CMakeLists.txt
29@@ -33,6 +33,14 @@ set (SOURCES
30 ../generic/vcos_generic_blockpool.c
31 )
32
33+if (BUILD_WAYLAND)
34+wayland_add_protocol_server(
35+ SOURCES
36+ ../../../interface/wayland/dispmanx.xml
37+ dispmanx
38+)
39+endif ()
40+
41 if (VCOS_PTHREADS_BUILD_SHARED)
42 add_library (vcos SHARED ${SOURCES})
43 target_link_libraries (vcos pthread dl rt)
44diff --git a/interface/vmcs_host/CMakeLists.txt b/interface/vmcs_host/CMakeLists.txt
45index 6718215..c415176 100755
46--- a/interface/vmcs_host/CMakeLists.txt
47+++ b/interface/vmcs_host/CMakeLists.txt
48@@ -17,14 +17,6 @@ set(VCHOSTIF_SOURCE
49 # ${VMCS_TARGET}/vmcs_main.c
50 # vc_vchi_haud.c
51
52-if (BUILD_WAYLAND)
53-wayland_add_protocol_server(
54- VCHOSTIF_SOURCE
55- ../../interface/wayland/dispmanx.xml
56- dispmanx
57-)
58-endif ()
59-
60 add_library(vchostif ${VCHOSTIF_SOURCE})
61
62 #add_library(bufman vc_vchi_bufman.c )
63diff --git a/interface/vmcs_host/vc_vchi_dispmanx.h b/interface/vmcs_host/vc_vchi_dispmanx.h
64index f0bae30..8c44c58 100644
65--- a/interface/vmcs_host/vc_vchi_dispmanx.h
66+++ b/interface/vmcs_host/vc_vchi_dispmanx.h
67@@ -69,7 +69,7 @@ typedef struct {
68 #ifdef BUILD_WAYLAND
69 /* XXX: This should be in a private header that can be included from EGL and vc_* */
70 #include <wayland-server.h>
71-#include "interface/vmcs_host/wayland-dispmanx-server-protocol.h"
72+#include "interface/vcos/pthreads/wayland-dispmanx-server-protocol.h"
73 struct wl_dispmanx_server_buffer {
74 struct wl_resource *resource;
75 struct wl_dispmanx *dispmanx;
76--
772.16.1
78
diff --git a/recipes-graphics/userland/files/0010-Fix-for-framerate-with-nested-composition.patch b/recipes-graphics/userland/files/0010-Fix-for-framerate-with-nested-composition.patch
new file mode 100644
index 0000000..a6c9a59
--- /dev/null
+++ b/recipes-graphics/userland/files/0010-Fix-for-framerate-with-nested-composition.patch
@@ -0,0 +1,60 @@
1From 7c51c2d37bfadaabbbf205237d932b685b09d34f Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Tue, 29 Mar 2016 20:38:30 -0700
4Subject: [PATCH 10/16] Fix for framerate with nested composition
5
6frame rate appears irregular and lower than expected when using nested composition.
7
8Signed-off-by: Khem Raj <raj.khem@gmail.com>
9---
10 interface/khronos/egl/egl_client.c | 8 ++++++++
11 1 file changed, 8 insertions(+)
12
13diff --git a/interface/khronos/egl/egl_client.c b/interface/khronos/egl/egl_client.c
14index 03fe67b..13a110c 100644
15--- a/interface/khronos/egl/egl_client.c
16+++ b/interface/khronos/egl/egl_client.c
17@@ -2342,6 +2342,9 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
18 surface->back_wl_buffer = buffer;
19 }
20
21+ glFlush();
22+ glFinish();
23+
24 RPC_CALL7(eglIntSwapBuffers_impl,
25 thread,
26 EGLINTSWAPBUFFERS_ID_V2,
27@@ -2353,6 +2356,8 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
28 RPC_UINT(khrn_platform_get_window_position(surface->win)),
29 RPC_INT(surface->back_wl_buffer->resource));
30
31+ RPC_FLUSH(thread);
32+
33 surface->front_wl_buffer->in_use = 1;
34 wl_surface_attach(wl_egl_window->wl_surface,
35 surface->front_wl_buffer->wl_buffer,
36@@ -2360,11 +2365,13 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
37 wl_surface_damage(wl_egl_window->wl_surface, 0, 0,
38 surface->width, surface->height);
39 wl_surface_commit(wl_egl_window->wl_surface);
40+ wl_display_flush(wl_display);
41
42 while(ret != -1 && surface->back_wl_buffer->in_use)
43 ret = wl_display_dispatch_queue(wl_display, process->wl_queue);
44 } else
45 #endif
46+ {
47 RPC_CALL6(eglIntSwapBuffers_impl,
48 thread,
49 EGLINTSWAPBUFFERS_ID,
50@@ -2376,6 +2383,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
51 RPC_UINT(khrn_platform_get_window_position(surface->win)));
52
53 RPC_FLUSH(thread);
54+ }
55
56 #ifdef ANDROID
57 CLIENT_UNLOCK();
58--
592.16.1
60
diff --git a/recipes-graphics/userland/files/0011-build-shared-library-for-vchostif.patch b/recipes-graphics/userland/files/0011-build-shared-library-for-vchostif.patch
new file mode 100644
index 0000000..55a5be8
--- /dev/null
+++ b/recipes-graphics/userland/files/0011-build-shared-library-for-vchostif.patch
@@ -0,0 +1,28 @@
1From fb3002f77a175633af31019c513754d2ef5f3ac0 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Sat, 2 Apr 2016 10:37:24 -0700
4Subject: [PATCH 11/16] build shared library for vchostif
5
6Fixes #149
7
8Signed-off-by: Khem Raj <raj.khem@gmail.com>
9---
10 interface/vmcs_host/CMakeLists.txt | 2 +-
11 1 file changed, 1 insertion(+), 1 deletion(-)
12
13diff --git a/interface/vmcs_host/CMakeLists.txt b/interface/vmcs_host/CMakeLists.txt
14index c415176..d0cca1a 100755
15--- a/interface/vmcs_host/CMakeLists.txt
16+++ b/interface/vmcs_host/CMakeLists.txt
17@@ -17,7 +17,7 @@ set(VCHOSTIF_SOURCE
18 # ${VMCS_TARGET}/vmcs_main.c
19 # vc_vchi_haud.c
20
21-add_library(vchostif ${VCHOSTIF_SOURCE})
22+add_library(vchostif SHARED ${VCHOSTIF_SOURCE})
23
24 #add_library(bufman vc_vchi_bufman.c )
25
26--
272.16.1
28
diff --git a/recipes-graphics/userland/files/0012-implement-buffer-wrapping-interface-for-dispmanx.patch b/recipes-graphics/userland/files/0012-implement-buffer-wrapping-interface-for-dispmanx.patch
new file mode 100644
index 0000000..28a5fc6
--- /dev/null
+++ b/recipes-graphics/userland/files/0012-implement-buffer-wrapping-interface-for-dispmanx.patch
@@ -0,0 +1,92 @@
1From df8b9633a45069bdd1bf256d974636ef11aa39cb Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Sat, 2 Apr 2016 10:54:59 -0700
4Subject: [PATCH 12/16] implement buffer wrapping interface for dispmanx
5
6Courtesy: Zan Dobersek
7
8Signed-off-by: Khem Raj <raj.khem@gmail.com>
9---
10 interface/khronos/ext/egl_wayland.c | 42 +++++++++++++++++++++++++++++++++++++
11 interface/wayland/dispmanx.xml | 10 +++++++++
12 2 files changed, 52 insertions(+)
13
14diff --git a/interface/khronos/ext/egl_wayland.c b/interface/khronos/ext/egl_wayland.c
15index 5730743..9ef89cd 100644
16--- a/interface/khronos/ext/egl_wayland.c
17+++ b/interface/khronos/ext/egl_wayland.c
18@@ -133,8 +133,50 @@ dispmanx_create_buffer(struct wl_client *client, struct wl_resource *resource,
19 buffer->handle);
20 }
21
22+static void
23+dispmanx_wrap_buffer(struct wl_client *client, struct wl_resource *resource,
24+ uint32_t id, uint32_t handle, int32_t width, int32_t height,
25+ uint32_t stride, uint32_t buffer_height, uint32_t format)
26+{
27+ struct wl_dispmanx_server_buffer *buffer;
28+ VC_IMAGE_TYPE_T vc_format = get_vc_format(format);
29+ uint32_t dummy;
30+
31+ if(vc_format == VC_IMAGE_MIN) {
32+ wl_resource_post_error(resource,
33+ WL_DISPMANX_ERROR_INVALID_FORMAT,
34+ "invalid format");
35+ return;
36+ }
37+
38+ buffer = calloc(1, sizeof *buffer);
39+ if (buffer == NULL) {
40+ wl_resource_post_no_memory(resource);
41+ return;
42+ }
43+
44+ buffer->handle = handle;
45+ buffer->width = width;
46+ buffer->height = height;
47+ buffer->format = format;
48+
49+ buffer->resource = wl_resource_create(resource->client, &wl_buffer_interface,
50+ 1, id);
51+ if (!buffer->resource) {
52+ wl_resource_post_no_memory(resource);
53+ vc_dispmanx_resource_delete(buffer->handle);
54+ free(buffer);
55+ return;
56+ }
57+
58+ wl_resource_set_implementation(buffer->resource,
59+ (void (**)(void)) &dispmanx_buffer_interface,
60+ buffer, destroy_buffer);
61+}
62+
63 static const struct wl_dispmanx_interface dispmanx_interface = {
64 dispmanx_create_buffer,
65+ dispmanx_wrap_buffer,
66 };
67
68 static void
69diff --git a/interface/wayland/dispmanx.xml b/interface/wayland/dispmanx.xml
70index c18626d..11ed1ef 100644
71--- a/interface/wayland/dispmanx.xml
72+++ b/interface/wayland/dispmanx.xml
73@@ -118,6 +118,16 @@
74 <arg name="buffer" type="object" interface="wl_buffer"/>
75 <arg name="handle" type="uint"/>
76 </event>
77+
78+ <request name="wrap_buffer">
79+ <arg name="id" type="new_id" interface="wl_buffer"/>
80+ <arg name="handle" type="uint"/>
81+ <arg name="width" type="int"/>
82+ <arg name="height" type="int"/>
83+ <arg name="stride" type="uint"/>
84+ <arg name="buffer_height" type="uint"/>
85+ <arg name="format" type="uint"/>
86+ </request>
87 </interface>
88
89 </protocol>
90--
912.16.1
92
diff --git a/recipes-graphics/userland/files/0013-Implement-triple-buffering-for-wayland.patch b/recipes-graphics/userland/files/0013-Implement-triple-buffering-for-wayland.patch
new file mode 100644
index 0000000..ebff314
--- /dev/null
+++ b/recipes-graphics/userland/files/0013-Implement-triple-buffering-for-wayland.patch
@@ -0,0 +1,90 @@
1From 2e0e331da8556fecd841349cfae294baf0f14485 Mon Sep 17 00:00:00 2001
2From: Jeff Wannamaker <jeff_wannamaker@cable.comcast.com>
3Date: Thu, 19 Jan 2017 18:56:07 +0000
4Subject: [PATCH 13/16] Implement triple buffering for wayland
5
6Change from double to triple buffering for wayland.
7This enables higher frame rates without tearing artifacts
8by allowing both the glFinish and the buffer release
9interlock to operate without pushing the frame period
10to two vertical intervals
11
12Signed-off-by: Jeff Wannamaker <jeff_wannamaker@cable.comcast.com>
13Signed-off-by: Khem Raj <raj.khem@gmail.com>
14---
15 interface/khronos/egl/egl_client.c | 3 ++-
16 interface/khronos/egl/egl_client_surface.c | 8 ++++++++
17 interface/khronos/egl/egl_client_surface.h | 11 +++++++++++
18 3 files changed, 21 insertions(+), 1 deletion(-)
19
20diff --git a/interface/khronos/egl/egl_client.c b/interface/khronos/egl/egl_client.c
21index 13a110c..0380274 100644
22--- a/interface/khronos/egl/egl_client.c
23+++ b/interface/khronos/egl/egl_client.c
24@@ -2323,7 +2323,8 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
25
26 buffer_temp = surface->front_wl_buffer;
27 surface->front_wl_buffer = surface->back_wl_buffer;
28- surface->back_wl_buffer = buffer_temp;
29+ surface->back_wl_buffer = surface->middle_wl_buffer;
30+ surface->middle_wl_buffer = buffer_temp;
31
32 configid = egl_config_to_id(surface->config);
33 color = egl_config_get_color_format(configid);
34diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c
35index 9a9582c..10b3b04 100644
36--- a/interface/khronos/egl/egl_client_surface.c
37+++ b/interface/khronos/egl/egl_client_surface.c
38@@ -402,12 +402,14 @@ EGL_SURFACE_T *egl_surface_create(
39 if (type == WINDOW && wl_display) {
40 surface->wl_egl_window = (struct wl_egl_window*)win;
41 surface->front_wl_buffer = NULL;
42+ surface->middle_wl_buffer = NULL;
43 surface->back_wl_buffer = allocate_wl_buffer(
44 surface->wl_egl_window, color);
45 resource = surface->back_wl_buffer->resource;
46 } else {
47 surface->wl_egl_window = NULL;
48 surface->front_wl_buffer = NULL;
49+ surface->middle_wl_buffer = NULL;
50 surface->back_wl_buffer = NULL;
51 resource = DISPMANX_NO_HANDLE;
52 }
53@@ -696,6 +698,12 @@ void egl_surface_free(EGL_SURFACE_T *surface)
54 surface->back_wl_buffer = 0;
55 }
56
57+ if (surface->middle_wl_buffer) {
58+ wl_buffer_destroy(surface->middle_wl_buffer->wl_buffer);
59+ free(surface->middle_wl_buffer);
60+ surface->middle_wl_buffer = 0;
61+ }
62+
63 if (surface->front_wl_buffer) {
64 wl_buffer_destroy(surface->front_wl_buffer->wl_buffer);
65 free(surface->front_wl_buffer);
66diff --git a/interface/khronos/egl/egl_client_surface.h b/interface/khronos/egl/egl_client_surface.h
67index e328b77..58a3184 100644
68--- a/interface/khronos/egl/egl_client_surface.h
69+++ b/interface/khronos/egl/egl_client_surface.h
70@@ -312,6 +312,17 @@ typedef struct {
71 */
72 struct wl_dispmanx_client_buffer *front_wl_buffer;
73
74+ /*
75+ middle_wl_buffer
76+
77+ Validity:
78+ type == WINDOW
79+
80+ Invariant:
81+ client-side information about the wl_buffer in the middle
82+ */
83+ struct wl_dispmanx_client_buffer *middle_wl_buffer;
84+
85 /*
86 back_wl_buffer
87
88--
892.16.1
90
diff --git a/recipes-graphics/userland/files/0014-GLES2-gl2ext.h-Define-GL_R8_EXT-and-GL_RG8_EXT.patch b/recipes-graphics/userland/files/0014-GLES2-gl2ext.h-Define-GL_R8_EXT-and-GL_RG8_EXT.patch
new file mode 100644
index 0000000..3da4a48
--- /dev/null
+++ b/recipes-graphics/userland/files/0014-GLES2-gl2ext.h-Define-GL_R8_EXT-and-GL_RG8_EXT.patch
@@ -0,0 +1,35 @@
1From 6e8562b45a2e14490da2ca258c9ce3d7bc8375f3 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 10 May 2017 06:39:34 +0000
4Subject: [PATCH 14/16] GLES2/gl2ext.h: Define GL_R8_EXT and GL_RG8_EXT
5
6weston code uses these defines
7Upstream-Status: Pending
8
9Signed-off-by: Khem Raj <raj.khem@gmail.com>
10---
11 interface/khronos/include/GLES2/gl2ext.h | 8 ++++++++
12 1 file changed, 8 insertions(+)
13
14diff --git a/interface/khronos/include/GLES2/gl2ext.h b/interface/khronos/include/GLES2/gl2ext.h
15index 4eacf7f..b1acc9f 100644
16--- a/interface/khronos/include/GLES2/gl2ext.h
17+++ b/interface/khronos/include/GLES2/gl2ext.h
18@@ -327,6 +327,14 @@ typedef void* GLeglImageOES;
19 #define GL_RGBX_BRCM 0x80EE
20 #endif
21
22+#ifndef GL_EXT_texture_rg
23+#define GL_EXT_texture_rg 1
24+#define GL_RED_EXT 0x1903
25+#define GL_RG_EXT 0x8227
26+#define GL_R8_EXT 0x8229
27+#define GL_RG8_EXT 0x822B
28+#endif /* GL_EXT_texture_rg */
29+
30 /* GL_EXT_texture_type_2_10_10_10_REV */
31 #ifndef GL_EXT_texture_type_2_10_10_10_REV
32 #define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
33--
342.18.0
35
diff --git a/recipes-graphics/userland/files/0015-EGL-glplatform.h-define-EGL_CAST.patch b/recipes-graphics/userland/files/0015-EGL-glplatform.h-define-EGL_CAST.patch
new file mode 100644
index 0000000..605d0c0
--- /dev/null
+++ b/recipes-graphics/userland/files/0015-EGL-glplatform.h-define-EGL_CAST.patch
@@ -0,0 +1,32 @@
1From a2182e5437a6664cdb0f3330f6cbee873b6f975a Mon Sep 17 00:00:00 2001
2From: Andrea Galbusera <gizero@gmail.com>
3Date: Fri, 14 Jul 2017 09:52:54 +0200
4Subject: [PATCH 15/16] EGL/glplatform.h: define EGL_CAST
5
6C++ / C typecast macros for special EGL handle values: used by libepoxy code
7The definition comes from the updated version of this header in mesa.
8
9Upstream-Status: Pending
10---
11 interface/khronos/include/EGL/eglplatform.h | 7 +++++++
12 1 file changed, 7 insertions(+)
13
14diff --git a/interface/khronos/include/EGL/eglplatform.h b/interface/khronos/include/EGL/eglplatform.h
15index 1f7c930..c39d425 100644
16--- a/interface/khronos/include/EGL/eglplatform.h
17+++ b/interface/khronos/include/EGL/eglplatform.h
18@@ -202,4 +202,11 @@ EGLAPI void EGLAPIENTRY BEGL_GetDefaultDriverInterfaces(BEGL_DriverInterfaces *i
19 #include "interface/khronos/common/khrn_client_mangle.h"
20 #endif
21
22+/* C++ / C typecast macros for special EGL handle values */
23+#if defined(__cplusplus)
24+#define EGL_CAST(type, value) (static_cast<type>(value))
25+#else
26+#define EGL_CAST(type, value) ((type) (value))
27+#endif
28+
29 #endif /* __eglplatform_h */
30--
312.16.1
32
diff --git a/recipes-graphics/userland/files/0016-Allow-multiple-wayland-compositor-state-data-per-pro.patch b/recipes-graphics/userland/files/0016-Allow-multiple-wayland-compositor-state-data-per-pro.patch
new file mode 100644
index 0000000..d20ec82
--- /dev/null
+++ b/recipes-graphics/userland/files/0016-Allow-multiple-wayland-compositor-state-data-per-pro.patch
@@ -0,0 +1,145 @@
1From 6b4c4d469d435bfcfb464356b6ccc9421c6b8fd5 Mon Sep 17 00:00:00 2001
2From: Jeff Wannamaker <jeff_wannamaker@cable.comcast.com>
3Date: Sat, 27 Jan 2018 12:28:31 -0500
4Subject: [PATCH 16/16] Allow multiple wayland compositor state data per
5 process
6
7When eglBindWaylandDisplayWL is called store the wl_global
8created in a list associated with the wayland display.
9This allows multiple wayland compositor instances to be
10created and used per process. This scenario is common for
11applications integrating externl process UI elements
12via embedded composition e.g. westeros
13
14Signed-off-by: Jeff Wannamaker <jeff_wannamaker@cable.comcast.com>
15Signed-off-by: Khem Raj <raj.khem@gmail.com>
16---
17 interface/khronos/common/khrn_client.c | 2 +-
18 interface/khronos/common/khrn_client.h | 11 +++++++-
19 interface/khronos/ext/egl_wayland.c | 50 ++++++++++++++++++++++++++++++----
20 3 files changed, 55 insertions(+), 8 deletions(-)
21
22diff --git a/interface/khronos/common/khrn_client.c b/interface/khronos/common/khrn_client.c
23index d7e798e..60bdb63 100644
24--- a/interface/khronos/common/khrn_client.c
25+++ b/interface/khronos/common/khrn_client.c
26@@ -147,7 +147,7 @@ bool client_process_state_init(CLIENT_PROCESS_STATE_T *process)
27 {
28 if (!process->inited) {
29 #ifdef BUILD_WAYLAND
30- process->wl_global = NULL;
31+ process->wlStateMap = NULL;
32 #endif
33
34 if (!khrn_pointer_map_init(&process->contexts, 64))
35diff --git a/interface/khronos/common/khrn_client.h b/interface/khronos/common/khrn_client.h
36index 615f7b4..4fa86f7 100644
37--- a/interface/khronos/common/khrn_client.h
38+++ b/interface/khronos/common/khrn_client.h
39@@ -170,6 +170,15 @@ static INLINE CLIENT_THREAD_STATE_T *CLIENT_GET_CHECK_THREAD_STATE(void)
40 return (CLIENT_THREAD_STATE_T *)platform_tls_get_check(client_tls);
41 }
42
43+#ifdef BUILD_WAYLAND
44+typedef struct WAYLAND_STATE
45+{
46+ struct WAYLAND_STATE *next;
47+ struct wl_display *display;
48+ struct wl_global *wl_global;
49+} WAYLAND_STATE_T;
50+#endif
51+
52 /*
53 per-process state
54
55@@ -318,7 +327,7 @@ struct CLIENT_PROCESS_STATE {
56 struct wl_event_queue *wl_queue;
57
58 /* Compositor-side Wayland state */
59- struct wl_global *wl_global;
60+ WAYLAND_STATE_T *wlStateMap;
61 #endif
62 };
63
64diff --git a/interface/khronos/ext/egl_wayland.c b/interface/khronos/ext/egl_wayland.c
65index 9ef89cd..abd5ab3 100644
66--- a/interface/khronos/ext/egl_wayland.c
67+++ b/interface/khronos/ext/egl_wayland.c
68@@ -208,17 +208,38 @@ eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
69 {
70 CLIENT_THREAD_STATE_T *thread;
71 CLIENT_PROCESS_STATE_T *process;
72+ WAYLAND_STATE_T *stateIter;
73+ WAYLAND_STATE_T *stateNew;
74+ struct wl_global *wl_global;
75
76 if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
77 return EGL_FALSE;
78
79- if (process->wl_global != NULL)
80+ stateIter= process->wlStateMap;
81+ while( stateIter )
82+ {
83+ if ( stateIter->display == display )
84+ goto error;
85+ stateIter= stateIter->next;
86+ }
87+
88+ wl_global = wl_global_create(display, &wl_dispmanx_interface, 1,
89+ NULL, bind_dispmanx);
90+ if (wl_global == NULL)
91 goto error;
92
93- process->wl_global = wl_global_create(display, &wl_dispmanx_interface, 1,
94- NULL, bind_dispmanx);
95- if (process->wl_global == NULL)
96+ stateNew= (WAYLAND_STATE_T*)calloc( 1, sizeof(WAYLAND_STATE_T));
97+ if (stateNew == NULL )
98+ {
99+ wl_global_destroy(wl_global);
100 goto error;
101+ }
102+
103+ stateNew->next= process->wlStateMap;
104+ stateNew->display= display;
105+ stateNew->wl_global= wl_global;
106+ process->wlStateMap= stateNew;
107+ CLIENT_UNLOCK();
108
109 return EGL_TRUE;
110
111@@ -232,12 +253,29 @@ eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
112 {
113 CLIENT_THREAD_STATE_T *thread;
114 CLIENT_PROCESS_STATE_T *process;
115+ WAYLAND_STATE_T *stateIter;
116+ WAYLAND_STATE_T *statePrev;
117
118 if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
119 return EGL_FALSE;
120
121- wl_global_destroy(process->wl_global);
122- process->wl_global = NULL;
123+ statePrev= NULL;
124+ stateIter= process->wlStateMap;
125+ while( stateIter )
126+ {
127+ if ( stateIter->display == display )
128+ {
129+ wl_global_destroy(stateIter->wl_global);
130+ if ( statePrev )
131+ statePrev->next= stateIter->next;
132+ else
133+ process->wlStateMap= stateIter->next;
134+ free( stateIter );
135+ break;
136+ }
137+ statePrev= stateIter;
138+ stateIter= stateIter->next;
139+ }
140
141 CLIENT_UNLOCK();
142
143--
1442.16.1
145
diff --git a/recipes-graphics/userland/files/0017-khronos-backport-typedef-for-EGL_EXT_image_dma_buf_i.patch b/recipes-graphics/userland/files/0017-khronos-backport-typedef-for-EGL_EXT_image_dma_buf_i.patch
new file mode 100644
index 0000000..fbfdb86
--- /dev/null
+++ b/recipes-graphics/userland/files/0017-khronos-backport-typedef-for-EGL_EXT_image_dma_buf_i.patch
@@ -0,0 +1,35 @@
1From 8403fb3869f56ea7492fa6265bd6cd1dd5146e6e Mon Sep 17 00:00:00 2001
2From: Hugo Hromic <hhromic@gmail.com>
3Date: Sun, 13 May 2018 10:49:04 +0100
4Subject: [PATCH] khronos: backport typedef for EGL_EXT_image_dma_buf_import
5
6The `gstreamer1.0-plugins-base` package version `1.14` uses `EGL_EXT_image_dma_buf_import`, which
7expects the `EGLuint64KHR` typedef that is present in recent versions of Khronos.
8However, the older version included in userland does not provide it.
9
10This patch backports the missing typedef from recent Khronos into userland.
11See: <https://www.khronos.org/registry/EGL/api/EGL/eglext.h>
12
13Submitted to userland in <https://github.com/raspberrypi/userland/pull/467>
14
15Upstream-Status: Submitted
16
17---
18 interface/khronos/include/EGL/eglext.h | 4 ++++
19 1 file changed, 4 insertions(+)
20
21diff --git a/interface/khronos/include/EGL/eglext.h b/interface/khronos/include/EGL/eglext.h
22index d7e5ba7..4ce762d 100755
23--- a/interface/khronos/include/EGL/eglext.h
24+++ b/interface/khronos/include/EGL/eglext.h
25@@ -190,6 +190,10 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSy
26 typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
27 #endif
28
29+#ifndef EGL_KHR_uint64_typedef
30+#define EGL_KHR_uint64_typedef 1
31+typedef khronos_uint64_t EGLuint64KHR;
32+#endif /* EGL_KHR_uint64_typedef */
33
34 #ifndef EGL_WL_bind_wayland_display
35 #define EGL_WL_bind_wayland_display 1
diff --git a/recipes-graphics/userland/files/0018-Add-EGL_IMG_context_priority-related-defines.patch b/recipes-graphics/userland/files/0018-Add-EGL_IMG_context_priority-related-defines.patch
new file mode 100644
index 0000000..330fb3e
--- /dev/null
+++ b/recipes-graphics/userland/files/0018-Add-EGL_IMG_context_priority-related-defines.patch
@@ -0,0 +1,35 @@
1From ca43aae3e1879d2595cfee80032322f5fdfdea11 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Sun, 15 Jul 2018 00:48:38 -0700
4Subject: [PATCH] Add EGL_IMG_context_priority related defines
5
6These defines are needed for compiling weston 4.x
7taken from Khronos headers
8
9Signed-off-by: Khem Raj <raj.khem@gmail.com>
10---
11 interface/khronos/include/EGL/eglext.h | 8 ++++++++
12 1 file changed, 8 insertions(+)
13
14diff --git a/interface/khronos/include/EGL/eglext.h b/interface/khronos/include/EGL/eglext.h
15index dcc90ce..6842bf9 100755
16--- a/interface/khronos/include/EGL/eglext.h
17+++ b/interface/khronos/include/EGL/eglext.h
18@@ -93,6 +93,14 @@ typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGL
19 typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
20 #endif
21
22+#ifndef EGL_IMG_context_priority
23+#define EGL_IMG_context_priority 1
24+#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3102
25+#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
26+#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
27+#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
28+#endif /* EGL_IMG_context_priority */
29+
30 #ifndef EGL_KHR_vg_parent_image
31 #define EGL_KHR_vg_parent_image 1
32 #define EGL_VG_PARENT_IMAGE_KHR 0x30BA /* eglCreateImageKHR target */
33--
342.18.0
35