1From 08d56c1174e27573ae8df2a7b9e6632afd0bfe86 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/18] 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.19.1
208
209