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