present_execute.c revision 5a7dfde8
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 /* We may have to requeue for the next MSC if check_flip_window prevented 52 * using a flip. 53 */ 54 if (vblank->exec_msc == crtc_msc + 1 && 55 screen_priv->queue_vblank(screen, window, vblank->crtc, vblank->event_id, 56 vblank->exec_msc) == Success) 57 return TRUE; 58 59 if (vblank->wait_fence) { 60 if (!present_fence_check_triggered(vblank->wait_fence)) { 61 present_fence_set_callback(vblank->wait_fence, present_wait_fence_triggered, vblank); 62 return TRUE; 63 } 64 } 65 return FALSE; 66} 67 68void 69present_execute_copy(present_vblank_ptr vblank, uint64_t crtc_msc) 70{ 71 WindowPtr window = vblank->window; 72 ScreenPtr screen = window->drawable.pScreen; 73 present_screen_priv_ptr screen_priv = present_screen_priv(screen); 74 75 /* If present_flip failed, we may have to requeue for the next MSC */ 76 if (vblank->exec_msc == crtc_msc + 1 && 77 Success == screen_priv->queue_vblank(screen, 78 window, 79 vblank->crtc, 80 vblank->event_id, 81 vblank->exec_msc)) { 82 vblank->queued = TRUE; 83 return; 84 } 85 86 present_copy_region(&window->drawable, vblank->pixmap, vblank->update, vblank->x_off, vblank->y_off); 87 88 /* present_copy_region sticks the region into a scratch GC, 89 * which is then freed, freeing the region 90 */ 91 vblank->update = NULL; 92 screen_priv->flush(window); 93 94 present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence); 95} 96 97void 98present_execute_post(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) 99{ 100 uint8_t mode; 101 102 /* Compute correct CompleteMode 103 */ 104 if (vblank->kind == PresentCompleteKindPixmap) { 105 if (vblank->pixmap && vblank->window) { 106 if (vblank->has_suboptimal && vblank->reason == PRESENT_FLIP_REASON_BUFFER_FORMAT) 107 mode = PresentCompleteModeSuboptimalCopy; 108 else 109 mode = PresentCompleteModeCopy; 110 } else { 111 mode = PresentCompleteModeSkip; 112 } 113 } 114 else 115 mode = PresentCompleteModeCopy; 116 117 present_vblank_notify(vblank, vblank->kind, mode, ust, crtc_msc); 118 present_vblank_destroy(vblank); 119} 120