1/* 2 * Copyright © 2013 Keith Packard 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of the copyright holders not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. The copyright holders make no representations 11 * about the suitability of this software for any purpose. It is provided "as 12 * is" without express or implied warranty. 13 * 14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 * OF THIS SOFTWARE. 21 */ 22 23#ifndef _PRESENT_PRIV_H_ 24#define _PRESENT_PRIV_H_ 25 26#include "dix-config.h" 27#include <X11/X.h> 28#include "scrnintstr.h" 29#include "misc.h" 30#include "list.h" 31#include "windowstr.h" 32#include "dixstruct.h" 33#include "present.h" 34#include <syncsdk.h> 35#include <syncsrv.h> 36#include <xfixes.h> 37#include <randrstr.h> 38#include <inttypes.h> 39 40#if 0 41#define DebugPresent(x) ErrorF x 42#else 43#define DebugPresent(x) 44#endif 45 46/* XXX this belongs in presentproto */ 47#ifndef PresentWindowDestroyed 48#define PresentWindowDestroyed (1 << 0) 49#endif 50 51extern int present_request; 52 53extern DevPrivateKeyRec present_screen_private_key; 54 55typedef struct present_fence *present_fence_ptr; 56 57typedef struct present_notify present_notify_rec, *present_notify_ptr; 58 59struct present_notify { 60 struct xorg_list window_list; 61 WindowPtr window; 62 CARD32 serial; 63}; 64 65struct present_vblank { 66 struct xorg_list window_list; 67 struct xorg_list event_queue; 68 ScreenPtr screen; 69 WindowPtr window; 70 PixmapPtr pixmap; 71 RegionPtr valid; 72 RegionPtr update; 73 RRCrtcPtr crtc; 74 uint32_t serial; 75 int16_t x_off; 76 int16_t y_off; 77 CARD16 kind; 78 uint64_t event_id; 79 uint64_t target_msc; /* target MSC when present should complete */ 80 uint64_t exec_msc; /* MSC at which present can be executed */ 81 uint64_t msc_offset; 82 present_fence_ptr idle_fence; 83 present_fence_ptr wait_fence; 84 present_notify_ptr notifies; 85 int num_notifies; 86 Bool queued; /* on present_exec_queue */ 87 Bool flip; /* planning on using flip */ 88 Bool flip_ready; /* wants to flip, but waiting for previous flip or unflip */ 89 Bool sync_flip; /* do flip synchronous to vblank */ 90 Bool abort_flip; /* aborting this flip */ 91 PresentFlipReason reason; /* reason for which flip is not possible */ 92 Bool has_suboptimal; /* whether client can support SuboptimalCopy mode */ 93}; 94 95typedef struct present_screen_priv present_screen_priv_rec, *present_screen_priv_ptr; 96typedef struct present_window_priv present_window_priv_rec, *present_window_priv_ptr; 97 98/* 99 * Mode hooks 100 */ 101typedef uint32_t (*present_priv_query_capabilities_ptr)(present_screen_priv_ptr screen_priv); 102typedef RRCrtcPtr (*present_priv_get_crtc_ptr)(present_screen_priv_ptr screen_priv, 103 WindowPtr window); 104 105typedef Bool (*present_priv_check_flip_ptr)(RRCrtcPtr crtc, 106 WindowPtr window, 107 PixmapPtr pixmap, 108 Bool sync_flip, 109 RegionPtr valid, 110 int16_t x_off, 111 int16_t y_off, 112 PresentFlipReason *reason); 113typedef void (*present_priv_check_flip_window_ptr)(WindowPtr window); 114typedef Bool (*present_priv_can_window_flip_ptr)(WindowPtr window); 115typedef void (*present_priv_clear_window_flip_ptr)(WindowPtr window); 116 117typedef int (*present_priv_pixmap_ptr)(WindowPtr window, 118 PixmapPtr pixmap, 119 CARD32 serial, 120 RegionPtr valid, 121 RegionPtr update, 122 int16_t x_off, 123 int16_t y_off, 124 RRCrtcPtr target_crtc, 125 SyncFence *wait_fence, 126 SyncFence *idle_fence, 127 uint32_t options, 128 uint64_t window_msc, 129 uint64_t divisor, 130 uint64_t remainder, 131 present_notify_ptr notifies, 132 int num_notifies); 133 134typedef int (*present_priv_queue_vblank_ptr)(ScreenPtr screen, 135 WindowPtr window, 136 RRCrtcPtr crtc, 137 uint64_t event_id, 138 uint64_t msc); 139typedef void (*present_priv_flush_ptr)(WindowPtr window); 140typedef void (*present_priv_re_execute_ptr)(present_vblank_ptr vblank); 141 142typedef void (*present_priv_abort_vblank_ptr)(ScreenPtr screen, 143 WindowPtr window, 144 RRCrtcPtr crtc, 145 uint64_t event_id, 146 uint64_t msc); 147typedef void (*present_priv_flip_destroy_ptr)(ScreenPtr screen); 148 149struct present_screen_priv { 150 CloseScreenProcPtr CloseScreen; 151 ConfigNotifyProcPtr ConfigNotify; 152 DestroyWindowProcPtr DestroyWindow; 153 ClipNotifyProcPtr ClipNotify; 154 155 present_vblank_ptr flip_pending; 156 uint64_t unflip_event_id; 157 158 uint32_t fake_interval; 159 160 /* Currently active flipped pixmap and fence */ 161 RRCrtcPtr flip_crtc; 162 WindowPtr flip_window; 163 uint32_t flip_serial; 164 PixmapPtr flip_pixmap; 165 present_fence_ptr flip_idle_fence; 166 Bool flip_sync; 167 168 present_screen_info_ptr info; 169 170 /* Mode hooks */ 171 present_priv_query_capabilities_ptr query_capabilities; 172 present_priv_get_crtc_ptr get_crtc; 173 174 present_priv_check_flip_ptr check_flip; 175 present_priv_check_flip_window_ptr check_flip_window; 176 present_priv_can_window_flip_ptr can_window_flip; 177 present_priv_clear_window_flip_ptr clear_window_flip; 178 179 present_priv_pixmap_ptr present_pixmap; 180 181 present_priv_queue_vblank_ptr queue_vblank; 182 present_priv_flush_ptr flush; 183 present_priv_re_execute_ptr re_execute; 184 185 present_priv_abort_vblank_ptr abort_vblank; 186 present_priv_flip_destroy_ptr flip_destroy; 187}; 188 189#define wrap(priv,real,mem,func) {\ 190 priv->mem = real->mem; \ 191 real->mem = func; \ 192} 193 194#define unwrap(priv,real,mem) {\ 195 real->mem = priv->mem; \ 196} 197 198static inline present_screen_priv_ptr 199present_screen_priv(ScreenPtr screen) 200{ 201 return (present_screen_priv_ptr)dixLookupPrivate(&(screen)->devPrivates, &present_screen_private_key); 202} 203 204/* 205 * Each window has a list of clients and event masks 206 */ 207typedef struct present_event *present_event_ptr; 208 209typedef struct present_event { 210 present_event_ptr next; 211 ClientPtr client; 212 WindowPtr window; 213 XID id; 214 int mask; 215} present_event_rec; 216 217struct present_window_priv { 218 WindowPtr window; 219 present_event_ptr events; 220 RRCrtcPtr crtc; /* Last reported CRTC from get_ust_msc */ 221 uint64_t msc_offset; 222 uint64_t msc; /* Last reported MSC from the current crtc */ 223 struct xorg_list vblank; 224 struct xorg_list notifies; 225}; 226 227#define PresentCrtcNeverSet ((RRCrtcPtr) 1) 228 229extern DevPrivateKeyRec present_window_private_key; 230 231static inline present_window_priv_ptr 232present_window_priv(WindowPtr window) 233{ 234 return (present_window_priv_ptr)dixGetPrivate(&(window)->devPrivates, &present_window_private_key); 235} 236 237present_window_priv_ptr 238present_get_window_priv(WindowPtr window, Bool create); 239 240/* 241 * Returns: 242 * TRUE if the first MSC value is after the second one 243 * FALSE if the first MSC value is equal to or before the second one 244 */ 245static inline Bool 246msc_is_after(uint64_t test, uint64_t reference) 247{ 248 return (int64_t)(test - reference) > 0; 249} 250 251/* 252 * present.c 253 */ 254uint32_t 255present_query_capabilities(RRCrtcPtr crtc); 256 257RRCrtcPtr 258present_get_crtc(WindowPtr window); 259 260void 261present_copy_region(DrawablePtr drawable, 262 PixmapPtr pixmap, 263 RegionPtr update, 264 int16_t x_off, 265 int16_t y_off); 266 267void 268present_pixmap_idle(PixmapPtr pixmap, WindowPtr window, CARD32 serial, struct present_fence *present_fence); 269 270void 271present_set_tree_pixmap(WindowPtr window, 272 PixmapPtr expected, 273 PixmapPtr pixmap); 274 275uint64_t 276present_get_target_msc(uint64_t target_msc_arg, 277 uint64_t crtc_msc, 278 uint64_t divisor, 279 uint64_t remainder, 280 uint32_t options); 281 282int 283present_pixmap(WindowPtr window, 284 PixmapPtr pixmap, 285 CARD32 serial, 286 RegionPtr valid, 287 RegionPtr update, 288 int16_t x_off, 289 int16_t y_off, 290 RRCrtcPtr target_crtc, 291 SyncFence *wait_fence, 292 SyncFence *idle_fence, 293 uint32_t options, 294 uint64_t target_msc, 295 uint64_t divisor, 296 uint64_t remainder, 297 present_notify_ptr notifies, 298 int num_notifies); 299 300int 301present_notify_msc(WindowPtr window, 302 CARD32 serial, 303 uint64_t target_msc, 304 uint64_t divisor, 305 uint64_t remainder); 306 307/* 308 * present_event.c 309 */ 310 311void 312present_free_events(WindowPtr window); 313 314void 315present_send_config_notify(WindowPtr window, int x, int y, int w, int h, int bw, WindowPtr sibling, CARD32 flags); 316 317void 318present_send_complete_notify(WindowPtr window, CARD8 kind, CARD8 mode, CARD32 serial, uint64_t ust, uint64_t msc); 319 320void 321present_send_idle_notify(WindowPtr window, CARD32 serial, PixmapPtr pixmap, present_fence_ptr idle_fence); 322 323int 324present_select_input(ClientPtr client, 325 CARD32 eid, 326 WindowPtr window, 327 CARD32 event_mask); 328 329Bool 330present_event_init(void); 331 332/* 333 * present_execute.c 334 */ 335Bool 336present_execute_wait(present_vblank_ptr vblank, uint64_t crtc_msc); 337 338void 339present_execute_copy(present_vblank_ptr vblank, uint64_t crtc_msc); 340 341void 342present_execute_post(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc); 343 344/* 345 * present_fake.c 346 */ 347int 348present_fake_get_ust_msc(ScreenPtr screen, uint64_t *ust, uint64_t *msc); 349 350int 351present_fake_queue_vblank(ScreenPtr screen, uint64_t event_id, uint64_t msc); 352 353void 354present_fake_abort_vblank(ScreenPtr screen, uint64_t event_id, uint64_t msc); 355 356void 357present_fake_screen_init(ScreenPtr screen); 358 359void 360present_fake_queue_init(void); 361 362/* 363 * present_fence.c 364 */ 365struct present_fence * 366present_fence_create(SyncFence *sync_fence); 367 368void 369present_fence_destroy(struct present_fence *present_fence); 370 371void 372present_fence_set_triggered(struct present_fence *present_fence); 373 374Bool 375present_fence_check_triggered(struct present_fence *present_fence); 376 377void 378present_fence_set_callback(struct present_fence *present_fence, 379 void (*callback)(void *param), 380 void *param); 381 382XID 383present_fence_id(struct present_fence *present_fence); 384 385/* 386 * present_notify.c 387 */ 388void 389present_clear_window_notifies(WindowPtr window); 390 391void 392present_free_window_notify(present_notify_ptr notify); 393 394int 395present_add_window_notify(present_notify_ptr notify); 396 397int 398present_create_notifies(ClientPtr client, int num_notifies, xPresentNotify *x_notifies, present_notify_ptr *p_notifies); 399 400void 401present_destroy_notifies(present_notify_ptr notifies, int num_notifies); 402 403/* 404 * present_redirect.c 405 */ 406 407WindowPtr 408present_redirect(ClientPtr client, WindowPtr target); 409 410/* 411 * present_request.c 412 */ 413int 414proc_present_dispatch(ClientPtr client); 415 416int 417sproc_present_dispatch(ClientPtr client); 418 419/* 420 * present_scmd.c 421 */ 422void 423present_abort_vblank(ScreenPtr screen, RRCrtcPtr crtc, uint64_t event_id, uint64_t msc); 424 425void 426present_flip_destroy(ScreenPtr screen); 427 428void 429present_restore_screen_pixmap(ScreenPtr screen); 430 431void 432present_set_abort_flip(ScreenPtr screen); 433 434Bool 435present_init(void); 436 437void 438present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv); 439 440/* 441 * present_screen.c 442 */ 443Bool 444present_screen_register_priv_keys(void); 445 446present_screen_priv_ptr 447present_screen_priv_init(ScreenPtr screen); 448 449/* 450 * present_vblank.c 451 */ 452void 453present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_t ust, uint64_t crtc_msc); 454 455Bool 456present_vblank_init(present_vblank_ptr vblank, 457 WindowPtr window, 458 PixmapPtr pixmap, 459 CARD32 serial, 460 RegionPtr valid, 461 RegionPtr update, 462 int16_t x_off, 463 int16_t y_off, 464 RRCrtcPtr target_crtc, 465 SyncFence *wait_fence, 466 SyncFence *idle_fence, 467 uint32_t options, 468 const uint32_t capabilities, 469 present_notify_ptr notifies, 470 int num_notifies, 471 uint64_t target_msc, 472 uint64_t crtc_msc); 473 474present_vblank_ptr 475present_vblank_create(WindowPtr window, 476 PixmapPtr pixmap, 477 CARD32 serial, 478 RegionPtr valid, 479 RegionPtr update, 480 int16_t x_off, 481 int16_t y_off, 482 RRCrtcPtr target_crtc, 483 SyncFence *wait_fence, 484 SyncFence *idle_fence, 485 uint32_t options, 486 const uint32_t capabilities, 487 present_notify_ptr notifies, 488 int num_notifies, 489 uint64_t target_msc, 490 uint64_t crtc_msc); 491 492void 493present_vblank_scrap(present_vblank_ptr vblank); 494 495void 496present_vblank_destroy(present_vblank_ptr vblank); 497 498#endif /* _PRESENT_PRIV_H_ */ 499