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