11b5d61b8Smrg/* 21b5d61b8Smrg * Copyright © 2013 Keith Packard 31b5d61b8Smrg * 41b5d61b8Smrg * Permission to use, copy, modify, distribute, and sell this software and its 51b5d61b8Smrg * documentation for any purpose is hereby granted without fee, provided that 61b5d61b8Smrg * the above copyright notice appear in all copies and that both that copyright 71b5d61b8Smrg * notice and this permission notice appear in supporting documentation, and 81b5d61b8Smrg * that the name of the copyright holders not be used in advertising or 91b5d61b8Smrg * publicity pertaining to distribution of the software without specific, 101b5d61b8Smrg * written prior permission. The copyright holders make no representations 111b5d61b8Smrg * about the suitability of this software for any purpose. It is provided "as 121b5d61b8Smrg * is" without express or implied warranty. 131b5d61b8Smrg * 141b5d61b8Smrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 151b5d61b8Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 161b5d61b8Smrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 171b5d61b8Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 181b5d61b8Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 191b5d61b8Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 201b5d61b8Smrg * OF THIS SOFTWARE. 211b5d61b8Smrg */ 221b5d61b8Smrg 231b5d61b8Smrg#include "present_priv.h" 241b5d61b8Smrg 251b5d61b8Smrg/* 261b5d61b8Smrg * Called when the wait fence is triggered; just gets the current msc/ust and 271b5d61b8Smrg * calls the proper execute again. That will re-check the fence and pend the 281b5d61b8Smrg * request again if it's still not actually ready 291b5d61b8Smrg */ 301b5d61b8Smrgstatic void 311b5d61b8Smrgpresent_wait_fence_triggered(void *param) 321b5d61b8Smrg{ 331b5d61b8Smrg present_vblank_ptr vblank = param; 341b5d61b8Smrg ScreenPtr screen = vblank->screen; 351b5d61b8Smrg present_screen_priv_ptr screen_priv = present_screen_priv(screen); 361b5d61b8Smrg 371b5d61b8Smrg screen_priv->re_execute(vblank); 381b5d61b8Smrg} 391b5d61b8Smrg 401b5d61b8SmrgBool 411b5d61b8Smrgpresent_execute_wait(present_vblank_ptr vblank, uint64_t crtc_msc) 421b5d61b8Smrg{ 431b5d61b8Smrg WindowPtr window = vblank->window; 441b5d61b8Smrg ScreenPtr screen = window->drawable.pScreen; 451b5d61b8Smrg present_screen_priv_ptr screen_priv = present_screen_priv(screen); 461b5d61b8Smrg 475a7dfde8Smrg /* We may have to requeue for the next MSC if check_flip_window prevented 485a7dfde8Smrg * using a flip. 495a7dfde8Smrg */ 505a7dfde8Smrg if (vblank->exec_msc == crtc_msc + 1 && 515a7dfde8Smrg screen_priv->queue_vblank(screen, window, vblank->crtc, vblank->event_id, 525a7dfde8Smrg vblank->exec_msc) == Success) 535a7dfde8Smrg return TRUE; 541b5d61b8Smrg 551b5d61b8Smrg if (vblank->wait_fence) { 561b5d61b8Smrg if (!present_fence_check_triggered(vblank->wait_fence)) { 571b5d61b8Smrg present_fence_set_callback(vblank->wait_fence, present_wait_fence_triggered, vblank); 581b5d61b8Smrg return TRUE; 591b5d61b8Smrg } 601b5d61b8Smrg } 611b5d61b8Smrg return FALSE; 621b5d61b8Smrg} 631b5d61b8Smrg 641b5d61b8Smrgvoid 651b5d61b8Smrgpresent_execute_copy(present_vblank_ptr vblank, uint64_t crtc_msc) 661b5d61b8Smrg{ 671b5d61b8Smrg WindowPtr window = vblank->window; 681b5d61b8Smrg ScreenPtr screen = window->drawable.pScreen; 691b5d61b8Smrg present_screen_priv_ptr screen_priv = present_screen_priv(screen); 701b5d61b8Smrg 715a7dfde8Smrg /* If present_flip failed, we may have to requeue for the next MSC */ 725a7dfde8Smrg if (vblank->exec_msc == crtc_msc + 1 && 731b5d61b8Smrg Success == screen_priv->queue_vblank(screen, 741b5d61b8Smrg window, 751b5d61b8Smrg vblank->crtc, 761b5d61b8Smrg vblank->event_id, 775a7dfde8Smrg vblank->exec_msc)) { 781b5d61b8Smrg vblank->queued = TRUE; 791b5d61b8Smrg return; 801b5d61b8Smrg } 811b5d61b8Smrg 821b5d61b8Smrg present_copy_region(&window->drawable, vblank->pixmap, vblank->update, vblank->x_off, vblank->y_off); 831b5d61b8Smrg 841b5d61b8Smrg /* present_copy_region sticks the region into a scratch GC, 851b5d61b8Smrg * which is then freed, freeing the region 861b5d61b8Smrg */ 871b5d61b8Smrg vblank->update = NULL; 881b5d61b8Smrg screen_priv->flush(window); 891b5d61b8Smrg 901b5d61b8Smrg present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence); 911b5d61b8Smrg} 921b5d61b8Smrg 931b5d61b8Smrgvoid 941b5d61b8Smrgpresent_execute_post(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) 951b5d61b8Smrg{ 961b5d61b8Smrg uint8_t mode; 971b5d61b8Smrg 981b5d61b8Smrg /* Compute correct CompleteMode 991b5d61b8Smrg */ 1001b5d61b8Smrg if (vblank->kind == PresentCompleteKindPixmap) { 1011b5d61b8Smrg if (vblank->pixmap && vblank->window) { 1021b5d61b8Smrg if (vblank->has_suboptimal && vblank->reason == PRESENT_FLIP_REASON_BUFFER_FORMAT) 1031b5d61b8Smrg mode = PresentCompleteModeSuboptimalCopy; 1041b5d61b8Smrg else 1051b5d61b8Smrg mode = PresentCompleteModeCopy; 1061b5d61b8Smrg } else { 1071b5d61b8Smrg mode = PresentCompleteModeSkip; 1081b5d61b8Smrg } 1091b5d61b8Smrg } 1101b5d61b8Smrg else 1111b5d61b8Smrg mode = PresentCompleteModeCopy; 1121b5d61b8Smrg 1131b5d61b8Smrg present_vblank_notify(vblank, vblank->kind, mode, ust, crtc_msc); 1141b5d61b8Smrg present_vblank_destroy(vblank); 1151b5d61b8Smrg} 116