present_execute.c revision 1b5d61b8
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#ifdef HAVE_XORG_CONFIG_H 241b5d61b8Smrg#include <xorg-config.h> 251b5d61b8Smrg#endif 261b5d61b8Smrg 271b5d61b8Smrg#include "present_priv.h" 281b5d61b8Smrg 291b5d61b8Smrg/* 301b5d61b8Smrg * Called when the wait fence is triggered; just gets the current msc/ust and 311b5d61b8Smrg * calls the proper execute again. That will re-check the fence and pend the 321b5d61b8Smrg * request again if it's still not actually ready 331b5d61b8Smrg */ 341b5d61b8Smrgstatic void 351b5d61b8Smrgpresent_wait_fence_triggered(void *param) 361b5d61b8Smrg{ 371b5d61b8Smrg present_vblank_ptr vblank = param; 381b5d61b8Smrg ScreenPtr screen = vblank->screen; 391b5d61b8Smrg present_screen_priv_ptr screen_priv = present_screen_priv(screen); 401b5d61b8Smrg 411b5d61b8Smrg screen_priv->re_execute(vblank); 421b5d61b8Smrg} 431b5d61b8Smrg 441b5d61b8SmrgBool 451b5d61b8Smrgpresent_execute_wait(present_vblank_ptr vblank, uint64_t crtc_msc) 461b5d61b8Smrg{ 471b5d61b8Smrg WindowPtr window = vblank->window; 481b5d61b8Smrg ScreenPtr screen = window->drawable.pScreen; 491b5d61b8Smrg present_screen_priv_ptr screen_priv = present_screen_priv(screen); 501b5d61b8Smrg 511b5d61b8Smrg if (vblank->requeue) { 521b5d61b8Smrg vblank->requeue = FALSE; 531b5d61b8Smrg if (msc_is_after(vblank->target_msc, crtc_msc) && 541b5d61b8Smrg Success == screen_priv->queue_vblank(screen, 551b5d61b8Smrg window, 561b5d61b8Smrg vblank->crtc, 571b5d61b8Smrg vblank->event_id, 581b5d61b8Smrg vblank->target_msc)) 591b5d61b8Smrg return TRUE; 601b5d61b8Smrg } 611b5d61b8Smrg 621b5d61b8Smrg if (vblank->wait_fence) { 631b5d61b8Smrg if (!present_fence_check_triggered(vblank->wait_fence)) { 641b5d61b8Smrg present_fence_set_callback(vblank->wait_fence, present_wait_fence_triggered, vblank); 651b5d61b8Smrg return TRUE; 661b5d61b8Smrg } 671b5d61b8Smrg } 681b5d61b8Smrg return FALSE; 691b5d61b8Smrg} 701b5d61b8Smrg 711b5d61b8Smrgvoid 721b5d61b8Smrgpresent_execute_copy(present_vblank_ptr vblank, uint64_t crtc_msc) 731b5d61b8Smrg{ 741b5d61b8Smrg WindowPtr window = vblank->window; 751b5d61b8Smrg ScreenPtr screen = window->drawable.pScreen; 761b5d61b8Smrg present_screen_priv_ptr screen_priv = present_screen_priv(screen); 771b5d61b8Smrg 781b5d61b8Smrg /* If present_flip failed, we may have to requeue for the target MSC */ 791b5d61b8Smrg if (vblank->target_msc == crtc_msc + 1 && 801b5d61b8Smrg Success == screen_priv->queue_vblank(screen, 811b5d61b8Smrg window, 821b5d61b8Smrg vblank->crtc, 831b5d61b8Smrg vblank->event_id, 841b5d61b8Smrg vblank->target_msc)) { 851b5d61b8Smrg vblank->queued = TRUE; 861b5d61b8Smrg return; 871b5d61b8Smrg } 881b5d61b8Smrg 891b5d61b8Smrg present_copy_region(&window->drawable, vblank->pixmap, vblank->update, vblank->x_off, vblank->y_off); 901b5d61b8Smrg 911b5d61b8Smrg /* present_copy_region sticks the region into a scratch GC, 921b5d61b8Smrg * which is then freed, freeing the region 931b5d61b8Smrg */ 941b5d61b8Smrg vblank->update = NULL; 951b5d61b8Smrg screen_priv->flush(window); 961b5d61b8Smrg 971b5d61b8Smrg present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence); 981b5d61b8Smrg} 991b5d61b8Smrg 1001b5d61b8Smrgvoid 1011b5d61b8Smrgpresent_execute_post(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) 1021b5d61b8Smrg{ 1031b5d61b8Smrg uint8_t mode; 1041b5d61b8Smrg 1051b5d61b8Smrg /* Compute correct CompleteMode 1061b5d61b8Smrg */ 1071b5d61b8Smrg if (vblank->kind == PresentCompleteKindPixmap) { 1081b5d61b8Smrg if (vblank->pixmap && vblank->window) { 1091b5d61b8Smrg if (vblank->has_suboptimal && vblank->reason == PRESENT_FLIP_REASON_BUFFER_FORMAT) 1101b5d61b8Smrg mode = PresentCompleteModeSuboptimalCopy; 1111b5d61b8Smrg else 1121b5d61b8Smrg mode = PresentCompleteModeCopy; 1131b5d61b8Smrg } else { 1141b5d61b8Smrg mode = PresentCompleteModeSkip; 1151b5d61b8Smrg } 1161b5d61b8Smrg } 1171b5d61b8Smrg else 1181b5d61b8Smrg mode = PresentCompleteModeCopy; 1191b5d61b8Smrg 1201b5d61b8Smrg present_vblank_notify(vblank, vblank->kind, mode, ust, crtc_msc); 1211b5d61b8Smrg present_vblank_destroy(vblank); 1221b5d61b8Smrg} 123