1 /* 2 Arcan Shared Memory Interface 3 4 Copyright (c) 2012-2018, Bjorn Stahl 5 All rights reserved. 6 7 Redistribution and use in source and binary forms, 8 with or without modification, are permitted provided that the 9 following conditions are met: 10 11 1. Redistributions of source code must retain the above copyright notice, 12 this list of conditions and the following disclaimer. 13 14 2. Redistributions in binary form must reproduce the above copyright notice, 15 this list of conditions and the following disclaimer in the documentation 16 and/or other materials provided with the distribution. 17 18 3. Neither the name of the copyright holder nor the names of its contributors 19 may be used to endorse or promote products derived from this software without 20 specific prior written permission. 21 22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 24 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 26 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 27 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32 THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #ifndef _HAVE_ARCAN_SHMIF_CONTROL 36 #define _HAVE_ARCAN_SHMIF_CONTROL 37 38 /* 39 * This header defines the interface and support functions for 40 * shared memory- based communication between the arcan parent 41 * and frameservers/non-authoritative clients. 42 * 43 * For extended documentation on how this interface works, design 44 * rationale, changes and so on, please refer to the wiki @ 45 * https://github.com/letoram/arcan/wiki/Shmif 46 */ 47 48 /* 49 * This prefix is used over HOME only if no explicit path was provided 50 * and there is no XDG_RUNTIME_DIR to use. 51 */ 52 #ifndef ARCAN_SHMIF_PREFIX 53 #define ARCAN_SHMIF_PREFIX ".arcan/." 54 #endif 55 56 /* 57 * Default permissions / mask that listening sockets will be created under 58 */ 59 #ifndef ARCAN_SHM_UMASK 60 #define ARCAN_SHM_UMASK (S_IRWXU | S_IRWXG) 61 #endif 62 63 /* 64 * Compile-time constants that define the size and layout 65 * of the shared structure. These values are part in defining the ABI 66 * and should therefore only be tuned when you have control of the 67 * whole-system compilation and packaging (OS distributions, embedded 68 * systems). 69 */ 70 71 /* 72 * Define the reserved ring-buffer space used for input and output events 73 * must be 0 < PP_QUEUE_SZ < 256 74 */ 75 #ifndef PP_QUEUE_SZ 76 #define PP_QUEUE_SZ 127 77 #endif 78 static const int ARCAN_SHMIF_QUEUE_SZ = PP_QUEUE_SZ; 79 80 /* 81 * Audio format and basic parameters, this is kept primitive on purpose. 82 * This will be revised shortly, but modifying still breaks ABI and may 83 * break current frameservers. 84 */ 85 #ifndef AUDIO_SAMPLE_TYPE 86 #define AUDIO_SAMPLE_TYPE int16_t 87 #endif 88 89 /* 90 * ALWAYS interleaved. for later quality work, all the video/audio 91 * buffer format tuning and indirection macros will be moved to separate 92 * selectable profile headers, and the packing macros will be redone 93 * using C11 type-generic macros. 94 */ 95 typedef AUDIO_SAMPLE_TYPE shmif_asample; 96 static const int ARCAN_SHMIF_SAMPLERATE = 48000; 97 static const int ARCAN_SHMIF_ACHANNELS = 2; 98 99 #ifndef SHMIF_AFLOAT 100 #define SHMIF_AFLOAT(X) ( (int16_t) ((X) * 32767.0) ) /* sacrifice -32768 */ 101 #endif 102 103 #ifndef SHMIF_AINT16 104 #define SHMIF_AINT16(X) ( (int16_t) ((X)) ) 105 #endif 106 107 /* 108 * These limits affect ABI as we need to track how much is used in each 109 * audiobuffer slot 110 */ 111 #define ARCAN_SHMIF_ABUFC_LIM 12 112 #define ARCAN_SHMIF_VBUFC_LIM 3 113 /* 114 * These are technically limited by the combination of graphics and video 115 * platforms. Since the buffers are placed at the end of the struct, they 116 * can be changed without breaking ABI though several resize requests may 117 * be rejected. 118 */ 119 #ifndef PP_SHMPAGE_MAXW 120 #define PP_SHMPAGE_MAXW 8192 121 #endif 122 static const int ARCAN_SHMPAGE_MAXW = PP_SHMPAGE_MAXW; 123 124 #ifndef PP_SHMPAGE_MAXH 125 #define PP_SHMPAGE_MAXH 8192 126 #endif 127 static const int ARCAN_SHMPAGE_MAXH = PP_SHMPAGE_MAXH; 128 129 /* 130 * Identification token that may need to be passed when making a socket 131 * connection to the main arcan process. 132 */ 133 #ifndef PP_SHMPAGE_SHMKEYLIM 134 #define PP_SHMPAGE_SHMKEYLIM 32 135 #endif 136 137 /* 138 * We abstract the base type for a pixel and provide a packing macro in order 139 * to permit systems with lower memory to switch to uint16 RGB565 style 140 * formats, and to permit future switches to higher depth/range. The 141 * separation between video_platform definition of these macros also allows a 142 * comparison between engine internals and interface to warn or convert. 143 */ 144 #ifndef VIDEO_PIXEL_TYPE 145 #define VIDEO_PIXEL_TYPE uint32_t 146 #endif 147 148 #ifndef ARCAN_SHMPAGE_VCHANNELS 149 #define ARCAN_SHMPAGE_VCHANNELS 4 150 #endif 151 152 #ifndef ARCAN_SHMPAGE_DEFAULT_PPCM 153 #define ARCAN_SHMPAGE_DEFAULT_PPCM 37.795276 154 #endif 155 156 static const float shmif_ppcm_default = ARCAN_SHMPAGE_DEFAULT_PPCM; 157 158 typedef VIDEO_PIXEL_TYPE shmif_pixel; 159 160 /* 161 * Reasonable starting dimensions, this can be changed without breaking ABI 162 * as parent/client will initiate a resize based on gain relative to the 163 * current size. 164 * 165 * It should, at least, fit 32*32*sizeof(shmif_pixel) + sizeof(struct) + 166 * sizeof event*PP_QUEUE_SIZE*2 + PP_AUDIOBUF_SZ with alignment padding. 167 */ 168 #ifndef PP_SHMPAGE_STARTSZ 169 #define PP_SHMPAGE_STARTSZ 2014088 170 #endif 171 172 /* 173 * This is to constrain a single segment from consuming too much memory, 174 * though it also plays a big role in OVERCOMMIT builds where single segment 175 * size is fixed and will always consume this amount. 176 */ 177 #ifndef PP_SHMPAGE_MAXSZ 178 #define PP_SHMPAGE_MAXSZ 104857600 179 #endif 180 static const int ARCAN_SHMPAGE_MAX_SZ = PP_SHMPAGE_MAXSZ; 181 182 /* 183 * Overcommit is a specialized build mode (that should be avoided if possible) 184 * that sets the initial segment size to PP_SHMPAGE_STARTSZ and no new buffer 185 * dimension negotiation will occur. This is needed for shitty platforms that 186 * don't provide the means for resizing a handle- backed memory mapped store. 187 * Not to point any fingers, but system-level OSX is a pile of shit. 188 */ 189 #ifdef ARCAN_SHMIF_OVERCOMMIT 190 static const int ARCAN_SHMPAGE_START_SZ = PP_SHMPAGE_MAXSZ; 191 #else 192 static const int ARCAN_SHMPAGE_START_SZ = PP_SHMPAGE_STARTSZ; 193 #endif 194 195 #ifndef PP_SHMPAGE_ALIGN 196 #define PP_SHMPAGE_ALIGN 64 197 #endif 198 static const int ARCAN_SHMPAGE_ALIGN = PP_SHMPAGE_ALIGN; 199 200 /* 201 * Two primary transfer operation types, from the perspective of the 202 * main arcan application (i.e. normally frameservers feed INPUT but 203 * specialized recording segments are flagged as OUTPUT. Internally, 204 * these have different synchronization rules. 205 */ 206 enum arcan_shmif_type { 207 SHMIF_INPUT = 1, 208 SHMIF_OUTPUT 209 }; 210 211 /* 212 * This enum defines the possible operations for audio and video 213 * synchronization (both or either) and how locking should behave. 214 */ 215 enum arcan_shmif_sigmask { 216 SHMIF_SIGVID = 1, 217 SHMIF_SIGAUD = 2, 218 219 /* synchronous, wait for parent to acknowledge 220 * (assuming there are no more buffers available) */ 221 SHMIF_SIGBLK_FORCE = 0, 222 223 /* Extra flag, always return immediately, further writes may cause 224 * tearing and other visual/aural artifacts */ 225 SHMIF_SIGBLK_NONE = 4, 226 227 /* For >= 2 buffered contexts, compare the current to the previous submitted 228 * buffer and shrink the dirty region to the boundary of the actually changed 229 * context. If there are no visible changes, the signalling will return 230 * immediately. This will only work if the buffer history is complete and no 231 * manual dirty management has been applied. */ 232 SHMIF_SIGVID_AUTO_DIRTY = 8, 233 }; 234 235 struct arcan_shmif_cont; 236 struct shmif_ext_hidden; 237 struct arcan_shmif_page; 238 struct arcan_shmif_initial; 239 240 typedef enum arcan_shmif_sigmask( 241 *shmif_trigger_hook)(struct arcan_shmif_cont*); 242 243 typedef void (*shmif_reset_hook)(int state, void* tag); 244 245 enum ARCAN_FLAGS { 246 SHMIF_NOFLAGS = 0, 247 248 /* by default, the connection IPC resources are unlinked, this 249 * may not always be desired (debugging, monitoring, ...) */ 250 SHMIF_DONT_UNLINK = 1, 251 252 /* a guard thread is usually allocated to monitor the status of 253 * the server, setting this flag explicitly prevents the creation of 254 * that thread */ 255 SHMIF_DISABLE_GUARD = 2, 256 257 /* failure to acquire a segment should be exit(EXIT_FAILURE); */ 258 SHMIF_ACQUIRE_FATALFAIL = 4, 259 260 /* if FATALFAIL, do we have a custom function? should be first argument */ 261 SHMIF_FATALFAIL_FUNC = 8, 262 263 /* set to sleep- try spin until a connection is established */ 264 SHMIF_CONNECT_LOOP = 16, 265 266 /* don't implement pause/resume management in backend, forward the 267 * events to frontend */ 268 SHMIF_MANUAL_PAUSE = 32, 269 270 /* On crash or disconnect, wait and try to reconnect. If successful, 271 * a _RESET event will be enqueued locally with ioev[0].iv == 3. 272 * Subsegments will still be lost, and if the connection has been set-up 273 * inherited+anonymous, this will still exit like normally. Set this 274 * flag to disable RECONNECT attempts entirely. */ 275 SHMIF_NOAUTO_RECONNECT = 64, 276 277 /* for use as flag input to shmif_migrate calls, the default behavior 278 * is to only permit migration of the primary segment as there are 279 * further client considerations when secondary segments run in different 280 * threads along with the problem if subsegment requests are rejected */ 281 SHMIF_MIGRATE_SUBSEGMENTS = 128, 282 283 /* 284 * When a connection is initiated, a number of events are gathered until 285 * the connection is activated (see arcan_shmif_initial) to determine 286 * costly properties in advance. By default, this also sets the initial 287 * size of the segment. Set this flag during connection if this behavior 288 * would be ignored/overridden by a manual- "data-source controlled" 289 * size. 290 */ 291 SHMIF_NOACTIVATE_RESIZE = 256, 292 293 /* 294 * Setting this flag disables the internal management preroll stage entirely 295 */ 296 SHMIF_NOACTIVATE = 512, 297 298 /* Setting this flag will avoid sending the register event on acquire */ 299 SHMIF_NOREGISTER = 1024 300 }; 301 302 /* 303 * Convenience wrapper function of checking environment variables 304 * for packed arguments, connection path / key etc. 305 * 306 * Will also clean-up / reset related environments 307 * to prevent propagation. 308 * 309 * If no arguments could be unpacked, *arg_arr will be set to NULL. 310 * If type is set to 0, no REGISTER event will be sent and you will 311 * need to send one manually. arg_arr livespan is tied to the _cont 312 * so the caller should not free or alias. 313 * 314 * If the [type] is not set, the connection will not wait for 315 * activation and the initial function will not provide anything 316 * useful. 317 */ 318 struct arg_arr; 319 struct arcan_shmif_cont arcan_shmif_open( 320 enum ARCAN_SEGID type, enum ARCAN_FLAGS flags, struct arg_arr**); 321 322 /* 323 * Retrieve a reference to the argument- array that was built 324 * during shmif_open. May fail (return NULL) on an invalid context 325 * or if no arguments could be unpacked at open time. 326 */ 327 struct arg_arr* arcan_shmif_args(struct arcan_shmif_cont*); 328 329 /* 330 * Similar to resize_ext, developed to work around some shortcomings 331 * in the initial version without breaking ABI. Adds some improvements 332 * to the register/connect approach. 333 * 334 * use like shmif_open, but pass a prefilled struct like below, 335 * along with its sizeof(struct smif_open_ext) 336 */ 337 struct shmif_open_ext { 338 enum ARCAN_SEGID type; 339 const char* title; 340 const char* ident; 341 uint64_t guid[2]; 342 }; 343 struct arcan_shmif_cont arcan_shmif_open_ext( 344 enum ARCAN_FLAGS flags, struct arg_arr**, 345 struct shmif_open_ext, size_t ext_sz); 346 347 /* 348 * If the context has been opened with the SHMIF_DONT_UNLINK flag, any 349 * named resources are still accessible. This is used for some corner 350 * cases where one client should be able to monitor another and so on. 351 * This function attempts to unlink any named resources tied to the 352 * context [c]. 353 */ 354 void arcan_shmif_unlink(struct arcan_shmif_cont* c); 355 356 /* 357 * accessor to the internal tracked segment mapping key (applicable 358 * to arcan_shmif_unlink and SHMIF_DONT_UNLINK). Will return NULL if 359 * the key has been unlinked. 360 */ 361 const char* arcan_shmif_segment_key(struct arcan_shmif_cont* c); 362 363 /* 364 * arcan_shmif_initial can be used to access initial configured 365 * settings (see struct arcan_shmif_initial for details). These values 366 * are only valid AFTER a successful call to arcan_shmif_open and ONLY 367 * until the first _poll or _wait call. 368 * 369 * REMEMBER to arcan_shmif_dupfd() on the fonts and render-nodes you 370 * want to keep and use as they will be closed, or set the fields to 371 * -1 to indicate that you take responsibility. 372 * 373 * RETURNS the number of bytes in struct (should == sizeof(struct 374 * arcan_shmif_initial, if larger, your code is using dated headers) 375 * or 0,NULL on failure (bad _cont or _enqueue/ _poll/_wait has been 376 * called). 377 */ 378 size_t arcan_shmif_initial(struct arcan_shmif_cont*, 379 struct arcan_shmif_initial**); 380 381 /* 382 * This is used to make a non-authoritative connection using 383 * a domain- socket as a connection point (as specified by the 384 * connpath and optional connkey). 385 * 386 * Will return NULL or a user-managed string with a key 387 * suitable for shmkey, along with a file descriptor to the 388 * connected socket in *conn_ch 389 */ 390 char* arcan_shmif_connect(const char* connpath, 391 const char* connkey, file_handle* conn_ch); 392 393 /* 394 * This is used to migrate a current connection, authoritative or not, 395 * to a non-authoritate connection, possibly using a different connection 396 * path and primitive. 397 * 398 * Will return false on invalid [cont] argument. 399 * 400 * Current limitations are that subsegments are not re-negotiated. 401 * Will return true or false depending on if the transfer was successful 402 * or not. If it failed, the referenced main connection is still valid. 403 */ 404 enum shmif_migrate_status { 405 SHMIF_MIGRATE_OK = 0, 406 SHMIF_MIGRATE_BADARG = -1, 407 SHMIF_MIGRATE_NOCON = -2, 408 SHMIF_MIGRATE_TRANSFER_FAIL = -4, 409 SHMIF_MIGRATE_BAD_SOURCE = -8 410 }; 411 412 enum shmif_migrate_status arcan_shmif_migrate( 413 struct arcan_shmif_cont* cont, const char* newpath, const char* key); 414 415 /* 416 * Using a identification string (implementation defined connection 417 * mechanism) If type is set to 0, no REGISTER event will be sent and 418 * you will need to send one manually. 419 */ 420 struct arcan_shmif_cont arcan_shmif_acquire( 421 struct arcan_shmif_cont* parent, /* should only be NULL internally */ 422 const char* shmkey, /* provided in ENV or from shmif_connect below */ 423 int type, /* (enum ARCAN_SEGID) archetype, in shmif_event.h */ 424 int flags, /* (enum ARCAN_FLAGS) */ 425 ... 426 ); 427 428 /* 429 * Used internally by _control etc. but also in ARCAN for mapping the 430 * different buffer positions / pointers, very limited use outside those 431 * contexts. Returns size: (end of last buffer) - addr 432 */ 433 uintptr_t arcan_shmif_mapav( 434 struct arcan_shmif_page* addr, 435 shmif_pixel* vbuf[], size_t vbufc, size_t vbuf_sz, 436 shmif_asample* abuf[], size_t abufc, size_t abuf_sz 437 ); 438 439 /* 440 * Calculate the actual size of the video buffer based on the set of hints and 441 * meta substructure. This is used INTERNALLY on both sides of SHMIF to 442 * calculate actual shmpage dimensions. The client can access this information 443 * as part of the shmif_cont structure. 444 */ 445 size_t arcan_shmif_vbufsz( 446 int meta, uint8_t hints, size_t w, size_t h, size_t rows, size_t cols); 447 448 /* 449 * There can be one "post-flag, pre-semaphore" hook that will occur 450 * before triggering a sigmask and can be used to synch audio to video 451 * or video to audio during transfers. 452 * 'mask' argument defines the signal mask slot (A xor B only, A or B is 453 * undefined behavior). 454 */ 455 shmif_trigger_hook arcan_shmif_signalhook(struct arcan_shmif_cont*, 456 enum arcan_shmif_sigmask mask, shmif_trigger_hook, void* data); 457 458 /* 459 * Using the specified shmpage state, synchronization semaphore handle, 460 * construct two event-queue contexts. Parent- flag should be set 461 * to false for frameservers 462 */ 463 void arcan_shmif_setevqs(struct arcan_shmif_page*, 464 sem_handle, arcan_evctx* inevq, arcan_evctx* outevq, bool parent); 465 466 /* resize/synchronization protocol to issue a resize of the output video buffer. 467 * 468 * This request can be declined (false return value) and should be considered 469 * expensive (may block indefinitely). Anything that depends on the contents of 470 * the shared-memory dependent parts of shmif_cont (eventqueue, vidp/audp, ...) 471 * should be considered invalid during/after a call to shmif_resize and the 472 * function will internally rebuild these structures. 473 * 474 * THIS FUNCTION IS NOT THREAD SAFE -- While a resize is pending, none of the 475 * other operations (drop, signal, en/de- queue) are safe. If events are 476 * managed on a separate thread, these should be treated in mutual exclusion 477 * with the size operation. This means that the pointers in the shmcont may be 478 * relocated, so keeping around aliases are dangerous. This can be tricky in a 479 * common case with multiple producer threads (a, v) and another event thread 480 * that reacts with a resize upon an event. 481 * 482 * arcan_shmif_lock/unlock can be used as a convenience non-reentrant mutex. 483 * 484 * There are four possible outcomes here: 485 * a. resize fails, dimensions exceed hard-coded limits. 486 * b. resize succeeds, vidp/audp are re-aligned. 487 * c. resize succeeds, the segment is truncated to a new size. 488 * d. resize succeeds, we switch to a new shared memory connection. 489 * 490 * Note that the actual effects / resize behavior in the running appl may be 491 * delayed until the first shmif_signal call on the resized segment. This is 492 * done in order to avoid visual artifacts that would stem from having source 493 * material in one resolution while metadata refers to another. 494 */ 495 bool arcan_shmif_resize( 496 struct arcan_shmif_cont*, unsigned width, unsigned height); 497 498 /* 499 * Extended version of resize that supports requesting more audio / video 500 * buffers for better swap/synch control. abuf_cnt and vbuf_cnt are limited 501 * to the constants ARCAN_SHMIF_ 502 * 503 * [meta] is used for extended / privileged data transfered and is specified 504 * as a bitmask of the following flags: 505 */ 506 enum shmif_ext_meta { 507 SHMIF_META_NONE = 0, 508 509 /* 510 * apad/apad_type region is reserved for extended color management, with 511 * normal SHMIF_SIGVID operation synchronizing updates, server side updating 512 * the structure with valid values, and client modifying 513 */ 514 SHMIF_META_CM = 2, 515 516 /* 517 * The video buffers will be switched to represent a 16-bit Float( 518 * R16,G16,B16,A16) format for HDR content and tone-mapping or HDR output 519 * is expected of the arcan instance. 520 */ 521 SHMIF_META_HDRF16 = 4, 522 523 /* 524 * This is reserved and not completely fleshed out yet, 525 * but will switch the semantics of the video buffer area to represent a 526 * texture-maps + GPU friendly packing format - with the apad area to 527 * define metadata. 528 */ 529 SHMIF_META_VOBJ = 8, 530 531 /* 532 * This contains the meta for one complete avatar tracking + display 533 * The common case for this is for a tool like the hmdserver to provide 534 * data. 535 */ 536 SHMIF_META_VR = 16, 537 538 /* 539 * Similar to HDR16, but switch to half-size mode (R8G8B8A8 -> RGB565) 540 */ 541 SHMIF_META_LDEF = 32, 542 543 /* 544 * Similar to HDR16, LDEF - but the video buffer is interpreted as a 545 * compressed video frame. This is primarily to let cliens that have 546 * a valid h264, av1, ... stream forward this without decoding. 547 */ 548 SHMIF_META_VENC = 64 549 }; 550 551 /* 552 * The acknowledged mask is reflected in cont->adata, and may subsequently 553 * affect apad and apad_type in the addr-> substructure as well. 554 */ 555 struct shmif_resize_ext { 556 uint32_t meta; 557 558 /* abuf_sz * abuf_cnt played back over samplerate */ 559 size_t abuf_sz; 560 ssize_t abuf_cnt; 561 ssize_t samplerate; 562 563 ssize_t vbuf_cnt; 564 /* 565 * this is only used with tpack, which gives us the relationship 566 * rows * cell_w = px_w 567 * cols * cell_h = px_h 568 */ 569 size_t rows; 570 size_t cols; 571 572 /* the number of ops (primitives) and ops-type come from shmif_sub and 573 * is used for calculating the size of the apad region reserved for vobj */ 574 size_t nops; 575 size_t op_fm; 576 }; 577 578 /* extended resize that allows better buffering and format controls, 579 * WARNING, the abuf_cnt and vbuf_cnt are especially important as it is 580 * allowed to set them to 0 (disable audio or video respectively). To 581 * set to -1 means 'retain the last buffer size' 582 */ 583 bool arcan_shmif_resize_ext(struct arcan_shmif_cont*, 584 unsigned width, unsigned height, struct shmif_resize_ext); 585 586 /* 587 * Unmap memory, release semaphores and related resources 588 */ 589 void arcan_shmif_drop(struct arcan_shmif_cont*); 590 591 /* 592 * Signal that a synchronized transfer should take place. The contents of the 593 * mask determine buffers to synch and blocking behavior. 594 * 595 * Returns the number of miliseconds that the synchronization reported, and 596 * is a value that can be used to adjust local rendering/buffer. 597 */ 598 unsigned arcan_shmif_signal(struct arcan_shmif_cont*, enum arcan_shmif_sigmask); 599 600 /* 601 * Signal a video transfer that is based on buffer sharing rather than on data 602 * in the shmpage. Otherwise it behaves like [arcan_shmif_signal] but with a 603 * possible reserved variadic argument for future use. 604 * 605 * If included with DEFINED(WANT_ARCAN_SHMIF_HELPER) and linked with 606 * arcan_shmif_ext, abstract support functions for setup and passing are 607 * provided (arcan_shmifext_***) 608 * 609 * mask matches (enum arcan_shmif_sigmask) but can't enforce the type here 610 * because of VA_ARGS + enum with -fshort-enums can yield UB. 611 * 612 * [NOTE] 613 * Ideally, this should work the other way around, i.e. on a resize, the server 614 * side provides the buffer descriptors to use, and signalhandle simply steps 615 * within this set. 616 * For DMA-Buf this is basically a no-go, while as for EGLStreams, that way 617 * would work better. 618 */ 619 unsigned arcan_shmif_signalhandle(struct arcan_shmif_cont* ctx, 620 int mask, int handle, size_t stride, int format, ...); 621 622 /* 623 * Returns true of handle based buffer passing is permitted or not, if not 624 * a software based approach is required. The extended graphics mode of shmif 625 * performs this conversion automatically for most cases. 626 * 627 * This should be tested before attempting a signal-handle as the event that 628 * carries rejection asynchronously. 629 */ 630 bool arcan_shmif_handle_permitted(struct arcan_shmif_cont* ctx); 631 632 /* 633 * Support function to set/unset the primary access segment (one slot for 634 * input. one slot for output), manually managed. This is just a static member 635 * helper with no currently strongly negotiated meaning. 636 */ 637 struct arcan_shmif_cont* arcan_shmif_primary(enum arcan_shmif_type); 638 void arcan_shmif_setprimary( enum arcan_shmif_type, struct arcan_shmif_cont*); 639 640 /* 641 * Enable/Lock a mutex tied to the segment. This is primarily to protect when 642 * the segment is accessed in separate threads and you need to run a resize 643 * negotiation. 644 */ 645 bool arcan_shmif_lock(struct arcan_shmif_cont*); 646 bool arcan_shmif_unlock(struct arcan_shmif_cont*); 647 648 /* 649 * Update the failure callback associated with a context- remapping due to 650 * a connection failure. Although ->vidp and ->audp may be correct, there are 651 * no guarantees and any aliases to these buffers should be updated in the 652 * callback. 653 * 654 * This is mainly useful for cases where the same shmif context is shared 655 * across multiple threads, e.g. when there is an audio producer thread and 656 * a video producer thread. 657 * 658 * The pitfalls are tied to automatic migration from crash recovery, where one 659 * producer can be stuck in signalling a data transfer, and another in event 660 * dispatch. 661 * 662 * The event dispatch discovers a forced migration, which will cause the 663 * segment mappings to be dropped, which will first lock the context. If this 664 * happens while one of the producers is holding a lock, we would enter a 665 * deadlock state. 666 * 667 * The reset callback can be triggered in multiple states: 668 * 669 * 0 : in event handler / resized 670 * 1 : context is lost and will be remapped (multiple calls) 671 * 2 : context have been remapped 672 * 3 : context didn't need to be remapped 673 * 4 : context recovery failed / broken 674 * 675 * The function returns any previous reset hook defined on the context. 676 */ 677 enum shmif_reset_hook { 678 SHMIF_RESET_RESIZE = 0, 679 SHMIF_RESET_LOST = 1, 680 SHMIF_RESET_REMAP = 2, 681 SHMIF_RESET_NOCHG = 3, 682 SHMIF_RESET_FAIL = 4 683 }; 684 shmif_reset_hook arcan_shmif_resetfunc( 685 struct arcan_shmif_cont*, shmif_reset_hook, void* tag); 686 687 /* 688 * This should be called periodically to prevent more subtle bugs from 689 * cascading and be caught at an earlier stage, it checks the shared memory 690 * context against a series of cookies and known guard values, returning 691 * [false] if not everything checks out. 692 * 693 * The guard thread (if active) uses this function as part of its monitoring 694 * heuristic. 695 */ 696 bool arcan_shmif_integrity_check(struct arcan_shmif_cont*); 697 698 /* 699 * Check if audio and/or video buffers are pending or free, 700 *-1 : broken segment 701 * 0 : both are free 702 * 1 : video pending 703 * 2 : audio pending 704 * 3 : video and audio pending 705 */ 706 int arcan_shmif_signalstatus(struct arcan_shmif_cont*); 707 708 struct arcan_shmif_region { 709 uint16_t x1, x2, y1, y2; 710 }; 711 712 struct arcan_shmif_cont { 713 struct arcan_shmif_page* addr; 714 715 /* offset- pointers into addr, can change between calls to shmif_ functions so 716 * aliasing is not recommended, especially important if (default) 717 * connection-crash recovery-reconnect is enabled as the address >may< be 718 * changed. If that is a concern, define a handler using the shmif_resetfunc */ 719 union { 720 shmif_pixel* vidp; 721 float* floatp; 722 uint8_t* vidb; 723 }; 724 union { 725 shmif_asample* audp; 726 uint8_t* audb; 727 }; 728 729 /* 730 * This cookie is set/kept to some implementation defined value and will be 731 * verified during integrity_check. It is placed here to quickly detect 732 * overflows in video or audio management from client side programming errors 733 */ 734 int16_t oflow_cookie; 735 736 /* use EITHER [audp, abufpos, abufcount] OR [audb, abufused, abufsize] 737 * to populate the current audio buffer depending on if you are working on 738 * SAMPLES or BYTES. abufpos != 0 will assume the latter */ 739 uint16_t abufused, abufpos; 740 uint16_t abufsize, abufcount; 741 742 /* updated on resize, provided to get feedback on an extended resize */ 743 uint8_t abuf_cnt; 744 745 /* 746 * the event handle is provided and used for signal event delivery 747 * in order to allow multiplexation with other input/output sources 748 */ 749 file_handle epipe; 750 751 /* 752 * Maintain a connection to the shared memory handle in order to handle 753 * resizing (on platforms that support it, otherwise define 754 * ARCAN_SHMIF_OVERCOMMIT which will only recalc pointers on resize 755 */ 756 file_handle shmh; 757 size_t shmsize; 758 759 /* 760 * Used internally for synchronization (and mapped / managed outside 761 * the regular shmpage). system-defined but typically named semaphores. 762 */ 763 sem_handle vsem, asem, esem; 764 765 /* 766 * Should be used to index vidp, i.e. vidp[y * pitch + x] = RGBA(r, g, b, a) 767 * stride and pitch account for padding, with stride being a row length in 768 * bytes and pitch a row length in pixels. 769 */ 770 size_t w, h, stride, pitch; 771 772 /* 773 * acknowledged extended attributes in response to an shmif_resize_ext 774 * request. Affects addr->apad and addr->apad_type as well. 775 * 776 * Read only, SYNCH ON EXT_RESIZE 777 */ 778 uint32_t adata; 779 780 /* 781 * defaults to ARCAN_SHMIF_SAMPLERATE but may be renegotiated as part 782 * of an extended resize. A deviation between the constant samplerate 783 * and the negotiated one will likely lead to resampling server-side. 784 * 785 * Read only, SYNCH ON EXT_RESIZE 786 */ 787 size_t samplerate; 788 789 /* 790 * Presentation and buffer content / format hints: 791 * 792 * SHMIF_RHINT_ORIGO_UL (or LL), 793 * SHMIF_RHINT_IGNORE_ALPHA 794 * SHMIF_RHINT_SUBREGION (only synch dirty region below) 795 * SHMIF_RHINT_SUBREGION_CHAIN (reserved, not in use) 796 * SHMIF_RHINT_CSPACE_SRGB (non-linear color space) 797 * SHMIF_RHINT_AUTH_TOK 798 * SHMIF_RHINT_VSIGNAL_EV (get frame- delivery notification via STEPFRAME) 799 * SHMIF_RHINT_TPACK (video buffer contents is packed in TPACK format) 800 * 801 * Write only, SYNCH on shmif_resize() calls. 802 */ 803 uint8_t hints; 804 805 /* 806 * IF the constraints: 807 * 808 * [Hints & SHMIF_RHINT_SUBREGION] and (X2>X1,(X2-X1)<=W,Y2>Y1,(Y2-Y1<=H)) 809 * valid, [ARCAN] MAY synch only the specified region. 810 * Caller manipulates this field, will be copied to shmpage during synch. 811 * 812 * The [dx, dy] hints inside of the region indicates the number of pixels that 813 * are scrolled based on the previously synched buffer. 814 * 815 * The dirty region is reset on either calls to arcan_shmif_signal (video) 816 * or on shmif_resize calls that impose a size change. 817 */ 818 struct arcan_shmif_region dirty; 819 820 /* 821 * The cookie act as overflow monitor and trigger for ABI incompatibilities 822 * between arcan main and program using the shmif library. Combined from 823 * shmpage struct offsets and type sizes. Periodically monitored (using 824 * arcan_shmif_integrity_check calls) and incompatibilities is a terminal 825 * state transition. 826 */ 827 uint64_t cookie; 828 829 /* 830 * User-tag, primarily to support attaching ancilliary data to subsegments 831 * that are run and synchronized in separate threads. 832 */ 833 void* user; 834 835 /* 836 * Opaque struct for implementation defined tracking (guard thread handles 837 * and related data). 838 */ 839 struct shmif_hidden* priv; 840 struct shmif_ext_hidden* privext; 841 842 /* 843 * Copy of the segment token identifier provided on the shmpage at setup 844 */ 845 uint32_t segment_token; 846 847 /* 848 * Video buffers may, based on extended contents hints etc. have a size 849 * that does not match the normal formula of w * h * pitch bytes. Instead, 850 * and length validation for user-side programming is best done against 851 * this field. This represents the size of a single video buffer. 852 */ 853 size_t vbufsize; 854 }; 855 856 struct arcan_shmif_initial { 857 /* pre-configured primary font and possible fallback, remember to convert 858 * to point size to account for density (interop macro 859 * SHMIF_PT_SIZE(ppcm, sz_mm) */ 860 struct { 861 int fd; 862 int type; 863 int hinting; 864 float size_mm; 865 } fonts[4]; 866 867 /* output display density and LED- layout hint for subpixel hinting */ 868 float density; 869 int rgb_layout; 870 871 /* maximum display output dimensions */ 872 size_t display_width_px; 873 size_t display_height_px; 874 uint16_t rate; 875 876 uint8_t lang[4], country[4], text_lang[4]; 877 float latitude, longitude, elevation; 878 879 /* device to use for 3D acceleration */ 880 int render_node; 881 882 /* UTC + */ 883 int timezone; 884 885 /* 16+16 possible color slots 886 * 887 * [0,1] are reserved 888 * 2..14: primary, secondary, bg, text, cursor, altcursor, highlight, label, 889 * warning, error, alert, reference, inactive, ui 890 * 891 * 15..: segment specific reference (terminal) 892 */ 893 struct { 894 uint8_t fg[3]; 895 uint8_t bg[3]; 896 bool fg_set, bg_set; 897 } colors[36]; 898 899 /* pixel size for cell alignment, this is mainly intended for TUI clients 900 * but could also be useful for grid- based UI components in toolkits that 901 * support such controls (CAD/CAM) */ 902 size_t cell_w; 903 size_t cell_h; 904 }; 905 906 enum rhint_mask { 907 /* 908 * Indicate if the buffer is to be treated as having its y=0 in the upper- 909 * left corner of an imaginary screen, or in the lower-left. The default is 910 * upper left, but many 3D accelerated drawing systems use the other form. 911 */ 912 SHMIF_RHINT_ORIGO_UL = 0, 913 SHMIF_RHINT_ORIGO_LL = 1, 914 915 /* 916 * Indicate that only a smaller portion of the buffer actually needs to 917 * be updated. It is still up to the server to decide what will actually 918 * be synched however, as it may not have access to a cached backing store 919 * in which to blit the subregion. 920 */ 921 SHMIF_RHINT_SUBREGION = 2, 922 923 /* 924 * Indicate that the contents of the alpha channel must be ignored or the 925 * output will not look as inteded. This is typical when the data source 926 * comes from a context that leaves the alpha channel in a 0- state and 927 * the client do not want to waste cycles repacking. 928 */ 929 SHMIF_RHINT_IGNORE_ALPHA = 4, 930 931 /* 932 * For shmif- vidp transfers, the source color space defaults to linear-RGB. 933 * 934 * Setting this flag indicates that the source colorspace is in sRGB format 935 * and that the engine should pick shaders and blending algorithms that can 936 * take this non-linearity into account. 937 */ 938 SHMIF_RHINT_CSPACE_SRGB = 8, 939 940 /* 941 * Used internally with shmifext_setup for the cases where we need to 942 * authenticate against the rendering subsystem. This is a no-op on many 943 * platforms. (ab)uses the VPTS field to exchange cookies. 944 */ 945 SHMIF_RHINT_AUTH_TOK = 16, 946 947 /* 948 * Used for cases where it is not wise to block on the signal- semaphore. 949 * When the buffer contents have been consumed and can be modified without 950 * risking tearing or corruption, receive a STEPFRAME event. The STEPFRAME 951 * event will contain .iv[0] == 1, .iv[1] == 0. 952 * This increases the load on the incoming eventqueue, so should be avoided if 953 * possible. If the incoming eventqueue is closing in on becoming saturated, 954 * the STEPFRAME event will not be emitted. 955 */ 956 SHMIF_RHINT_VSIGNAL_EV = 32, 957 958 /* 959 * [Reserved, not yet used] 960 * Change the buffer contents management method to be a chain of dirty 961 * rectangles rather than one continous buffer. This means that the contents of 962 * the normal vidp, stride and pitch members may mutate between calls to 963 * arcan_shmif_dirty and that it is write only, you can't use it for reliable 964 * blending etc. Setting this bit will invalidate SHMIF_RHINT_SUBREGION. 965 */ 966 SHMIF_RHINT_SUBREGION_CHAIN = 64, 967 968 /* 969 * Changes the buffer contents to be packed in the TPACK format (see 970 * tui/raster). This means that the server side will ignore the normal size 971 * hints and emit window resizes etc. accordingly. Thus, _resize calls on 972 * a TPACK segment only needs to be called if the context vbufsize member 973 * is too small. In those cases, the _resize dimensions are still expected 974 * to be in pixels. 975 */ 976 SHMIF_RHINT_TPACK = 128 977 }; 978 979 struct arcan_shmif_page; 980 981 #ifndef ARCAN_SHMIF_HIDEPAGE 982 struct arcan_shmif_page { 983 /* 984 * These will be statically set to the ASHMIF_VERSION_MAJOR, ASHMIF_VERSION_MAJOR 985 * defines, a mismatch will cause the integrity_check to fail and both sides 986 * may decide to terminate. Thus, they also act as a header guard. A more 987 * precise guard value is found in [cookie]. 988 */ 989 int8_t major; 990 int8_t minor; 991 992 /* [FSRV-REQ, ARCAN-ACK, ATOMIC-NOCARE] 993 * Will be checked periodically and before transfers. When set, FSRV should 994 * treat other contents of page as UNDEFINED until acknowledged. 995 * RELATES-TO: width, height */ 996 volatile int8_t resized; 997 998 /* [FSRV-SET or ARCAN-SET, ATOMIC-NOCARE] 999 * Dead man's switch, set to 1 when a connection is active and released 1000 * if parent or child detects an anomaly that would indicate misuse or 1001 * data corruption. This will trigger guard-threads and similar structures 1002 * to release semaphores and attempt to shut down gracefully. 1003 */ 1004 volatile uint8_t dms; 1005 1006 /* [FSRV-SET, ARCAN-ACK(fl+sem)] 1007 * Set whenever a buffer is ready to be synchronized. 1008 * [vready-1] indicates the buffer index of the last set frame, while 1009 * vpending are the number of frames with contents that hasn't been 1010 * synchronzied. 1011 * [aready-1] indicates the starting index for buffers that have not 1012 * been synchronized, ring-buffer wrapping the bits that are set. 1013 */ 1014 volatile atomic_uint aready; 1015 volatile atomic_uint apending; 1016 volatile atomic_uint vready; 1017 volatile atomic_uint vpending; 1018 1019 /* abufused contains the number of bytes consumed in every slot */ 1020 volatile _Atomic uint_least16_t abufused[ARCAN_SHMIF_ABUFC_LIM]; 1021 1022 /* 1023 * Presentation hints, manipulate field in _cont, not here. 1024 */ 1025 volatile _Atomic uint_least8_t hints; 1026 1027 /* 1028 * see dirty- field in _cont, manipulate there, not here. 1029 */ 1030 volatile _Atomic struct arcan_shmif_region dirty; 1031 volatile _Atomic int16_t scroll_dx; 1032 volatile _Atomic int16_t scroll_dy; 1033 1034 /* [FSRV-SET] 1035 * Unique (or 0) segment identifier. Prvodes a local namespace for specifying 1036 * relative properties (e.g. VIEWPORT command from popups) between subsegments, 1037 * is always 0 for subsegments. 1038 */ 1039 uint32_t segment_token; 1040 1041 /* [ARCAN-SET] 1042 * Calculated once when initializing segment, and verified periodically from 1043 * both [FSRV] and [ARCAN]. Any deviation MAY have the [dms] be pulled. 1044 */ 1045 uint64_t cookie; 1046 1047 /* 1048 * [ARCAN-SET (parent), FSRV-SET (child)] 1049 * Uses the event model provded in shmif/arcan_event and tightly couples 1050 * structure / event layout which introduces a number of implementation defined 1051 * constraints, making this interface a poor choice for a protocol. 1052 */ 1053 struct { 1054 struct arcan_event evqueue[ PP_QUEUE_SZ ]; 1055 uint8_t front, back; 1056 } childevq, parentevq; 1057 1058 /* [ARCAN-SET (parent), FSRV-CHECK] 1059 * Arcan mandates segment size, will only change during resize negotiation. 1060 * If this differs from the previous known size (tracked inside shmif_cont), 1061 * the segment should be remapped. 1062 * 1063 * Not all operations will lead to a change in segment_size, OVERCOMMIT 1064 * builds has its size fixed, and parent may heuristically determine if 1065 * a shrinking- operation is worth the overhead or not. 1066 */ 1067 volatile uint32_t segment_size; 1068 1069 /* 1070 * [FSRV-SET (resize), ARCAN-ACK] 1071 * Current video output dimensions. If these deviate from the agreed upon 1072 * dimensions (i.e. change w,h and set the resized flag to !0) ARCAN will 1073 * simply ignore the data presented. 1074 */ 1075 volatile _Atomic uint_least16_t w, h; 1076 1077 /* 1078 * [ARCAN-SET, FSRV-SET] 1079 * Client acknowledges this in resize requests where cell alignment / 1080 * dimensions are needed, undefined unless in TPACK hint state. This should 1081 * be a value that can be calculated from fonthint etc. but that is asynch. 1082 */ 1083 volatile _Atomic uint_least8_t rows, cols; 1084 1085 /* 1086 * [FSRV-SET (aready signal), ARCAN-ACK] 1087 * Video buffers are planar transfers of a pre-determined size. Audio, 1088 * on the other hand, can be appended and consumed by the side that currently 1089 * holds the synch- semaphore. Note that if the transfered amount for each 1090 * synch is less than the negotiated abufsize, audio artifacts may be heard. 1091 */ 1092 volatile _Atomic uint_least16_t abufsize; 1093 1094 /* 1095 * [FSRV-SET (resize), ARCAN-ACK] 1096 * Desired buffer samplerate, 0 maps back to ARCAN_SHMIF_SAMPLERATE that 1097 * should be tuned for the underlying audio system at build-time. 1098 */ 1099 volatile _Atomic uint_least32_t audiorate; 1100 1101 /* 1102 * [FSRV-OR-ARCAN-SET] 1103 * Timestamp hint for presentation of a video frame (using synch-to-video) 1104 * Also used as negotiation for RHINT_TOKEN_AUTH used by shmifext_setup 1105 * internally. 1106 */ 1107 volatile _Atomic uint_least64_t vpts; 1108 1109 /* 1110 * [ARCAN-SET] 1111 * Set during segment initalization, provides some identifier to determine 1112 * if the parent process is still alive (used internally by GUARDTHREAD). 1113 * Can also be updated in relation to a RESET event. 1114 */ 1115 process_handle parent; 1116 1117 /* 1118 * [FSRV-OR-ARCAN-SET] 1119 * Possibly changed during an extended resize 1120 * Set once during initiaization, and will be zero/NULL for most connection. 1121 * The intended use is to provide a mechanism for further engine segmentation 1122 * and for more complex data sources. A prime example is the hmdsupport tool. 1123 */ 1124 volatile _Atomic uint32_t apad, apad_type; 1125 1126 /* 1127 * [FSRV-SET-ON-DMS/EXIT] 1128 * Short user-readable utf8- message to indicate a possible reason for a 1129 * crash, failure or otherwise unexpected termination 1130 */ 1131 volatile char last_words[32]; 1132 1133 /* 1134 * Begin of apad/apad_type negotiated block. For the actual calculations here, 1135 * look inside engine/arcan_frameserver.c for setproto, and in platform for 1136 * the shmemop.c implementation. 1137 */ 1138 _Alignas(16) uintptr_t adata[]; 1139 }; 1140 #endif 1141 #endif 1142