| Andrew Geissler | 26e4bea | 2020-11-30 19:54:03 -0600 | [diff] [blame] | 1 | From 8a734f44beea9b10548ba696eaea1f5a76148fd5 Mon Sep 17 00:00:00 2001 | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 2 | From: Dom Cobley <dc4@broadcom.com> | 
|  | 3 | Date: Tue, 9 Jul 2013 09:26:26 -0400 | 
| Andrew Geissler | 26e4bea | 2020-11-30 19:54:03 -0600 | [diff] [blame] | 4 | Subject: [PATCH] Allow applications to set next resource handle | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 5 |  | 
|  | 6 | This patch adds provisions in userland to | 
|  | 7 | let apps callers set the next rendereing dispmanx resource. | 
|  | 8 | It's useful for implementing, say, a buffer carousel. | 
|  | 9 | --- | 
| Patrick Williams | 520786c | 2023-06-25 16:20:36 -0500 | [diff] [blame] | 10 | Upstream-Status: Pending | 
|  | 11 |  | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 12 | interface/khronos/common/khrn_client_rpc.h |  2 ++ | 
|  | 13 | interface/khronos/common/khrn_int_ids.h    |  2 ++ | 
|  | 14 | interface/khronos/egl/egl_client.c         | 30 +++++++++++++++++++--- | 
|  | 15 | interface/khronos/egl/egl_client_surface.c | 24 ++++++++++++++++- | 
|  | 16 | interface/khronos/egl/egl_client_surface.h |  3 ++- | 
|  | 17 | interface/khronos/egl/egl_int_impl.h       |  5 ++-- | 
|  | 18 | 6 files changed, 59 insertions(+), 7 deletions(-) | 
|  | 19 |  | 
|  | 20 | diff --git a/interface/khronos/common/khrn_client_rpc.h b/interface/khronos/common/khrn_client_rpc.h | 
|  | 21 | index dc4351d..10ea060 100644 | 
|  | 22 | --- a/interface/khronos/common/khrn_client_rpc.h | 
|  | 23 | +++ b/interface/khronos/common/khrn_client_rpc.h | 
|  | 24 | @@ -685,6 +685,7 @@ static INLINE void rpc_call12_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id | 
|  | 25 | 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); } | 
|  | 26 | 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); } | 
|  | 27 | 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); } | 
|  | 28 | +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); } | 
|  | 29 | #endif | 
|  | 30 |  | 
|  | 31 | #define RPC_CALL1_OUT_CTRL(fn, thread, id, out)                                               rpc_call1_out_ctrl(thread, id, out) | 
|  | 32 | @@ -702,6 +703,7 @@ static INLINE void rpc_call15_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id | 
|  | 33 | #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) | 
|  | 34 | #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) | 
|  | 35 | #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) | 
|  | 36 | +#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) | 
|  | 37 |  | 
|  | 38 | # if !defined(__SYMBIAN32__)  //use functions defined in khrpc.cpp | 
|  | 39 | 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; } | 
|  | 40 | diff --git a/interface/khronos/common/khrn_int_ids.h b/interface/khronos/common/khrn_int_ids.h | 
|  | 41 | index 8378f4a..ec961e0 100644 | 
|  | 42 | --- a/interface/khronos/common/khrn_int_ids.h | 
|  | 43 | +++ b/interface/khronos/common/khrn_int_ids.h | 
|  | 44 | @@ -367,6 +367,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | 45 | */ | 
|  | 46 |  | 
|  | 47 | #define EGLINTCREATESURFACE_ID            0x4000 | 
|  | 48 | +#define EGLINTCREATESURFACE_ID_V2         0x4100 | 
|  | 49 | #define EGLINTCREATEGLES11_ID             0x4001 | 
|  | 50 | #define EGLINTCREATEGLES20_ID             0x4002 | 
|  | 51 | #define EGLINTCREATEVG_ID                 0x4003 | 
|  | 52 | @@ -377,6 +378,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | 53 | #define EGLINTMAKECURRENT_ID              0x4008 | 
|  | 54 | #define EGLINTFLUSHANDWAIT_ID             0x4009 | 
|  | 55 | #define EGLINTSWAPBUFFERS_ID              0x400a | 
|  | 56 | +#define EGLINTSWAPBUFFERS_ID_V2           0x410a | 
|  | 57 | #define EGLINTSELECTMIPMAP_ID             0x400b | 
|  | 58 | #define EGLINTFLUSH_ID                    0x400c | 
|  | 59 | #define EGLINTGETCOLORDATA_ID             0x400d | 
|  | 60 | diff --git a/interface/khronos/egl/egl_client.c b/interface/khronos/egl/egl_client.c | 
|  | 61 | index 9d617c8..b8bb374 100644 | 
|  | 62 | --- a/interface/khronos/egl/egl_client.c | 
|  | 63 | +++ b/interface/khronos/egl/egl_client.c | 
|  | 64 | @@ -162,6 +162,17 @@ static void egl_current_release(CLIENT_PROCESS_STATE_T *process, EGL_CURRENT_T * | 
|  | 65 | void egl_gl_flush_callback(bool wait); | 
|  | 66 | void egl_vg_flush_callback(bool wait); | 
|  | 67 |  | 
|  | 68 | +#include "interface/vmcs_host/vc_dispmanx_types.h" | 
|  | 69 | +/**HACKHACK - give us the ability to inject a DispmanX | 
|  | 70 | + * resource handle into the CreateWindowSurface and | 
|  | 71 | + * SwapBuffers calls */ | 
|  | 72 | +static DISPMANX_RESOURCE_HANDLE_T next_resource_handle; | 
|  | 73 | + | 
|  | 74 | +EGLAPI EGLBoolean EGLAPIENTRY eglSetNextResourceHandle(DISPMANX_RESOURCE_HANDLE_T handle) | 
|  | 75 | +{ | 
|  | 76 | +   next_resource_handle = handle; | 
|  | 77 | +} | 
|  | 78 | + | 
|  | 79 | /* | 
|  | 80 | TODO: do an RPC call to make sure the Khronos vll is loaded (and that it stays loaded until eglTerminate) | 
|  | 81 | Also affects global image (and possibly others?) | 
|  | 82 | @@ -644,7 +655,8 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig c | 
|  | 83 | false, | 
|  | 84 | EGL_NO_TEXTURE, | 
|  | 85 | EGL_NO_TEXTURE, | 
|  | 86 | -                                0, 0); | 
|  | 87 | +                                0, 0, | 
|  | 88 | +                                next_resource_handle); | 
|  | 89 |  | 
|  | 90 | if (surface) { | 
|  | 91 | if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) { | 
|  | 92 | @@ -889,7 +901,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig | 
|  | 93 | mipmap_texture, | 
|  | 94 | texture_format, | 
|  | 95 | texture_target, | 
|  | 96 | -                             0, 0); | 
|  | 97 | +                             0, 0, 0); | 
|  | 98 |  | 
|  | 99 | if (surface) { | 
|  | 100 | if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) { | 
|  | 101 | @@ -1031,7 +1043,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig c | 
|  | 102 | false, | 
|  | 103 | EGL_NO_TEXTURE, | 
|  | 104 | EGL_NO_TEXTURE, | 
|  | 105 | -                                   pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle); | 
|  | 106 | +                                   pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle, 0); | 
|  | 107 |  | 
|  | 108 | if (surface) { | 
|  | 109 | if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) { | 
|  | 110 | @@ -2303,6 +2315,18 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf) | 
|  | 111 |  | 
|  | 112 | vcos_log_trace("eglSwapBuffers server call"); | 
|  | 113 |  | 
|  | 114 | +               if (next_resource_handle) | 
|  | 115 | +               RPC_CALL7(eglIntSwapBuffers_impl, | 
|  | 116 | +                     thread, | 
|  | 117 | +                     EGLINTSWAPBUFFERS_ID_V2, | 
|  | 118 | +                     RPC_UINT(surface->serverbuffer), | 
|  | 119 | +                     RPC_UINT(surface->width), | 
|  | 120 | +                     RPC_UINT(surface->height), | 
|  | 121 | +                     RPC_UINT(surface->internal_handle), | 
|  | 122 | +                     RPC_UINT(surface->swap_behavior == EGL_BUFFER_PRESERVED ? 1 : 0), | 
|  | 123 | +                     RPC_UINT(khrn_platform_get_window_position(surface->win)), | 
|  | 124 | +                     RPC_INT(next_resource_handle)); | 
|  | 125 | +               else | 
|  | 126 | RPC_CALL6(eglIntSwapBuffers_impl, | 
|  | 127 | thread, | 
|  | 128 | EGLINTSWAPBUFFERS_ID, | 
|  | 129 | diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c | 
|  | 130 | index 6846dfa..128325e 100644 | 
|  | 131 | --- a/interface/khronos/egl/egl_client_surface.c | 
|  | 132 | +++ b/interface/khronos/egl/egl_client_surface.c | 
|  | 133 | @@ -314,7 +314,8 @@ EGL_SURFACE_T *egl_surface_create( | 
|  | 134 | EGLenum texture_format, | 
|  | 135 | EGLenum texture_target, | 
|  | 136 | EGLNativePixmapType pixmap, | 
|  | 137 | -   const uint32_t *pixmap_server_handle) | 
|  | 138 | +   const uint32_t *pixmap_server_handle, | 
|  | 139 | +   DISPMANX_RESOURCE_HANDLE_T next_resource_handle) | 
|  | 140 | { | 
|  | 141 | KHRN_IMAGE_FORMAT_T color; | 
|  | 142 | KHRN_IMAGE_FORMAT_T depth; | 
|  | 143 | @@ -473,6 +474,27 @@ EGL_SURFACE_T *egl_surface_create( | 
|  | 144 | #endif | 
|  | 145 | uint32_t results[3]; | 
|  | 146 |  | 
|  | 147 | +         if (next_resource_handle) | 
|  | 148 | +         RPC_CALL16_OUT_CTRL(eglIntCreateSurface_impl, | 
|  | 149 | +                             thread, | 
|  | 150 | +                             EGLINTCREATESURFACE_ID_V2, | 
|  | 151 | +                             RPC_UINT(serverwin), | 
|  | 152 | +                             RPC_UINT(buffers), | 
|  | 153 | +                             RPC_UINT(width), | 
|  | 154 | +                             RPC_UINT(height), | 
|  | 155 | +                             RPC_UINT(color), | 
|  | 156 | +                             RPC_UINT(depth), | 
|  | 157 | +                             RPC_UINT(mask), | 
|  | 158 | +                             RPC_UINT(multi), | 
|  | 159 | +                             RPC_UINT(largest_pbuffer), | 
|  | 160 | +                             RPC_UINT(mipmap_texture), | 
|  | 161 | +                             RPC_UINT(config_depth_bits), | 
|  | 162 | +                             RPC_UINT(config_stencil_bits), | 
|  | 163 | +                             RPC_UINT(sem_name), | 
|  | 164 | +                             RPC_UINT(type), | 
|  | 165 | +                             RPC_INT(next_resource_handle), | 
|  | 166 | +                             results); | 
|  | 167 | +         else | 
|  | 168 | RPC_CALL15_OUT_CTRL(eglIntCreateSurface_impl, | 
|  | 169 | thread, | 
|  | 170 | EGLINTCREATESURFACE_ID, | 
|  | 171 | diff --git a/interface/khronos/egl/egl_client_surface.h b/interface/khronos/egl/egl_client_surface.h | 
|  | 172 | index c99d44c..b5bf70a 100644 | 
|  | 173 | --- a/interface/khronos/egl/egl_client_surface.h | 
|  | 174 | +++ b/interface/khronos/egl/egl_client_surface.h | 
|  | 175 | @@ -322,7 +322,8 @@ extern EGL_SURFACE_T *egl_surface_create( | 
|  | 176 | EGLenum texture_format, | 
|  | 177 | EGLenum texture_target, | 
|  | 178 | EGLNativePixmapType pixmap, | 
|  | 179 | -   const uint32_t *pixmap_server_handle); | 
|  | 180 | +   const uint32_t *pixmap_server_handle, | 
|  | 181 | +   DISPMANX_RESOURCE_HANDLE_T next_resource_handle); | 
|  | 182 | extern EGL_SURFACE_T *egl_surface_from_vg_image( | 
|  | 183 | VGImage vg_handle, | 
|  | 184 | EGLSurface name, | 
|  | 185 | diff --git a/interface/khronos/egl/egl_int_impl.h b/interface/khronos/egl/egl_int_impl.h | 
|  | 186 | index 8a5734c..51b3580 100644 | 
|  | 187 | --- a/interface/khronos/egl/egl_int_impl.h | 
|  | 188 | +++ b/interface/khronos/egl/egl_int_impl.h | 
|  | 189 | @@ -56,7 +56,8 @@ FN(int, eglIntCreateSurface_impl, ( | 
|  | 190 | uint32_t config_stencil_bits, | 
|  | 191 | uint32_t sem, | 
|  | 192 | uint32_t type, | 
|  | 193 | -   uint32_t *results)) | 
|  | 194 | +   uint32_t *results, | 
|  | 195 | +   DISPMANX_RESOURCE_HANDLE_T next_resource_handle)) | 
|  | 196 |  | 
|  | 197 | FN(int, eglIntCreatePbufferFromVGImage_impl, ( | 
|  | 198 | VGImage vg_handle, | 
|  | 199 | @@ -110,7 +111,7 @@ FN(void, eglIntMakeCurrent_impl, (uint32_t pid_0, uint32_t pid_1, uint32_t glver | 
|  | 200 | FN(int, eglIntFlushAndWait_impl, (uint32_t flushgl, uint32_t flushvg)) | 
|  | 201 | FN(void, eglIntFlush_impl, (uint32_t flushgl, uint32_t flushvg)) | 
|  | 202 |  | 
|  | 203 | -FN(void, eglIntSwapBuffers_impl, (EGL_SURFACE_ID_T s, uint32_t width, uint32_t height, uint32_t handle, uint32_t preserve, uint32_t position)) | 
|  | 204 | +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)) | 
|  | 205 | FN(void, eglIntSelectMipmap_impl, (EGL_SURFACE_ID_T s, int level)) | 
|  | 206 |  | 
|  | 207 | 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)) |