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 51 extern int present_request; 52 53 extern DevPrivateKeyRec present_screen_private_key; 54 55 typedef struct present_fence *present_fence_ptr; 56 57 typedef struct present_notify present_notify_rec, *present_notify_ptr; 58 59 struct present_notify { 60 struct xorg_list window_list; 61 WindowPtr window; 62 CARD32 serial; 63 }; 64 65 struct 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 95 typedef struct present_screen_priv present_screen_priv_rec, *present_screen_priv_ptr; 96 typedef struct present_window_priv present_window_priv_rec, *present_window_priv_ptr; 97 98 /* 99 * Mode hooks 100 */ 101 typedef uint32_t (*present_priv_query_capabilities_ptr)(present_screen_priv_ptr screen_priv); 102 typedef RRCrtcPtr (*present_priv_get_crtc_ptr)(present_screen_priv_ptr screen_priv, 103 WindowPtr window); 104 105 typedef 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); 113 typedef void (*present_priv_check_flip_window_ptr)(WindowPtr window); 114 typedef Bool (*present_priv_can_window_flip_ptr)(WindowPtr window); 115 typedef void (*present_priv_clear_window_flip_ptr)(WindowPtr window); 116 117 typedef 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 134 typedef int (*present_priv_queue_vblank_ptr)(ScreenPtr screen, 135 WindowPtr window, 136 RRCrtcPtr crtc, 137 uint64_t event_id, 138 uint64_t msc); 139 typedef void (*present_priv_flush_ptr)(WindowPtr window); 140 typedef void (*present_priv_re_execute_ptr)(present_vblank_ptr vblank); 141 142 typedef void (*present_priv_abort_vblank_ptr)(ScreenPtr screen, 143 WindowPtr window, 144 RRCrtcPtr crtc, 145 uint64_t event_id, 146 uint64_t msc); 147 typedef void (*present_priv_flip_destroy_ptr)(ScreenPtr screen); 148 149 struct 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 198 static inline present_screen_priv_ptr 199 present_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 */ 207 typedef struct present_event *present_event_ptr; 208 209 typedef 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 217 struct 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 229 extern DevPrivateKeyRec present_window_private_key; 230 231 static inline present_window_priv_ptr 232 present_window_priv(WindowPtr window) 233 { 234 return (present_window_priv_ptr)dixGetPrivate(&(window)->devPrivates, &present_window_private_key); 235 } 236 237 present_window_priv_ptr 238 present_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 */ 245 static inline Bool 246 msc_is_after(uint64_t test, uint64_t reference) 247 { 248 return (int64_t)(test - reference) > 0; 249 } 250 251 /* 252 * present.c 253 */ 254 uint32_t 255 present_query_capabilities(RRCrtcPtr crtc); 256 257 RRCrtcPtr 258 present_get_crtc(WindowPtr window); 259 260 void 261 present_copy_region(DrawablePtr drawable, 262 PixmapPtr pixmap, 263 RegionPtr update, 264 int16_t x_off, 265 int16_t y_off); 266 267 void 268 present_pixmap_idle(PixmapPtr pixmap, WindowPtr window, CARD32 serial, struct present_fence *present_fence); 269 270 void 271 present_set_tree_pixmap(WindowPtr window, 272 PixmapPtr expected, 273 PixmapPtr pixmap); 274 275 uint64_t 276 present_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 282 int 283 present_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 300 int 301 present_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 311 void 312 present_free_events(WindowPtr window); 313 314 void 315 present_send_config_notify(WindowPtr window, int x, int y, int w, int h, int bw, WindowPtr sibling, CARD32 flags); 316 317 void 318 present_send_complete_notify(WindowPtr window, CARD8 kind, CARD8 mode, CARD32 serial, uint64_t ust, uint64_t msc); 319 320 void 321 present_send_idle_notify(WindowPtr window, CARD32 serial, PixmapPtr pixmap, present_fence_ptr idle_fence); 322 323 int 324 present_select_input(ClientPtr client, 325 CARD32 eid, 326 WindowPtr window, 327 CARD32 event_mask); 328 329 Bool 330 present_event_init(void); 331 332 /* 333 * present_execute.c 334 */ 335 Bool 336 present_execute_wait(present_vblank_ptr vblank, uint64_t crtc_msc); 337 338 void 339 present_execute_copy(present_vblank_ptr vblank, uint64_t crtc_msc); 340 341 void 342 present_execute_post(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc); 343 344 /* 345 * present_fake.c 346 */ 347 int 348 present_fake_get_ust_msc(ScreenPtr screen, uint64_t *ust, uint64_t *msc); 349 350 int 351 present_fake_queue_vblank(ScreenPtr screen, uint64_t event_id, uint64_t msc); 352 353 void 354 present_fake_abort_vblank(ScreenPtr screen, uint64_t event_id, uint64_t msc); 355 356 void 357 present_fake_screen_init(ScreenPtr screen); 358 359 void 360 present_fake_queue_init(void); 361 362 /* 363 * present_fence.c 364 */ 365 struct present_fence * 366 present_fence_create(SyncFence *sync_fence); 367 368 void 369 present_fence_destroy(struct present_fence *present_fence); 370 371 void 372 present_fence_set_triggered(struct present_fence *present_fence); 373 374 Bool 375 present_fence_check_triggered(struct present_fence *present_fence); 376 377 void 378 present_fence_set_callback(struct present_fence *present_fence, 379 void (*callback)(void *param), 380 void *param); 381 382 XID 383 present_fence_id(struct present_fence *present_fence); 384 385 /* 386 * present_notify.c 387 */ 388 void 389 present_clear_window_notifies(WindowPtr window); 390 391 void 392 present_free_window_notify(present_notify_ptr notify); 393 394 int 395 present_add_window_notify(present_notify_ptr notify); 396 397 int 398 present_create_notifies(ClientPtr client, int num_notifies, xPresentNotify *x_notifies, present_notify_ptr *p_notifies); 399 400 void 401 present_destroy_notifies(present_notify_ptr notifies, int num_notifies); 402 403 /* 404 * present_redirect.c 405 */ 406 407 WindowPtr 408 present_redirect(ClientPtr client, WindowPtr target); 409 410 /* 411 * present_request.c 412 */ 413 int 414 proc_present_dispatch(ClientPtr client); 415 416 int 417 sproc_present_dispatch(ClientPtr client); 418 419 /* 420 * present_scmd.c 421 */ 422 void 423 present_abort_vblank(ScreenPtr screen, RRCrtcPtr crtc, uint64_t event_id, uint64_t msc); 424 425 void 426 present_flip_destroy(ScreenPtr screen); 427 428 void 429 present_restore_screen_pixmap(ScreenPtr screen); 430 431 void 432 present_set_abort_flip(ScreenPtr screen); 433 434 Bool 435 present_init(void); 436 437 void 438 present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv); 439 440 /* 441 * present_screen.c 442 */ 443 Bool 444 present_screen_register_priv_keys(void); 445 446 present_screen_priv_ptr 447 present_screen_priv_init(ScreenPtr screen); 448 449 /* 450 * present_vblank.c 451 */ 452 void 453 present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_t ust, uint64_t crtc_msc); 454 455 Bool 456 present_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 474 present_vblank_ptr 475 present_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 492 void 493 present_vblank_scrap(present_vblank_ptr vblank); 494 495 void 496 present_vblank_destroy(present_vblank_ptr vblank); 497 498 #endif /* _PRESENT_PRIV_H_ */ 499