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#include "present_priv.h" 24 25/* 26 * Called when the wait fence is triggered; just gets the current msc/ust and 27 * calls the proper execute again. That will re-check the fence and pend the 28 * request again if it's still not actually ready 29 */ 30static void 31present_wait_fence_triggered(void *param) 32{ 33 present_vblank_ptr vblank = param; 34 ScreenPtr screen = vblank->screen; 35 present_screen_priv_ptr screen_priv = present_screen_priv(screen); 36 37 screen_priv->re_execute(vblank); 38} 39 40Bool 41present_execute_wait(present_vblank_ptr vblank, uint64_t crtc_msc) 42{ 43 WindowPtr window = vblank->window; 44 ScreenPtr screen = window->drawable.pScreen; 45 present_screen_priv_ptr screen_priv = present_screen_priv(screen); 46 47 /* We may have to requeue for the next MSC if check_flip_window prevented 48 * using a flip. 49 */ 50 if (vblank->exec_msc == crtc_msc + 1 && 51 screen_priv->queue_vblank(screen, window, vblank->crtc, vblank->event_id, 52 vblank->exec_msc) == Success) 53 return TRUE; 54 55 if (vblank->wait_fence) { 56 if (!present_fence_check_triggered(vblank->wait_fence)) { 57 present_fence_set_callback(vblank->wait_fence, present_wait_fence_triggered, vblank); 58 return TRUE; 59 } 60 } 61 return FALSE; 62} 63 64void 65present_execute_copy(present_vblank_ptr vblank, uint64_t crtc_msc) 66{ 67 WindowPtr window = vblank->window; 68 ScreenPtr screen = window->drawable.pScreen; 69 present_screen_priv_ptr screen_priv = present_screen_priv(screen); 70 71 /* If present_flip failed, we may have to requeue for the next MSC */ 72 if (vblank->exec_msc == crtc_msc + 1 && 73 Success == screen_priv->queue_vblank(screen, 74 window, 75 vblank->crtc, 76 vblank->event_id, 77 vblank->exec_msc)) { 78 vblank->queued = TRUE; 79 return; 80 } 81 82 present_copy_region(&window->drawable, vblank->pixmap, vblank->update, vblank->x_off, vblank->y_off); 83 84 /* present_copy_region sticks the region into a scratch GC, 85 * which is then freed, freeing the region 86 */ 87 vblank->update = NULL; 88 screen_priv->flush(window); 89 90 present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence); 91} 92 93void 94present_execute_post(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) 95{ 96 uint8_t mode; 97 98 /* Compute correct CompleteMode 99 */ 100 if (vblank->kind == PresentCompleteKindPixmap) { 101 if (vblank->pixmap && vblank->window) { 102 if (vblank->has_suboptimal && vblank->reason == PRESENT_FLIP_REASON_BUFFER_FORMAT) 103 mode = PresentCompleteModeSuboptimalCopy; 104 else 105 mode = PresentCompleteModeCopy; 106 } else { 107 mode = PresentCompleteModeSkip; 108 } 109 } 110 else 111 mode = PresentCompleteModeCopy; 112 113 present_vblank_notify(vblank, vblank->kind, mode, ust, crtc_msc); 114 present_vblank_destroy(vblank); 115} 116